You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/10/08 15:51:41 UTC
(nuttx) 02/10: libc/modlib: free memory resource when rmmod elf
This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch releases/12.7
in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 79b4b39994d6000543f887c4a8c8fe74435cf407
Author: dongjiuzhu1 <do...@xiaomi.com>
AuthorDate: Wed Feb 21 15:58:02 2024 +0800
libc/modlib: free memory resource when rmmod elf
Signed-off-by: dongjiuzhu1 <do...@xiaomi.com>
---
include/nuttx/lib/modlib.h | 4 ++++
libs/libc/dlfcn/lib_dlclose.c | 33 +++++++++++++++++++++++++++++++++
libs/libc/dlfcn/lib_dlopen.c | 5 +++++
libs/libc/modlib/modlib_unload.c | 2 +-
sched/module/mod_rmmod.c | 39 ++++++++++++++++++++++++++++++++++-----
5 files changed, 77 insertions(+), 6 deletions(-)
diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h
index 8ca35e84ae..cb6f5a178a 100644
--- a/include/nuttx/lib/modlib.h
+++ b/include/nuttx/lib/modlib.h
@@ -159,6 +159,10 @@ struct module_s
struct mod_info_s modinfo; /* Module information */
FAR void *textalloc; /* Allocated kernel text memory */
FAR void *dataalloc; /* Allocated kernel memory */
+#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
+ FAR void **sectalloc; /* All sections memory allocated when ELF file was loaded */
+ uint16_t nsect; /* Number of entries in sectalloc array */
+#endif
int dynamic; /* Module is a dynamic shared object */
#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE)
size_t textsize; /* Size of the kernel .text memory allocation */
diff --git a/libs/libc/dlfcn/lib_dlclose.c b/libs/libc/dlfcn/lib_dlclose.c
index 335d7fb77c..e50055ea71 100644
--- a/libs/libc/dlfcn/lib_dlclose.c
+++ b/libs/libc/dlfcn/lib_dlclose.c
@@ -132,6 +132,34 @@ static inline int dlremove(FAR void *handle)
if (!modp->dynamic)
{
+#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
+ int i;
+
+ for (i = 0; i < modp->nsect && modp->sectalloc[i] != NULL; i++)
+ {
+# ifdef CONFIG_ARCH_USE_TEXT_HEAP
+ if (up_textheap_heapmember(modp->sectalloc[i]))
+ {
+ up_textheap_free(modp->sectalloc[i]);
+ continue;
+ }
+# endif
+
+# ifdef CONFIG_ARCH_USE_DATA_HEAP
+ if (up_dataheap_heapmember(modp->sectalloc[i]))
+ {
+ up_dataheap_free(modp->sectalloc[i]);
+ continue;
+ }
+# endif
+
+ lib_free(modp->sectalloc[i]);
+ }
+
+ lib_free(modp->sectalloc);
+ modp->sectalloc = NULL;
+ modp->nsect = 0;
+#else
if (modp->textalloc != NULL)
{
/* Free the module memory */
@@ -147,8 +175,13 @@ static inline int dlremove(FAR void *handle)
{
/* Free the module memory */
+#if defined(CONFIG_ARCH_USE_DATA_HEAP)
+ up_dataheap_free((FAR void *)modp->dataalloc);
+#else
lib_free((FAR void *)modp->dataalloc);
+#endif
}
+#endif
}
else
{
diff --git a/libs/libc/dlfcn/lib_dlopen.c b/libs/libc/dlfcn/lib_dlopen.c
index a9921ccdf9..89e4874d6d 100644
--- a/libs/libc/dlfcn/lib_dlopen.c
+++ b/libs/libc/dlfcn/lib_dlopen.c
@@ -238,6 +238,11 @@ static inline FAR void *dlinsert(FAR const char *filename)
/* Save the load information */
+#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
+ modp->sectalloc = (FAR void *)loadinfo.sectalloc;
+ modp->nsect = loadinfo.ehdr.e_shnum;
+#endif
+
modp->textalloc = (FAR void *)loadinfo.textalloc;
modp->dataalloc = (FAR void *)loadinfo.datastart;
modp->dynamic = (loadinfo.ehdr.e_type == ET_DYN);
diff --git a/libs/libc/modlib/modlib_unload.c b/libs/libc/modlib/modlib_unload.c
index 02c8646855..12cdb813f4 100644
--- a/libs/libc/modlib/modlib_unload.c
+++ b/libs/libc/modlib/modlib_unload.c
@@ -87,7 +87,7 @@ int modlib_unload(FAR struct mod_loadinfo_s *loadinfo)
lib_free((FAR void *)loadinfo->sectalloc[i]);
}
- lib_free(loadinfo->sectalloc);
+ lib_free(loadinfo->sectalloc);
#else
if (loadinfo->textalloc != 0)
{
diff --git a/sched/module/mod_rmmod.c b/sched/module/mod_rmmod.c
index 885d2cfcd8..bc1470d456 100644
--- a/sched/module/mod_rmmod.c
+++ b/sched/module/mod_rmmod.c
@@ -127,15 +127,44 @@ int rmmod(FAR void *handle)
if (!modp->dynamic)
{
-#if defined(CONFIG_ARCH_USE_TEXT_HEAP)
- up_textheap_free((FAR void *)modp->textalloc);
+#ifdef CONFIG_ARCH_USE_SEPARATED_SECTION
+ int i;
+
+ for (i = 0; i < modp->nsect && modp->sectalloc[i] != NULL; i++)
+ {
+# ifdef CONFIG_ARCH_USE_TEXT_HEAP
+ if (up_textheap_heapmember(modp->sectalloc[i]))
+ {
+ up_textheap_free(modp->sectalloc[i]);
+ continue;
+ }
+# endif
+
+# ifdef CONFIG_ARCH_USE_DATA_HEAP
+ if (up_dataheap_heapmember(modp->sectalloc[i]))
+ {
+ up_dataheap_free(modp->sectalloc[i]);
+ continue;
+ }
+# endif
+
+ kmm_free(modp->sectalloc[i]);
+ }
+
+ kmm_free(modp->sectalloc);
+ modp->sectalloc = NULL;
+ modp->nsect = 0;
#else
+# if defined(CONFIG_ARCH_USE_TEXT_HEAP)
+ up_textheap_free((FAR void *)modp->textalloc);
+# else
kmm_free((FAR void *)modp->textalloc);
-#endif
-#if defined(CONFIG_ARCH_USE_DATA_HEAP)
+# endif
+# if defined(CONFIG_ARCH_USE_DATA_HEAP)
up_dataheap_free((FAR void *)modp->dataalloc);
-#else
+# else
kmm_free((FAR void *)modp->dataalloc);
+# endif
#endif
}
else