Skip to content

Commit 828de39

Browse files
authored
[libc][libdl] Fix dlopen() failing to find already-loaded modules
1 parent fab5966 commit 828de39

File tree

3 files changed

+76
-20
lines changed

3 files changed

+76
-20
lines changed

components/libc/posix/libdl/dlmodule.c

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,32 +33,79 @@ static struct rt_module_symtab *_rt_module_symtab_end = RT_NULL;
3333
#pragma section="RTMSymTab"
3434
#endif
3535

36-
/* set the name of module */
37-
static void _dlmodule_set_name(struct rt_dlmodule *module, const char *path)
36+
/**
37+
* @brief Extract module name from a file path by stripping directory and extension.
38+
*
39+
* @param path the file path (e.g., "/mnt/sdcard/apps/clock.so")
40+
* @param name buffer to store the extracted module name
41+
* @param name_size size of the name buffer
42+
*
43+
* @note This function extracts the base name without path and extension.
44+
* Examples:
45+
* - "/mnt/sdcard/apps/clock.so" -> "clock"
46+
* - "/mnt/v1.2/app.so" -> "app" (dots in path are ignored)
47+
* - ".hidden" -> ".hidden" (hidden files without extension)
48+
* - ".hidden.so" -> ".hidden" (hidden files with extension)
49+
*/
50+
void dlmodule_extract_name(const char *path, char *name, int name_size)
3851
{
3952
int size;
40-
struct rt_object *object;
41-
const char *first, *end, *ptr;
53+
const char *first, *end, *ptr, *last_dot;
4254

43-
object = &(module->parent);
44-
ptr = first = (char *)path;
45-
end = path + rt_strlen(path);
55+
RT_ASSERT(path != RT_NULL);
56+
RT_ASSERT(name != RT_NULL);
57+
RT_ASSERT(name_size > 0);
58+
59+
ptr = first = path;
60+
end = path + rt_strlen(path);
4661

62+
/* find the start of filename (after last '/') */
4763
while (*ptr != '\0')
4864
{
4965
if (*ptr == '/')
5066
first = ptr + 1;
67+
ptr++;
68+
}
69+
70+
/* find last extension in filename portion only (after last '/') */
71+
last_dot = RT_NULL;
72+
ptr = first;
73+
while (*ptr != '\0')
74+
{
5175
if (*ptr == '.')
52-
end = ptr - 1;
76+
last_dot = ptr;
77+
ptr++;
78+
}
79+
80+
/* determine end position for module name */
81+
if (last_dot != RT_NULL && last_dot != first)
82+
{
83+
/* extension found (dot not at start of filename), strip it */
84+
end = last_dot;
85+
}
86+
/* else: no extension, or filename starts with dot only (e.g., ".hidden"),
87+
* use entire filename */
5388

54-
ptr ++;
89+
size = end - first;
90+
if (size <= 0)
91+
{
92+
/* defensive: empty path or path ending with "/" */
93+
size = rt_strlen(first);
5594
}
95+
if (size >= name_size)
96+
size = name_size - 1;
97+
98+
rt_strncpy(name, first, size);
99+
name[size] = '\0';
100+
}
56101

57-
size = end - first + 1;
58-
if (size >= RT_NAME_MAX) size = RT_NAME_MAX - 1;
102+
/* set the name of module */
103+
static void _dlmodule_set_name(struct rt_dlmodule *module, const char *path)
104+
{
105+
struct rt_object *object;
59106

60-
rt_strncpy(object->name, first, size);
61-
object->name[size] = '\0';
107+
object = &(module->parent);
108+
dlmodule_extract_name(path, object->name, RT_NAME_MAX);
62109
}
63110

64111
#define RT_MODULE_ARG_MAX 8

components/libc/posix/libdl/dlmodule.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ void dlmodule_exit(int ret_code);
8282

8383
struct rt_dlmodule *dlmodule_find(const char *name);
8484

85+
void dlmodule_extract_name(const char *path, char *name, int name_size);
86+
8587
rt_ubase_t dlmodule_symbol_find(const char *sym_str);
8688

8789
#endif

components/libc/posix/libdl/dlopen.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ void* dlopen(const char *filename, int flags)
3333
{
3434
struct rt_dlmodule *module;
3535
char *fullpath;
36-
const char*def_path = MODULE_ROOT_DIR;
36+
const char *def_path = MODULE_ROOT_DIR;
37+
char module_name[RT_NAME_MAX];
3738

3839
/* check parameters */
3940
RT_ASSERT(filename != RT_NULL);
@@ -48,15 +49,21 @@ void* dlopen(const char *filename, int flags)
4849
}
4950
else
5051
{
51-
fullpath = (char*)filename; /* absolute path, use it directly */
52+
fullpath = (char *)filename; /* absolute path, use it directly */
5253
}
5354

55+
/* Extract module name from path (strip directory and extension)
56+
* This matches the logic in _dlmodule_set_name() so that dlmodule_find()
57+
* can properly locate already-loaded modules by their stored name.
58+
*/
59+
dlmodule_extract_name(fullpath, module_name, RT_NAME_MAX);
60+
5461
rt_enter_critical();
5562

56-
/* find in module list */
57-
module = dlmodule_find(fullpath);
63+
/* find in module list using the stripped module name */
64+
module = dlmodule_find(module_name);
5865

59-
if(module != RT_NULL)
66+
if (module != RT_NULL)
6067
{
6168
rt_exit_critical();
6269
module->nref++;
@@ -67,11 +74,11 @@ void* dlopen(const char *filename, int flags)
6774
module = dlmodule_load(fullpath);
6875
}
6976

70-
if(fullpath != filename)
77+
if (fullpath != filename)
7178
{
7279
rt_free(fullpath);
7380
}
7481

75-
return (void*)module;
82+
return (void *)module;
7683
}
7784
RTM_EXPORT(dlopen);

0 commit comments

Comments
 (0)