mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-06-02 21:12:20 +08:00
[libc][libdl] Fix dlopen() failing to find already-loaded modules
This commit is contained in:
@@ -33,32 +33,79 @@ static struct rt_module_symtab *_rt_module_symtab_end = RT_NULL;
|
|||||||
#pragma section="RTMSymTab"
|
#pragma section="RTMSymTab"
|
||||||
#endif
|
#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;
|
int size;
|
||||||
struct rt_object *object;
|
const char *first, *end, *ptr, *last_dot;
|
||||||
const char *first, *end, *ptr;
|
|
||||||
|
|
||||||
object = &(module->parent);
|
RT_ASSERT(path != RT_NULL);
|
||||||
ptr = first = (char *)path;
|
RT_ASSERT(name != RT_NULL);
|
||||||
|
RT_ASSERT(name_size > 0);
|
||||||
|
|
||||||
|
ptr = first = path;
|
||||||
end = path + rt_strlen(path);
|
end = path + rt_strlen(path);
|
||||||
|
|
||||||
|
/* find the start of filename (after last '/') */
|
||||||
while (*ptr != '\0')
|
while (*ptr != '\0')
|
||||||
{
|
{
|
||||||
if (*ptr == '/')
|
if (*ptr == '/')
|
||||||
first = ptr + 1;
|
first = ptr + 1;
|
||||||
if (*ptr == '.')
|
|
||||||
end = ptr - 1;
|
|
||||||
|
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
size = end - first + 1;
|
/* find last extension in filename portion only (after last '/') */
|
||||||
if (size >= RT_NAME_MAX) size = RT_NAME_MAX - 1;
|
last_dot = RT_NULL;
|
||||||
|
ptr = first;
|
||||||
|
while (*ptr != '\0')
|
||||||
|
{
|
||||||
|
if (*ptr == '.')
|
||||||
|
last_dot = ptr;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
|
||||||
rt_strncpy(object->name, first, size);
|
/* determine end position for module name */
|
||||||
object->name[size] = '\0';
|
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 */
|
||||||
|
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set the name of module */
|
||||||
|
static void _dlmodule_set_name(struct rt_dlmodule *module, const char *path)
|
||||||
|
{
|
||||||
|
struct rt_object *object;
|
||||||
|
|
||||||
|
object = &(module->parent);
|
||||||
|
dlmodule_extract_name(path, object->name, RT_NAME_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define RT_MODULE_ARG_MAX 8
|
#define RT_MODULE_ARG_MAX 8
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ void dlmodule_exit(int ret_code);
|
|||||||
|
|
||||||
struct rt_dlmodule *dlmodule_find(const char *name);
|
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);
|
rt_ubase_t dlmodule_symbol_find(const char *sym_str);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ void* dlopen(const char *filename, int flags)
|
|||||||
struct rt_dlmodule *module;
|
struct rt_dlmodule *module;
|
||||||
char *fullpath;
|
char *fullpath;
|
||||||
const char *def_path = MODULE_ROOT_DIR;
|
const char *def_path = MODULE_ROOT_DIR;
|
||||||
|
char module_name[RT_NAME_MAX];
|
||||||
|
|
||||||
/* check parameters */
|
/* check parameters */
|
||||||
RT_ASSERT(filename != RT_NULL);
|
RT_ASSERT(filename != RT_NULL);
|
||||||
@@ -51,10 +52,16 @@ void* dlopen(const char *filename, int flags)
|
|||||||
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();
|
rt_enter_critical();
|
||||||
|
|
||||||
/* find in module list */
|
/* find in module list using the stripped module name */
|
||||||
module = dlmodule_find(fullpath);
|
module = dlmodule_find(module_name);
|
||||||
|
|
||||||
if (module != RT_NULL)
|
if (module != RT_NULL)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user