diff --git a/components/libc/posix/libdl/dlmodule.c b/components/libc/posix/libdl/dlmodule.c index eee45d0843a..7ce60908774 100644 --- a/components/libc/posix/libdl/dlmodule.c +++ b/components/libc/posix/libdl/dlmodule.c @@ -33,32 +33,79 @@ static struct rt_module_symtab *_rt_module_symtab_end = RT_NULL; #pragma section="RTMSymTab" #endif -/* set the name of module */ -static void _dlmodule_set_name(struct rt_dlmodule *module, const char *path) +/** + * @brief Extract module name from a file path by stripping directory and extension. + * + * @param path the file path (e.g., "/mnt/sdcard/apps/clock.so") + * @param name buffer to store the extracted module name + * @param name_size size of the name buffer + * + * @note This function extracts the base name without path and extension. + * Examples: + * - "/mnt/sdcard/apps/clock.so" -> "clock" + * - "/mnt/v1.2/app.so" -> "app" (dots in path are ignored) + * - ".hidden" -> ".hidden" (hidden files without extension) + * - ".hidden.so" -> ".hidden" (hidden files with extension) + */ +void dlmodule_extract_name(const char *path, char *name, int name_size) { int size; - struct rt_object *object; - const char *first, *end, *ptr; + const char *first, *end, *ptr, *last_dot; - object = &(module->parent); - ptr = first = (char *)path; - end = path + rt_strlen(path); + RT_ASSERT(path != RT_NULL); + RT_ASSERT(name != RT_NULL); + RT_ASSERT(name_size > 0); + + ptr = first = path; + end = path + rt_strlen(path); + /* find the start of filename (after last '/') */ while (*ptr != '\0') { if (*ptr == '/') first = ptr + 1; + ptr++; + } + + /* find last extension in filename portion only (after last '/') */ + last_dot = RT_NULL; + ptr = first; + while (*ptr != '\0') + { if (*ptr == '.') - end = ptr - 1; + last_dot = ptr; + ptr++; + } + + /* determine end position for module name */ + if (last_dot != RT_NULL && last_dot != first) + { + /* extension found (dot not at start of filename), strip it */ + end = last_dot; + } + /* else: no extension, or filename starts with dot only (e.g., ".hidden"), + * use entire filename */ - ptr ++; + size = end - first; + if (size <= 0) + { + /* defensive: empty path or path ending with "/" */ + size = rt_strlen(first); } + if (size >= name_size) + size = name_size - 1; + + rt_strncpy(name, first, size); + name[size] = '\0'; +} - size = end - first + 1; - if (size >= RT_NAME_MAX) size = RT_NAME_MAX - 1; +/* set the name of module */ +static void _dlmodule_set_name(struct rt_dlmodule *module, const char *path) +{ + struct rt_object *object; - rt_strncpy(object->name, first, size); - object->name[size] = '\0'; + object = &(module->parent); + dlmodule_extract_name(path, object->name, RT_NAME_MAX); } #define RT_MODULE_ARG_MAX 8 diff --git a/components/libc/posix/libdl/dlmodule.h b/components/libc/posix/libdl/dlmodule.h index 75ca3258000..418c1a95c7d 100644 --- a/components/libc/posix/libdl/dlmodule.h +++ b/components/libc/posix/libdl/dlmodule.h @@ -82,6 +82,8 @@ void dlmodule_exit(int ret_code); struct rt_dlmodule *dlmodule_find(const char *name); +void dlmodule_extract_name(const char *path, char *name, int name_size); + rt_ubase_t dlmodule_symbol_find(const char *sym_str); #endif diff --git a/components/libc/posix/libdl/dlopen.c b/components/libc/posix/libdl/dlopen.c index 8545bce1180..baaf1667132 100644 --- a/components/libc/posix/libdl/dlopen.c +++ b/components/libc/posix/libdl/dlopen.c @@ -33,7 +33,8 @@ void* dlopen(const char *filename, int flags) { struct rt_dlmodule *module; char *fullpath; - const char*def_path = MODULE_ROOT_DIR; + const char *def_path = MODULE_ROOT_DIR; + char module_name[RT_NAME_MAX]; /* check parameters */ RT_ASSERT(filename != RT_NULL); @@ -48,15 +49,21 @@ void* dlopen(const char *filename, int flags) } else { - fullpath = (char*)filename; /* absolute path, use it directly */ + fullpath = (char *)filename; /* absolute path, use it directly */ } + /* Extract module name from path (strip directory and extension) + * This matches the logic in _dlmodule_set_name() so that dlmodule_find() + * can properly locate already-loaded modules by their stored name. + */ + dlmodule_extract_name(fullpath, module_name, RT_NAME_MAX); + rt_enter_critical(); - /* find in module list */ - module = dlmodule_find(fullpath); + /* find in module list using the stripped module name */ + module = dlmodule_find(module_name); - if(module != RT_NULL) + if (module != RT_NULL) { rt_exit_critical(); module->nref++; @@ -67,11 +74,11 @@ void* dlopen(const char *filename, int flags) module = dlmodule_load(fullpath); } - if(fullpath != filename) + if (fullpath != filename) { rt_free(fullpath); } - return (void*)module; + return (void *)module; } RTM_EXPORT(dlopen);