Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 60 additions & 13 deletions components/libc/posix/libdl/dlmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions components/libc/posix/libdl/dlmodule.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
21 changes: 14 additions & 7 deletions components/libc/posix/libdl/dlopen.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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++;
Expand All @@ -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);