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) +#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 +# 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