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 9403bc126b95a5648915f3e785422807e735b41f Author: anjiahao <[email protected]> AuthorDate: Mon Apr 29 19:59:34 2024 +0800 modlib/dlfcn:unify same code Signed-off-by: anjiahao <[email protected]> --- binfmt/binfmt_unloadmodule.c | 35 +-- binfmt/libelf/libelf_load.c | 9 - include/nuttx/lib/modlib.h | 104 +++++++- libs/libc/dlfcn/lib_dlclose.c | 210 +--------------- libs/libc/dlfcn/lib_dlopen.c | 266 +-------------------- libs/libc/dlfcn/lib_dlsym.c | 86 +------ libs/libc/modlib/CMakeLists.txt | 6 +- libs/libc/modlib/Make.defs | 2 + .../libc/modlib/modlib_gethandle.c | 30 +-- .../libc/modlib/modlib_getsymbol.c | 46 ++-- .../libc/modlib/modlib_insert.c | 61 ++--- libs/libc/modlib/modlib_load.c | 2 +- .../libc/modlib/modlib_remove.c | 32 +-- libs/libc/modlib/modlib_unload.c | 21 +- sched/module/mod_insmod.c | 241 +------------------ sched/module/mod_modhandle.c | 25 +- sched/module/mod_modsym.c | 52 +--- sched/module/mod_rmmod.c | 155 +----------- 18 files changed, 235 insertions(+), 1148 deletions(-) diff --git a/binfmt/binfmt_unloadmodule.c b/binfmt/binfmt_unloadmodule.c index bc5effded8..0f0b246dee 100644 --- a/binfmt/binfmt_unloadmodule.c +++ b/binfmt/binfmt_unloadmodule.c @@ -162,29 +162,30 @@ int unload_module(FAR struct binary_s *binp) } #ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - for (i = 0; binp->sectalloc[i] != NULL && i < binp->nsect; i++) - { -# ifdef CONFIG_ARCH_USE_TEXT_HEAP - if (up_textheap_heapmember(binp->sectalloc[i])) + for (i = 0; binp->sectalloc[i] != NULL && i < binp->nsect; i++) { - up_textheap_free(binp->sectalloc[i]); - continue; - } +# ifdef CONFIG_ARCH_USE_TEXT_HEAP + if (up_textheap_heapmember(binp->sectalloc[i])) + { + up_textheap_free(binp->sectalloc[i]); + } + else # endif # ifdef CONFIG_ARCH_USE_DATA_HEAP - if (up_dataheap_heapmember(binp->sectalloc[i])) - { - up_dataheap_free(binp->sectalloc[i]); - continue; - } + if (up_dataheap_heapmember(binp->sectalloc[i])) + { + up_dataheap_free(binp->sectalloc[i]); + } + else # endif + { + kumm_free(binp->sectalloc[i]); + } + } - kumm_free(binp->sectalloc[i]); - } - - binp->alloc[0] = NULL; - binp->alloc[1] = NULL; + binp->alloc[0] = NULL; + binp->alloc[1] = NULL; #endif /* Free allocated address spaces */ diff --git a/binfmt/libelf/libelf_load.c b/binfmt/libelf/libelf_load.c index a3d1b0d1c7..1ffade84e2 100644 --- a/binfmt/libelf/libelf_load.c +++ b/binfmt/libelf/libelf_load.c @@ -270,15 +270,6 @@ static inline int elf_loadfile(FAR struct elf_loadinfo_s *loadinfo) { FAR Elf_Shdr *shdr = &loadinfo->shdr[i]; - /* SHF_ALLOC indicates that the section requires memory during - * execution. - */ - - if ((shdr->sh_flags & SHF_ALLOC) == 0) - { - continue; - } - #ifdef CONFIG_ARCH_USE_SEPARATED_SECTION if (loadinfo->ehdr.e_type == ET_REL) { diff --git a/include/nuttx/lib/modlib.h b/include/nuttx/lib/modlib.h index cb6f5a178a..e198b2c1c2 100644 --- a/include/nuttx/lib/modlib.h +++ b/include/nuttx/lib/modlib.h @@ -196,7 +196,7 @@ struct mod_loadinfo_s */ #ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - uintptr_t *sectalloc; /* All sections memory allocated when ELF file was loaded */ + FAR uintptr_t *sectalloc; /* All sections memory allocated when ELF file was loaded */ #endif uintptr_t textalloc; /* .text memory allocated when module was loaded */ @@ -563,4 +563,106 @@ int modlib_registry_foreach(mod_callback_t callback, FAR void *arg); void modlib_freesymtab(FAR struct module_s *modp); +/**************************************************************************** + * Name: modlib_insert + * + * Description: + * Verify that the file is an ELF module binary and, if so, load the + * module into kernel memory and initialize it for use. + * + * NOTE: modlib_setsymtab() had to have been called in board-specific OS + * logic prior to calling this function from application logic (perhaps via + * boardctl(BOARDIOC_OS_SYMTAB). Otherwise, insmod will be unable to + * resolve symbols in the OS module. + * + * Input Parameters: + * + * filename - Full path to the module binary to be loaded + * modname - The name that can be used to refer to the module after + * it has been loaded. + * + * Returned Value: + * A non-NULL module handle that can be used on subsequent calls to other + * module interfaces is returned on success. If modlib_insert() was + * unable to load the module modlib_insert() will return a NULL handle + * and the errno variable will be set appropriately. + * + ****************************************************************************/ + +FAR void *modlib_insert(FAR const char *filename, FAR const char *modname); + +/**************************************************************************** + * Name: modlib_getsymbol + * + * Description: + * modlib_getsymbol() returns the address of a symbol defined within the + * object that was previously made accessible through a modlib_getsymbol() + * call. handle is the value returned from a call to modlib_insert() (and + * which has not since been released via a call to modlib_remove()), + * name is the symbol's name as a character string. + * + * The returned symbol address will remain valid until modlib_remove() is + * called. + * + * Input Parameters: + * handle - The opaque, non-NULL value returned by a previous successful + * call to modlib_insert(). + * name - A pointer to the symbol name string. + * + * Returned Value: + * The address associated with the symbol is returned on success. + * If handle does not refer to a valid module opened by modlib_insert(), + * or if the named modlib_symbol cannot be found within any of the objects + * associated with handle, modlib_getsymbol() will return NULL and the + * errno variable will be set appropriately. + * + * NOTE: This means that the address zero can never be a valid return + * value. + * + ****************************************************************************/ + +FAR const void *modlib_getsymbol(FAR void *handle, FAR const char *name); + +/**************************************************************************** + * Name: modlib_remove + * + * Description: + * Remove a previously installed module from memory. + * + * Input Parameters: + * handle - The module handler previously returned by modlib_insert(). + * + * Returned Value: + * Zero (OK) on success. On any failure, -1 (ERROR) is returned the + * errno value is set appropriately. + * + ****************************************************************************/ + +int modlib_remove(FAR void *handle); + +/**************************************************************************** + * Name: modlib_modhandle + * + * Description: + * modlib_modhandle() returns the module handle for the installed + * module with the provided name. A secondary use of this function is to + * determine if a module has been loaded or not. + * + * Input Parameters: + * name - A pointer to the module name string. + * + * Returned Value: + * The non-NULL module handle previously returned by modlib_insert() is + * returned on success. If no module with that name is installed, + * modlib_modhandle() will return a NULL handle and the errno variable + * will be set appropriately. + * + ****************************************************************************/ + +#ifdef HAVE_MODLIB_NAMES +FAR void *modlib_gethandle(FAR const char *name); +#else +# define modlib_gethandle(n) NULL +#endif + #endif /* __INCLUDE_NUTTX_LIB_MODLIB_H */ diff --git a/libs/libc/dlfcn/lib_dlclose.c b/libs/libc/dlfcn/lib_dlclose.c index e50055ea71..aff1a7bf9a 100644 --- a/libs/libc/dlfcn/lib_dlclose.c +++ b/libs/libc/dlfcn/lib_dlclose.c @@ -25,211 +25,13 @@ #include <nuttx/config.h> #include <dlfcn.h> -#include <assert.h> -#include <debug.h> -#include <errno.h> -#include <nuttx/module.h> #include <nuttx/lib/modlib.h> -#include "libc.h" - /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: dlremove - * - * Description: - * Remove a previously installed shared library from memory. - * - * Input Parameters: - * handle - The shared library handle previously returned by dlopen(). - * - * Returned Value: - * Zero (OK) on success. On any failure, -1 (ERROR) is returned the - * errno value is set appropriately. - * - ****************************************************************************/ - -#ifdef CONFIG_BUILD_PROTECTED -static inline int dlremove(FAR void *handle) -{ - FAR struct module_s *modp = (FAR struct module_s *)handle; - void (**array)(void); - int ret; - int i; - - DEBUGASSERT(modp != NULL); - - /* Get exclusive access to the module registry */ - - modlib_registry_lock(); - - /* Verify that the module is in the registry */ - - ret = modlib_registry_verify(modp); - if (ret < 0) - { - serr("ERROR: Failed to verify module: %d\n", ret); - goto errout_with_lock; - } - -#if CONFIG_MODLIB_MAXDEPEND > 0 - /* Refuse to remove any module that other modules may depend upon. */ - - if (modp->dependents > 0) - { - serr("ERROR: Module has dependents: %d\n", modp->dependents); - ret = -EBUSY; - goto errout_with_lock; - } -#endif - - /* Is there an uninitializer? */ - - if (modp->modinfo.uninitializer != NULL) - { - /* Try to uninitialize the module */ - - ret = modp->modinfo.uninitializer(modp->modinfo.arg); - - /* Did the module successfully uninitialize? */ - - if (ret < 0) - { - serr("ERROR: Failed to uninitialize the module: %d\n", ret); - goto errout_with_lock; - } - - /* Nullify so that the uninitializer cannot be called again */ - - modp->modinfo.uninitializer = NULL; - - /* Call any .fini_array entries in reverse order */ - - array = (void (**)(void))modp->finiarr; - for (i = (modp->nfini - 1); i >= 0; i--) - { - array[i](); - } - -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->initializer = NULL; - modp->modinfo.arg = NULL; - modp->modinfo.exports = NULL; - modp->modinfo.nexports = 0; -#endif - } - - /* Release resources held by the module */ - - /* Dynamic shared objects have text and data allocated in one - * operation to keep the relative positions between the two - * areas relative otherwise references to the GOT will fail - */ - - 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 */ - -#if defined(CONFIG_ARCH_USE_TEXT_HEAP) - up_textheap_free((FAR void *)modp->textalloc); -#else - lib_free((FAR void *)modp->textalloc); -#endif - } - - if (modp->dataalloc != NULL) - { - /* 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 - { - lib_free((FAR void *)modp->textalloc); - } - - /* Nullify so that the memory cannot be freed again */ - - modp->textalloc = NULL; - modp->dataalloc = NULL; -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->textsize = 0; - modp->datasize = 0; -#endif - - /* Free the modules exported symmbols table */ - - modlib_freesymtab(modp); - - /* Remove the module from the registry */ - - ret = modlib_registry_del(modp); - if (ret < 0) - { - serr("ERROR: Failed to remove the module from the registry: %d\n", - ret); - goto errout_with_lock; - } - -#if CONFIG_MODLIB_MAXDEPEND > 0 - /* Eliminate any dependencies that this module has on other modules */ - - modlib_undepend(modp); -#endif - modlib_registry_unlock(); - - /* And free the registry entry */ - - lib_free(modp); - return OK; - -errout_with_lock: - modlib_registry_unlock(); - set_errno(-ret); - return ERROR; -} -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -277,15 +79,11 @@ errout_with_lock: int dlclose(FAR void *handle) { -#if defined(CONFIG_BUILD_FLAT) +#if defined(CONFIG_BUILD_FLAT) || defined(CONFIG_BUILD_PROTECTED) /* In the FLAT build, a shared library is essentially the same as a kernel * module. - */ - - return rmmod(handle); - -#elif defined(CONFIG_BUILD_PROTECTED) - /* The PROTECTED build is equivalent to the FLAT build EXCEPT that there + * + * The PROTECTED build is equivalent to the FLAT build EXCEPT that there * must be two copies of the module logic: One residing in kernel * space and using the kernel symbol table and one residing in user space * using the user space symbol table. @@ -293,7 +91,7 @@ int dlclose(FAR void *handle) * dlremove() is essentially a clone of rmmod(). */ - return dlremove(handle); + return modlib_remove(handle); #else /* if defined(CONFIG_BUILD_KERNEL) */ /* The KERNEL build is considerably more complex: In order to be shared, diff --git a/libs/libc/dlfcn/lib_dlopen.c b/libs/libc/dlfcn/lib_dlopen.c index 89e4874d6d..b0fbc3db65 100644 --- a/libs/libc/dlfcn/lib_dlopen.c +++ b/libs/libc/dlfcn/lib_dlopen.c @@ -24,129 +24,17 @@ #include <nuttx/config.h> -#include <stdlib.h> -#include <string.h> #include <libgen.h> #include <dlfcn.h> -#include <assert.h> -#include <debug.h> -#include <errno.h> -#include <unistd.h> -#include <sys/param.h> #include <nuttx/envpath.h> -#include <nuttx/module.h> #include <nuttx/lib/modlib.h> - -#include "libc.h" -#include "debug.h" +#include <nuttx/lib/lib.h> /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: dldump_loadinfo - ****************************************************************************/ - -#ifdef CONFIG_BUILD_PROTECTED -# if defined(CONFIG_DEBUG_INFO) && defined(CONFIG_DEBUG_BINFMT) -static void dldump_loadinfo(FAR struct mod_loadinfo_s *loadinfo) -{ - int i; - - binfo("LOAD_INFO:\n"); - binfo(" textalloc: %08lx\n", (long)loadinfo->textalloc); - binfo(" datastart: %08lx\n", (long)loadinfo->datastart); - binfo(" textsize: %ld\n", (long)loadinfo->textsize); - binfo(" datasize: %ld\n", (long)loadinfo->datasize); - binfo(" filelen: %ld\n", (long)loadinfo->filelen); - binfo(" filfd: %d\n", loadinfo->filfd); - binfo(" symtabidx: %d\n", loadinfo->symtabidx); - binfo(" strtabidx: %d\n", loadinfo->strtabidx); - - binfo("ELF Header:\n"); - binfo(" e_ident: %02x %02x %02x %02x\n", - loadinfo->ehdr.e_ident[0], loadinfo->ehdr.e_ident[1], - loadinfo->ehdr.e_ident[2], loadinfo->ehdr.e_ident[3]); - binfo(" e_type: %04x\n", loadinfo->ehdr.e_type); - binfo(" e_machine: %04x\n", loadinfo->ehdr.e_machine); - binfo(" e_version: %08x\n", loadinfo->ehdr.e_version); - binfo(" e_entry: %08lx\n", (long)loadinfo->ehdr.e_entry); - binfo(" e_phoff: %d\n", loadinfo->ehdr.e_phoff); - binfo(" e_shoff: %d\n", loadinfo->ehdr.e_shoff); - binfo(" e_flags: %08x\n" , loadinfo->ehdr.e_flags); - binfo(" e_ehsize: %d\n", loadinfo->ehdr.e_ehsize); - binfo(" e_phentsize: %d\n", loadinfo->ehdr.e_phentsize); - binfo(" e_phnum: %d\n", loadinfo->ehdr.e_phnum); - binfo(" e_shentsize: %d\n", loadinfo->ehdr.e_shentsize); - binfo(" e_shnum: %d\n", loadinfo->ehdr.e_shnum); - binfo(" e_shstrndx: %d\n", loadinfo->ehdr.e_shstrndx); - - if (loadinfo->shdr && loadinfo->ehdr.e_shnum > 0) - { - for (i = 0; i < loadinfo->ehdr.e_shnum; i++) - { - FAR Elf_Shdr *shdr = &loadinfo->shdr[i]; - binfo("Sections %d:\n", i); -# ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - if (loadinfo->ehdr.e_type == ET_REL) - { - binfo(" sh_alloc: %08jx\n", - (uintmax_t)loadinfo->sectalloc[i]); - } -# endif - - binfo(" sh_name: %08x\n", shdr->sh_name); - binfo(" sh_type: %08x\n", shdr->sh_type); - binfo(" sh_flags: %08x\n", shdr->sh_flags); - binfo(" sh_addr: %08x\n", shdr->sh_addr); - binfo(" sh_offset: %d\n", shdr->sh_offset); - binfo(" sh_size: %d\n", shdr->sh_size); - binfo(" sh_link: %d\n", shdr->sh_link); - binfo(" sh_info: %d\n", shdr->sh_info); - binfo(" sh_addralign: %d\n", shdr->sh_addralign); - binfo(" sh_entsize: %d\n", shdr->sh_entsize); - } - } - - if (loadinfo->phdr && loadinfo->ehdr.e_phnum > 0) - { - for (i = 0; i < loadinfo->ehdr.e_phnum; i++) - { - FAR Elf32_Phdr *phdr = &loadinfo->phdr[i]; - binfo("Program Header %d:\n", i); - binfo(" p_type: %08x\n", phdr->p_type); - binfo(" p_offset: %08x\n", phdr->p_offset); - binfo(" p_vaddr: %08x\n", phdr->p_vaddr); - binfo(" p_paddr: %08x\n", phdr->p_paddr); - binfo(" p_filesz: %08x\n", phdr->p_filesz); - binfo(" p_memsz: %08x\n", phdr->p_memsz); - binfo(" p_flags: %08x\n", phdr->p_flags); - binfo(" p_align: %08x\n", phdr->p_align); - } - } -} -# else -# define dldump_loadinfo(i) -# endif -#endif - -/**************************************************************************** - * Name: dldump_initializer - ****************************************************************************/ - -#if defined(CONFIG_BUILD_PROTECTED) && defined(CONFIG_MODLIB_DUMPBUFFER) -static void dldump_initializer(mod_initializer_t initializer, - FAR struct mod_loadinfo_s *loadinfo) -{ - modlib_dumpbuffer("Initializer code", (FAR const uint8_t *)initializer, - MIN(loadinfo->textsize - loadinfo->ehdr.e_entry, 512)); -} -#else -# define dldump_initializer(b,l) -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -173,148 +61,7 @@ static void dldump_initializer(mod_initializer_t initializer, * ****************************************************************************/ -#ifdef CONFIG_BUILD_PROTECTED -/* The PROTECTED build is equivalent to the FLAT build EXCEPT that there - * must be two copies of the module logic: One residing in kernel - * space and using the kernel symbol table and one residing in user space - * using the user space symbol table. - * - * dlinsert() is essentially a clone of insmod(). - */ - -static inline FAR void *dlinsert(FAR const char *filename) -{ - struct mod_loadinfo_s loadinfo; - FAR struct module_s *modp; - mod_initializer_t initializer; - void (**array)(void); - int ret; - int i; - - binfo("Loading file: %s\n", filename); - - /* Get exclusive access to the module registry */ - - modlib_registry_lock(); - - /* Initialize the ELF library to load the program binary. */ - - ret = modlib_initialize(filename, &loadinfo); - dldump_loadinfo(&loadinfo); - if (ret != 0) - { - serr("ERROR: Failed to initialize to load module: %d\n", ret); - goto errout_with_loadinfo; - } - - /* Allocate a module registry entry to hold the module data */ - - modp = (FAR struct module_s *)lib_zalloc(sizeof(struct module_s)); - if (modp == NULL) - { - ret = -ENOMEM; - binfo("Failed to initialize for load of ELF program: %d\n", ret); - goto errout_with_loadinfo; - } - - /* Load the program binary */ - - ret = modlib_load(&loadinfo); - dldump_loadinfo(&loadinfo); - if (ret != 0) - { - binfo("Failed to load ELF program binary: %d\n", ret); - goto errout_with_registry_entry; - } - - /* Bind the program to the kernel symbol table */ - - ret = modlib_bind(modp, &loadinfo); - if (ret != 0) - { - binfo("Failed to bind symbols program binary: %d\n", ret); - goto errout_with_load; - } - - /* 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); -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->textsize = loadinfo.textsize; - modp->datasize = loadinfo.datasize; -#endif - - /* Get the module initializer entry point */ - - initializer = (mod_initializer_t)(loadinfo.textalloc + - loadinfo.ehdr.e_entry); -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->initializer = initializer; -#endif - dldump_initializer(initializer, &loadinfo); - - /* Call the module initializer */ - - switch (loadinfo.ehdr.e_type) - { - case ET_REL : - ret = initializer(&modp->modinfo); - if (ret < 0) - { - binfo("Failed to initialize the module: %d\n", ret); - goto errout_with_load; - } - break; - case ET_DYN : - - /* Process any preinit_array entries */ - - array = (void (**)(void)) loadinfo.preiarr; - for (i = 0; i < loadinfo.nprei; i++) - { - array[i](); - } - - /* Process any init_array entries */ - - array = (void (**)(void)) loadinfo.initarr; - for (i = 0; i < loadinfo.ninit; i++) - { - array[i](); - } - - modp->finiarr = loadinfo.finiarr; - modp->nfini = loadinfo.nfini; - break; - } - - /* Add the new module entry to the registry */ - - modlib_registry_add(modp); - - modlib_uninitialize(&loadinfo); - modlib_registry_unlock(); - return modp; - -errout_with_load: - modlib_unload(&loadinfo); - modlib_undepend(modp); -errout_with_registry_entry: - lib_free(modp); -errout_with_loadinfo: - modlib_uninitialize(&loadinfo); - modlib_registry_unlock(); - set_errno(-ret); - return NULL; -} -#elif defined(CONFIG_BUILD_FLAT) +#if defined(CONFIG_BUILD_FLAT) || defined(CONFIG_BUILD_PROTECTED) /* In the FLAT build, a shared library is essentially the same as a kernel * module. * @@ -322,6 +69,13 @@ errout_with_loadinfo: * - No automatic binding of symbols * - No dependencies * - mode is ignored. + * + * The PROTECTED build is equivalent to the FLAT build EXCEPT that there + * must be two copies of the module logic: One residing in kernel + * space and using the kernel symbol table and one residing in user space + * using the user space symbol table. + * + * dlinsert() is essentially a clone of insmod(). */ static inline FAR void *dlinsert(FAR const char *filename) @@ -341,7 +95,7 @@ static inline FAR void *dlinsert(FAR const char *filename) * name. */ - handle = insmod(filename, basename(name)); + handle = modlib_insert(filename, basename(name)); lib_free(name); return handle; } diff --git a/libs/libc/dlfcn/lib_dlsym.c b/libs/libc/dlfcn/lib_dlsym.c index 66fa6af077..5308e6c699 100644 --- a/libs/libc/dlfcn/lib_dlsym.c +++ b/libs/libc/dlfcn/lib_dlsym.c @@ -25,87 +25,13 @@ #include <nuttx/config.h> #include <dlfcn.h> -#include <assert.h> -#include <debug.h> -#include <errno.h> -#include <nuttx/symtab.h> -#include <nuttx/module.h> #include <nuttx/lib/modlib.h> /**************************************************************************** * Private Functions ****************************************************************************/ -/**************************************************************************** - * Name: dlgetsym - * - * Description: - * dlgetsym() implements dlsym() for the PROTECTED build. - * - * Input Parameters: - * handle - The opaque, non-NULL value returned by a previous successful - * call to insmod(). - * name - A pointer to the symbol name string. - * - * Returned Value: - * See dlsym(). - * - ****************************************************************************/ - -#ifdef CONFIG_BUILD_PROTECTED -static inline FAR const void *dlgetsym(FAR void *handle, - FAR const char *name) -{ - FAR struct module_s *modp = (FAR struct module_s *)handle; - FAR const struct symtab_s *symbol; - int err; - int ret; - - /* Verify that the module is in the registry */ - - modlib_registry_lock(); - ret = modlib_registry_verify(modp); - if (ret < 0) - { - serr("ERROR: Failed to verify module: %d\n", ret); - err = -ret; - goto errout_with_lock; - } - - /* Does the module have a symbol table? */ - - if (modp->modinfo.exports == NULL || modp->modinfo.nexports == 0) - { - serr("ERROR: Module has no symbol table\n"); - err = ENOENT; - goto errout_with_lock; - } - - /* Search the symbol table for the matching symbol */ - - symbol = symtab_findbyname(modp->modinfo.exports, name, - modp->modinfo.nexports); - if (symbol == NULL) - { - serr("ERROR: Failed to find symbol in symbol \"%s\" in table\n", name); - err = ENOENT; - goto errout_with_lock; - } - - /* Return the address within the module associated with the symbol */ - - modlib_registry_unlock(); - DEBUGASSERT(symbol->sym_value != NULL); - return symbol->sym_value; - -errout_with_lock: - modlib_registry_unlock(); - set_errno(err); - return NULL; -} -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -143,15 +69,11 @@ errout_with_lock: FAR void *dlsym(FAR void *handle, FAR const char *name) { -#if defined(CONFIG_BUILD_FLAT) +#if defined(CONFIG_BUILD_FLAT) || defined(CONFIG_BUILD_PROTECTED) /* In the FLAT build, a shared library is essentially the same as a kernel * module. - */ - - return (FAR void *)modsym(handle, name); - -#elif defined(CONFIG_BUILD_PROTECTED) - /* The PROTECTED build is equivalent to the FLAT build EXCEPT that there + * + * The PROTECTED build is equivalent to the FLAT build EXCEPT that there * must be two copies of the module logic: One residing in kernel * space and using the kernel symbol table and one residing in user space * using the user space symbol table. @@ -159,7 +81,7 @@ FAR void *dlsym(FAR void *handle, FAR const char *name) * dlgetsem() is essentially a clone of modsym(). */ - return (FAR void *)dlgetsym(handle, name); + return (FAR void *)modlib_getsymbol(handle, name); #else /* if defined(CONFIG_BUILD_KERNEL) */ /* The KERNEL build is considerably more complex: In order to be shared, diff --git a/libs/libc/modlib/CMakeLists.txt b/libs/libc/modlib/CMakeLists.txt index 741f37abf9..e1606b6772 100644 --- a/libs/libc/modlib/CMakeLists.txt +++ b/libs/libc/modlib/CMakeLists.txt @@ -36,7 +36,11 @@ if(CONFIG_LIBC_MODLIB) modlib_symtab.c modlib_uninit.c modlib_unload.c - modlib_verify.c) + modlib_verify.c + modlib_gethandle.c + modlib_getsymbol.c + modlib_insert.c + modlib_remove.c) list(APPEND SRCS modlib_globals.S) diff --git a/libs/libc/modlib/Make.defs b/libs/libc/modlib/Make.defs index f9cd0a3e33..8b6f1d0100 100644 --- a/libs/libc/modlib/Make.defs +++ b/libs/libc/modlib/Make.defs @@ -26,6 +26,8 @@ CSRCS += modlib_bind.c modlib_depend.c modlib_init.c modlib_iobuffer.c CSRCS += modlib_load.c modlib_loadhdrs.c modlib_verify.c CSRCS += modlib_read.c modlib_registry.c modlib_sections.c CSRCS += modlib_symbols.c modlib_symtab.c modlib_uninit.c modlib_unload.c +CSRCS += modlib_gethandle.c modlib_getsymbol.c modlib_insert.c +CSRCS += modlib_remove.c # Add the modlib directory to the build diff --git a/sched/module/mod_modhandle.c b/libs/libc/modlib/modlib_gethandle.c similarity index 76% copy from sched/module/mod_modhandle.c copy to libs/libc/modlib/modlib_gethandle.c index 13e7c55133..ddd7303df3 100644 --- a/sched/module/mod_modhandle.c +++ b/libs/libc/modlib/modlib_gethandle.c @@ -1,7 +1,5 @@ /**************************************************************************** - * sched/module/mod_modhandle.c - * - * SPDX-License-Identifier: Apache-2.0 + * libs/libc/modlib/modlib_gethandle.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -25,40 +23,38 @@ ****************************************************************************/ #include <nuttx/config.h> - -#include <sys/types.h> #include <assert.h> #include <debug.h> #include <errno.h> -#include <nuttx/module.h> #include <nuttx/lib/modlib.h> -#ifdef CONFIG_MODULE - /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: modhandle + * Name: modlib_modhandle * * Description: - * modhandle() returns the module handle for the installed module with the - * provided name. A secondary use of this function is to determine if a - * module has been loaded or not. + * modlib_modhandle() returns the module handle for the installed + * module with the provided name. A secondary use of this function is to + * determine if a module has been loaded or not. * * Input Parameters: * name - A pointer to the module name string. * * Returned Value: - * The non-NULL module handle previously returned by insmod() is returned - * on success. If no module with that name is installed, modhandle() will - * return a NULL handle and the errno variable will be set appropriately. + * The non-NULL module handle previously returned by modlib_insert() is + * returned on success. If no module with that name is installed, + * modlib_modhandle() will return a NULL handle and the errno variable + * will be set appropriately. * ****************************************************************************/ -FAR void *modhandle(FAR const char *name) +#ifdef HAVE_MODLIB_NAMES + +FAR void *modlib_gethandle(FAR const char *name) { FAR struct module_s *modp; @@ -81,4 +77,4 @@ FAR void *modhandle(FAR const char *name) return modp; } -#endif /* CONFIG_MODULE */ +#endif /* HAVE_MODLIB_NAMES */ diff --git a/sched/module/mod_modsym.c b/libs/libc/modlib/modlib_getsymbol.c similarity index 75% copy from sched/module/mod_modsym.c copy to libs/libc/modlib/modlib_getsymbol.c index f5afc7e9dc..c73a454a10 100644 --- a/sched/module/mod_modsym.c +++ b/libs/libc/modlib/modlib_getsymbol.c @@ -1,7 +1,5 @@ /**************************************************************************** - * sched/module/mod_modsym.c - * - * SPDX-License-Identifier: Apache-2.0 + * libs/libc/modlib/modlib_getsymbol.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -25,51 +23,50 @@ ****************************************************************************/ #include <nuttx/config.h> - #include <assert.h> -#include <errno.h> #include <debug.h> +#include <errno.h> -#include <nuttx/symtab.h> -#include <nuttx/module.h> #include <nuttx/lib/modlib.h> +#include <nuttx/symtab.h> /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: modsym + * Name: modlib_getsymbol * * Description: - * modsym() returns the address of a symbol defined within the object that - * was previously made accessible through a insmod() call. handle is the - * value returned from a call to insmod() (and which has not since been - * released via a call to rmmod()), name is the symbol's name as a - * character string. + * modlib_getsymbol() returns the address of a symbol defined within the + * object that was previously made accessible through a modlib_getsymbol() + * call. handle is the value returned from a call to modlib_insert() (and + * which has not since been released via a call to modlib_remove()), + * name is the symbol's name as a character string. * - * The returned symbol address will remain valid until rmmod() is called. + * The returned symbol address will remain valid until modlib_remove() is + * called. * * Input Parameters: * handle - The opaque, non-NULL value returned by a previous successful - * call to insmod(). + * call to modlib_insert(). * name - A pointer to the symbol name string. * * Returned Value: * The address associated with the symbol is returned on success. - * If handle does not refer to a valid module opened by insmod(), or if - * the named symbol cannot be found within any of the objects associated - * with handle, modsym() will return NULL and the errno variable will be - * set appropriately. + * If handle does not refer to a valid module opened by modlib_insert(), + * or if the named modlib_symbol cannot be found within any of the objects + * associated with handle, modlib_getsymbol() will return NULL and the + * errno variable will be set appropriately. * * NOTE: This means that the address zero can never be a valid return * value. * ****************************************************************************/ -FAR const void *modsym(FAR void *handle, FAR const char *name) +FAR const void *modlib_getsymbol(FAR void *handle, FAR const char *name) { - FAR struct module_s *modp = (FAR struct module_s *)handle; + FAR struct module_s *modp = handle; FAR const struct symtab_s *symbol; int err; int ret; @@ -98,16 +95,17 @@ FAR const void *modsym(FAR void *handle, FAR const char *name) symbol = symtab_findbyname(modp->modinfo.exports, name, modp->modinfo.nexports); + + modlib_registry_unlock(); if (symbol == NULL) { berr("ERROR: Failed to find symbol in symbol \"%s\" in table\n", name); - err = ENOENT; - goto errout_with_lock; + set_errno(ENOENT); + return NULL; } /* Return the address within the module associated with the symbol */ - modlib_registry_unlock(); DEBUGASSERT(symbol->sym_value != NULL); return symbol->sym_value; diff --git a/sched/module/mod_insmod.c b/libs/libc/modlib/modlib_insert.c similarity index 89% copy from sched/module/mod_insmod.c copy to libs/libc/modlib/modlib_insert.c index a020089450..ec3098db44 100644 --- a/sched/module/mod_insmod.c +++ b/libs/libc/modlib/modlib_insert.c @@ -1,7 +1,5 @@ /**************************************************************************** - * sched/module/mod_insmod.c - * - * SPDX-License-Identifier: Apache-2.0 + * libs/libc/modlib/modlib_insert.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -25,32 +23,24 @@ ****************************************************************************/ #include <nuttx/config.h> - -#include <sys/param.h> -#include <sys/types.h> -#include <stdint.h> -#include <string.h> #include <assert.h> -#include <errno.h> #include <debug.h> +#include <errno.h> +#include <sys/param.h> -#include <nuttx/arch.h> -#include <nuttx/kmalloc.h> -#include <nuttx/module.h> +#include <nuttx/lib/lib.h> #include <nuttx/lib/modlib.h> -#ifdef CONFIG_MODULE - /**************************************************************************** * Private Functions ****************************************************************************/ /**************************************************************************** - * Name: mod_dumploadinfo + * Name: modlib_dumploadinfo ****************************************************************************/ #ifdef CONFIG_DEBUG_BINFMT_INFO -static void mod_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo) +static void modlib_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo) { int i; @@ -112,22 +102,22 @@ static void mod_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo) } } #else -# define mod_dumploadinfo(i) +# define modlib_dumploadinfo(i) #endif /**************************************************************************** - * Name: mod_dumpinitializer + * Name: modlib_dumpinitializer ****************************************************************************/ #ifdef CONFIG_MODLIB_DUMPBUFFER -static void mod_dumpinitializer(mod_initializer_t initializer, - FAR struct mod_loadinfo_s *loadinfo) +static void modlib_dumpinitializer(mod_initializer_t initializer, + FAR struct mod_loadinfo_s *loadinfo) { modlib_dumpbuffer("Initializer code", (FAR const uint8_t *)initializer, MIN(loadinfo->textsize - loadinfo->ehdr.e_entry, 512)); } #else -# define mod_dumpinitializer(b,l) +# define modlib_dumpinitializer(b,l) #endif /**************************************************************************** @@ -135,7 +125,7 @@ static void mod_dumpinitializer(mod_initializer_t initializer, ****************************************************************************/ /**************************************************************************** - * Name: insmod + * Name: modlib_insert * * Description: * Verify that the file is an ELF module binary and, if so, load the @@ -154,13 +144,13 @@ static void mod_dumpinitializer(mod_initializer_t initializer, * * Returned Value: * A non-NULL module handle that can be used on subsequent calls to other - * module interfaces is returned on success. If insmod() was unable to - * load the module insmod() will return a NULL handle and the errno - * variable will be set appropriately. + * module interfaces is returned on success. If modlib_insert() was + * unable to load the module modlib_insert() will return a NULL handle + * and the errno variable will be set appropriately. * ****************************************************************************/ -FAR void *insmod(FAR const char *filename, FAR const char *modname) +FAR void *modlib_insert(FAR const char *filename, FAR const char *modname) { struct mod_loadinfo_s loadinfo; FAR struct module_s *modp; @@ -178,16 +168,19 @@ FAR void *insmod(FAR const char *filename, FAR const char *modname) /* Check if this module is already installed */ +#ifdef HAVE_MODLIB_NAMES if (modlib_registry_find(modname) != NULL) { - ret = -EEXIST; - goto errout_with_lock; + modlib_registry_unlock(); + set_errno(EEXIST); + return NULL; } +#endif /* Initialize the ELF library to load the program binary. */ ret = modlib_initialize(filename, &loadinfo); - mod_dumploadinfo(&loadinfo); + modlib_dumploadinfo(&loadinfo); if (ret != 0) { berr("ERROR: Failed to initialize to load module: %d\n", ret); @@ -196,7 +189,7 @@ FAR void *insmod(FAR const char *filename, FAR const char *modname) /* Allocate a module registry entry to hold the module data */ - modp = kmm_zalloc(sizeof(struct module_s)); + modp = lib_zalloc(sizeof(struct module_s)); if (modp == NULL) { berr("Failed to allocate struct module_s\n"); @@ -213,7 +206,7 @@ FAR void *insmod(FAR const char *filename, FAR const char *modname) /* Load the program binary */ ret = modlib_load(&loadinfo); - mod_dumploadinfo(&loadinfo); + modlib_dumploadinfo(&loadinfo); if (ret != 0) { binfo("Failed to load ELF program binary: %d\n", ret); @@ -245,7 +238,7 @@ FAR void *insmod(FAR const char *filename, FAR const char *modname) #if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) modp->initializer = initializer; #endif - mod_dumpinitializer(initializer, &loadinfo); + modlib_dumpinitializer(initializer, &loadinfo); /* Call the module initializer */ @@ -296,13 +289,11 @@ errout_with_load: modlib_undepend(modp); #endif errout_with_registry_entry: - kmm_free(modp); + lib_free(modp); errout_with_loadinfo: modlib_uninitialize(&loadinfo); -errout_with_lock: modlib_registry_unlock(); set_errno(-ret); return NULL; } -#endif /* CONFIG_MODULE */ diff --git a/libs/libc/modlib/modlib_load.c b/libs/libc/modlib/modlib_load.c index 26748ed2ae..4aaae3a1b9 100644 --- a/libs/libc/modlib/modlib_load.c +++ b/libs/libc/modlib/modlib_load.c @@ -70,7 +70,7 @@ static int modlib_section_alloc(FAR struct mod_loadinfo_s *loadinfo, /* Allocate memory info for all sections */ loadinfo->sectalloc = lib_zalloc(sizeof(uintptr_t) * - loadinfo->ehdr.e_shnum); + loadinfo->ehdr.e_shnum); if (loadinfo->sectalloc == NULL) { return -ENOMEM; diff --git a/sched/module/mod_rmmod.c b/libs/libc/modlib/modlib_remove.c similarity index 90% copy from sched/module/mod_rmmod.c copy to libs/libc/modlib/modlib_remove.c index bc1470d456..a645c68986 100644 --- a/sched/module/mod_rmmod.c +++ b/libs/libc/modlib/modlib_remove.c @@ -1,7 +1,5 @@ /**************************************************************************** - * sched/module/mod_rmmod.c - * - * SPDX-License-Identifier: Apache-2.0 + * libs/libc/modlib/modlib_remove.c * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with @@ -25,30 +23,26 @@ ****************************************************************************/ #include <nuttx/config.h> - -#include <sys/types.h> #include <assert.h> #include <debug.h> #include <errno.h> -#include <nuttx/kmalloc.h> -#include <nuttx/module.h> +#include <nuttx/arch.h> +#include <nuttx/lib/lib.h> #include <nuttx/lib/modlib.h> -#ifdef CONFIG_MODULE - /**************************************************************************** * Public Functions ****************************************************************************/ /**************************************************************************** - * Name: rmmod + * Name: modlib_remove * * Description: * Remove a previously installed module from memory. * * Input Parameters: - * handle - The module handler previously returned by insmod(). + * handle - The module handler previously returned by modlib_insert(). * * Returned Value: * Zero (OK) on success. On any failure, -1 (ERROR) is returned the @@ -56,7 +50,7 @@ * ****************************************************************************/ -int rmmod(FAR void *handle) +int modlib_remove(FAR void *handle) { FAR struct module_s *modp = (FAR struct module_s *)handle; int ret; @@ -148,28 +142,28 @@ int rmmod(FAR void *handle) } # endif - kmm_free(modp->sectalloc[i]); + lib_free(modp->sectalloc[i]); } - kmm_free(modp->sectalloc); + lib_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); + lib_free((FAR void *)modp->textalloc); # endif # if defined(CONFIG_ARCH_USE_DATA_HEAP) up_dataheap_free((FAR void *)modp->dataalloc); # else - kmm_free((FAR void *)modp->dataalloc); + lib_free((FAR void *)modp->dataalloc); # endif #endif } else { - kmm_free((FAR void *)modp->textalloc); + lib_free((FAR void *)modp->textalloc); } modp->textalloc = NULL; @@ -199,7 +193,7 @@ int rmmod(FAR void *handle) /* And free the registry entry */ - kmm_free(modp); + lib_free(modp); return OK; errout_with_lock: @@ -207,5 +201,3 @@ errout_with_lock: set_errno(-ret); return ERROR; } - -#endif /* CONFIG_MODULE */ diff --git a/libs/libc/modlib/modlib_unload.c b/libs/libc/modlib/modlib_unload.c index 12cdb813f4..981e2a8fd1 100644 --- a/libs/libc/modlib/modlib_unload.c +++ b/libs/libc/modlib/modlib_unload.c @@ -72,39 +72,40 @@ int modlib_unload(FAR struct mod_loadinfo_s *loadinfo) if (up_textheap_heapmember((FAR void *)loadinfo->sectalloc[i])) { up_textheap_free((FAR void *)loadinfo->sectalloc[i]); - continue; } + else # endif # ifdef CONFIG_ARCH_USE_DATA_HEAP if (up_dataheap_heapmember((FAR void *)loadinfo->sectalloc[i])) { up_dataheap_free((FAR void *)loadinfo->sectalloc[i]); - continue; } + else # endif - - lib_free((FAR void *)loadinfo->sectalloc[i]); + { + lib_free((FAR void *)loadinfo->sectalloc[i]); + } } lib_free(loadinfo->sectalloc); #else if (loadinfo->textalloc != 0) { -#if defined(CONFIG_ARCH_USE_TEXT_HEAP) +# if defined(CONFIG_ARCH_USE_TEXT_HEAP) up_textheap_free((FAR void *)loadinfo->textalloc); -#else +# else lib_free((FAR void *)loadinfo->textalloc); -#endif +# endif } if (loadinfo->datastart != 0) { -#if defined(CONFIG_ARCH_USE_DATA_HEAP) +# if defined(CONFIG_ARCH_USE_DATA_HEAP) up_dataheap_free((FAR void *)loadinfo->datastart); -#else +# else lib_free((FAR void *)loadinfo->datastart); -#endif +# endif } #endif } diff --git a/sched/module/mod_insmod.c b/sched/module/mod_insmod.c index a020089450..ab17c38ba8 100644 --- a/sched/module/mod_insmod.c +++ b/sched/module/mod_insmod.c @@ -26,110 +26,11 @@ #include <nuttx/config.h> -#include <sys/param.h> -#include <sys/types.h> -#include <stdint.h> -#include <string.h> -#include <assert.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/arch.h> -#include <nuttx/kmalloc.h> #include <nuttx/module.h> #include <nuttx/lib/modlib.h> #ifdef CONFIG_MODULE -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: mod_dumploadinfo - ****************************************************************************/ - -#ifdef CONFIG_DEBUG_BINFMT_INFO -static void mod_dumploadinfo(FAR struct mod_loadinfo_s *loadinfo) -{ - int i; - - binfo("LOAD_INFO:\n"); - binfo(" textalloc: %08lx\n", (long)loadinfo->textalloc); - binfo(" datastart: %08lx\n", (long)loadinfo->datastart); - binfo(" textsize: %ld\n", (long)loadinfo->textsize); - binfo(" datasize: %ld\n", (long)loadinfo->datasize); - binfo(" textalign: %zu\n", loadinfo->textalign); - binfo(" dataalign: %zu\n", loadinfo->dataalign); - binfo(" filelen: %ld\n", (long)loadinfo->filelen); - binfo(" filfd: %d\n", loadinfo->filfd); - binfo(" symtabidx: %d\n", loadinfo->symtabidx); - binfo(" strtabidx: %d\n", loadinfo->strtabidx); - - binfo("ELF Header:\n"); - binfo(" e_ident: %02x %02x %02x %02x\n", - loadinfo->ehdr.e_ident[0], loadinfo->ehdr.e_ident[1], - loadinfo->ehdr.e_ident[2], loadinfo->ehdr.e_ident[3]); - binfo(" e_type: %04x\n", loadinfo->ehdr.e_type); - binfo(" e_machine: %04x\n", loadinfo->ehdr.e_machine); - binfo(" e_version: %08x\n", loadinfo->ehdr.e_version); - binfo(" e_entry: %08lx\n", (long)loadinfo->ehdr.e_entry); - binfo(" e_phoff: %ju\n", (uintmax_t)loadinfo->ehdr.e_phoff); - binfo(" e_shoff: %ju\n", (uintmax_t)loadinfo->ehdr.e_shoff); - binfo(" e_flags: %08x\n", loadinfo->ehdr.e_flags); - binfo(" e_ehsize: %d\n", loadinfo->ehdr.e_ehsize); - binfo(" e_phentsize: %d\n", loadinfo->ehdr.e_phentsize); - binfo(" e_phnum: %d\n", loadinfo->ehdr.e_phnum); - binfo(" e_shentsize: %d\n", loadinfo->ehdr.e_shentsize); - binfo(" e_shnum: %d\n", loadinfo->ehdr.e_shnum); - binfo(" e_shstrndx: %d\n", loadinfo->ehdr.e_shstrndx); - - if (loadinfo->shdr && loadinfo->ehdr.e_shnum > 0) - { - for (i = 0; i < loadinfo->ehdr.e_shnum; i++) - { - FAR Elf_Shdr *shdr = &loadinfo->shdr[i]; - binfo("Sections %d:\n", i); -# ifdef CONFIG_ARCH_USE_SEPARATED_SECTION - if (loadinfo->ehdr.e_type == ET_REL) - { - binfo(" sh_alloc: %08jx\n", - (uintmax_t)loadinfo->sectalloc[i]); - } -# endif - - binfo(" sh_name: %08x\n", shdr->sh_name); - binfo(" sh_type: %08x\n", shdr->sh_type); - binfo(" sh_flags: %08jx\n", (uintmax_t)shdr->sh_flags); - binfo(" sh_addr: %08jx\n", (uintmax_t)shdr->sh_addr); - binfo(" sh_offset: %ju\n", (uintmax_t)shdr->sh_offset); - binfo(" sh_size: %ju\n", (uintmax_t)shdr->sh_size); - binfo(" sh_link: %d\n", shdr->sh_link); - binfo(" sh_info: %d\n", shdr->sh_info); - binfo(" sh_addralign: %ju\n", (uintmax_t)shdr->sh_addralign); - binfo(" sh_entsize: %ju\n", (uintmax_t)shdr->sh_entsize); - } - } -} -#else -# define mod_dumploadinfo(i) -#endif - -/**************************************************************************** - * Name: mod_dumpinitializer - ****************************************************************************/ - -#ifdef CONFIG_MODLIB_DUMPBUFFER -static void mod_dumpinitializer(mod_initializer_t initializer, - FAR struct mod_loadinfo_s *loadinfo) -{ - modlib_dumpbuffer("Initializer code", (FAR const uint8_t *)initializer, - MIN(loadinfo->textsize - loadinfo->ehdr.e_entry, 512)); -} -#else -# define mod_dumpinitializer(b,l) -#endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -162,147 +63,7 @@ static void mod_dumpinitializer(mod_initializer_t initializer, FAR void *insmod(FAR const char *filename, FAR const char *modname) { - struct mod_loadinfo_s loadinfo; - FAR struct module_s *modp; - mod_initializer_t initializer; - FAR void (**array)(void); - int ret; - int i; - - DEBUGASSERT(filename != NULL && modname != NULL); - binfo("Loading file: %s\n", filename); - - /* Get exclusive access to the module registry */ - - modlib_registry_lock(); - - /* Check if this module is already installed */ - - if (modlib_registry_find(modname) != NULL) - { - ret = -EEXIST; - goto errout_with_lock; - } - - /* Initialize the ELF library to load the program binary. */ - - ret = modlib_initialize(filename, &loadinfo); - mod_dumploadinfo(&loadinfo); - if (ret != 0) - { - berr("ERROR: Failed to initialize to load module: %d\n", ret); - goto errout_with_loadinfo; - } - - /* Allocate a module registry entry to hold the module data */ - - modp = kmm_zalloc(sizeof(struct module_s)); - if (modp == NULL) - { - berr("Failed to allocate struct module_s\n"); - ret = -ENOMEM; - goto errout_with_loadinfo; - } - -#ifdef HAVE_MODLIB_NAMES - /* Save the module name in the registry entry */ - - strlcpy(modp->modname, modname, sizeof(modp->modname)); -#endif - - /* Load the program binary */ - - ret = modlib_load(&loadinfo); - mod_dumploadinfo(&loadinfo); - if (ret != 0) - { - binfo("Failed to load ELF program binary: %d\n", ret); - goto errout_with_registry_entry; - } - - /* Bind the program to the kernel symbol table */ - - ret = modlib_bind(modp, &loadinfo); - if (ret != 0) - { - binfo("Failed to bind symbols program binary: %d\n", ret); - goto errout_with_load; - } - - /* Save the load information */ - - modp->textalloc = (FAR void *)loadinfo.textalloc; - modp->dataalloc = (FAR void *)loadinfo.datastart; -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->textsize = loadinfo.textsize; - modp->datasize = loadinfo.datasize; -#endif - - /* Get the module initializer entry point */ - - initializer = (mod_initializer_t)(loadinfo.textalloc + - loadinfo.ehdr.e_entry); -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->initializer = initializer; -#endif - mod_dumpinitializer(initializer, &loadinfo); - - /* Call the module initializer */ - - switch (loadinfo.ehdr.e_type) - { - case ET_REL : - ret = initializer(&modp->modinfo); - if (ret < 0) - { - binfo("Failed to initialize the module: %d\n", ret); - goto errout_with_load; - } - break; - case ET_DYN : - - /* Process any preinit_array entries */ - - array = (FAR void (**)(void))loadinfo.preiarr; - for (i = 0; i < loadinfo.nprei; i++) - { - array[i](); - } - - /* Process any init_array entries */ - - array = (FAR void (**)(void))loadinfo.initarr; - for (i = 0; i < loadinfo.ninit; i++) - { - array[i](); - } - - modp->finiarr = loadinfo.finiarr; - modp->nfini = loadinfo.nfini; - break; - } - - /* Add the new module entry to the registry */ - - modlib_registry_add(modp); - - modlib_uninitialize(&loadinfo); - modlib_registry_unlock(); - return modp; - -errout_with_load: - modlib_unload(&loadinfo); -#if CONFIG_MODLIB_MAXDEPEND > 0 - modlib_undepend(modp); -#endif -errout_with_registry_entry: - kmm_free(modp); -errout_with_loadinfo: - modlib_uninitialize(&loadinfo); -errout_with_lock: - modlib_registry_unlock(); - set_errno(-ret); - return NULL; + return modlib_insert(filename, modname); } #endif /* CONFIG_MODULE */ diff --git a/sched/module/mod_modhandle.c b/sched/module/mod_modhandle.c index 13e7c55133..006593feac 100644 --- a/sched/module/mod_modhandle.c +++ b/sched/module/mod_modhandle.c @@ -26,11 +26,6 @@ #include <nuttx/config.h> -#include <sys/types.h> -#include <assert.h> -#include <debug.h> -#include <errno.h> - #include <nuttx/module.h> #include <nuttx/lib/modlib.h> @@ -60,25 +55,7 @@ FAR void *modhandle(FAR const char *name) { - FAR struct module_s *modp; - - DEBUGASSERT(name != NULL); - - /* Get exclusive access to the module registry */ - - modlib_registry_lock(); - - /* Find the module entry for this name in the registry */ - - modp = modlib_registry_find(name); - if (modp == NULL) - { - berr("ERROR: Failed to find module %s\n", name); - set_errno(ENOENT); - } - - modlib_registry_unlock(); - return modp; + return modlib_gethandle(name); } #endif /* CONFIG_MODULE */ diff --git a/sched/module/mod_modsym.c b/sched/module/mod_modsym.c index f5afc7e9dc..3a839a2615 100644 --- a/sched/module/mod_modsym.c +++ b/sched/module/mod_modsym.c @@ -26,11 +26,6 @@ #include <nuttx/config.h> -#include <assert.h> -#include <errno.h> -#include <debug.h> - -#include <nuttx/symtab.h> #include <nuttx/module.h> #include <nuttx/lib/modlib.h> @@ -69,50 +64,5 @@ FAR const void *modsym(FAR void *handle, FAR const char *name) { - FAR struct module_s *modp = (FAR struct module_s *)handle; - FAR const struct symtab_s *symbol; - int err; - int ret; - - /* Verify that the module is in the registry */ - - modlib_registry_lock(); - ret = modlib_registry_verify(modp); - if (ret < 0) - { - berr("ERROR: Failed to verify module: %d\n", ret); - err = -ret; - goto errout_with_lock; - } - - /* Does the module have a symbol table? */ - - if (modp->modinfo.exports == NULL || modp->modinfo.nexports == 0) - { - berr("ERROR: Module has no symbol table\n"); - err = ENOENT; - goto errout_with_lock; - } - - /* Search the symbol table for the matching symbol */ - - symbol = symtab_findbyname(modp->modinfo.exports, name, - modp->modinfo.nexports); - if (symbol == NULL) - { - berr("ERROR: Failed to find symbol in symbol \"%s\" in table\n", name); - err = ENOENT; - goto errout_with_lock; - } - - /* Return the address within the module associated with the symbol */ - - modlib_registry_unlock(); - DEBUGASSERT(symbol->sym_value != NULL); - return symbol->sym_value; - -errout_with_lock: - modlib_registry_unlock(); - set_errno(err); - return NULL; + return modlib_getsymbol(handle, name); } diff --git a/sched/module/mod_rmmod.c b/sched/module/mod_rmmod.c index bc1470d456..933ac1a15c 100644 --- a/sched/module/mod_rmmod.c +++ b/sched/module/mod_rmmod.c @@ -26,12 +26,6 @@ #include <nuttx/config.h> -#include <sys/types.h> -#include <assert.h> -#include <debug.h> -#include <errno.h> - -#include <nuttx/kmalloc.h> #include <nuttx/module.h> #include <nuttx/lib/modlib.h> @@ -58,154 +52,7 @@ int rmmod(FAR void *handle) { - FAR struct module_s *modp = (FAR struct module_s *)handle; - int ret; - - DEBUGASSERT(modp != NULL); - - /* Get exclusive access to the module registry */ - - modlib_registry_lock(); - - /* Verify that the module is in the registry */ - - ret = modlib_registry_verify(modp); - if (ret < 0) - { - berr("ERROR: Failed to verify module: %d\n", ret); - goto errout_with_lock; - } - -#if CONFIG_MODLIB_MAXDEPEND > 0 - /* Refuse to remove any module that other modules may depend upon. */ - - if (modp->dependents > 0) - { - berr("ERROR: Module has dependents: %d\n", modp->dependents); - ret = -EBUSY; - goto errout_with_lock; - } -#endif - - /* Is there an uninitializer? */ - - if (modp->modinfo.uninitializer != NULL) - { - /* Try to uninitialize the module */ - - ret = modp->modinfo.uninitializer(modp->modinfo.arg); - - /* Did the module successfully uninitialize? */ - - if (ret < 0) - { - berr("ERROR: Failed to uninitialize the module: %d\n", ret); - goto errout_with_lock; - } - - /* Nullify so that the uninitializer cannot be called again */ - - modp->modinfo.uninitializer = NULL; -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->initializer = NULL; - modp->modinfo.arg = NULL; - modp->modinfo.exports = NULL; - modp->modinfo.nexports = 0; -#endif - } - - /* Release resources held by the module */ - - if (modp->textalloc != NULL || modp->dataalloc != NULL) - { - /* Free the module memory and nullify so that the memory cannot - * be freed again - * - * NOTE: For dynamic shared objects there is only a single - * allocation: the text/data were allocated in one operation - */ - - 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 - - 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) - up_dataheap_free((FAR void *)modp->dataalloc); -# else - kmm_free((FAR void *)modp->dataalloc); -# endif -#endif - } - else - { - kmm_free((FAR void *)modp->textalloc); - } - - modp->textalloc = NULL; - modp->dataalloc = NULL; -#if defined(CONFIG_FS_PROCFS) && !defined(CONFIG_FS_PROCFS_EXCLUDE_MODULE) - modp->textsize = 0; - modp->datasize = 0; -#endif - } - - /* Remove the module from the registry */ - - ret = modlib_registry_del(modp); - if (ret < 0) - { - berr("ERROR: Failed to remove the module from the registry: %d\n", - ret); - goto errout_with_lock; - } - -#if CONFIG_MODLIB_MAXDEPEND > 0 - /* Eliminate any dependencies that this module has on other modules */ - - modlib_undepend(modp); -#endif - modlib_registry_unlock(); - - /* And free the registry entry */ - - kmm_free(modp); - return OK; - -errout_with_lock: - modlib_registry_unlock(); - set_errno(-ret); - return ERROR; + return modlib_remove(handle); } #endif /* CONFIG_MODULE */
