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 <[email protected]>
AuthorDate: Wed Feb 21 15:58:02 2024 +0800

    libc/modlib: free memory resource when rmmod elf
    
    Signed-off-by: dongjiuzhu1 <[email protected]>
---
 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

Reply via email to