Merge pull request #3294 from tonyzheng-rockchip/fix-dlmodule

Fix dlmodule must depends on file system issue
This commit is contained in:
Bernard Xiong 2019-12-27 15:42:28 +08:00 committed by GitHub
commit c2322353aa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 211 additions and 1 deletions

View File

@ -34,9 +34,19 @@ if RT_USING_LIBC && RT_USING_DFS
default n default n
endif endif
endif
if RT_USING_LIBC
config RT_USING_MODULE config RT_USING_MODULE
bool "Enable dynamic module with dlopen/dlsym/dlclose feature" bool "Enable dynamic module with dlopen/dlsym/dlclose feature"
default n default n
if RT_USING_MODULE
config RT_USING_CUSTOM_DLMODULE
bool "Enable load dynamic module by custom"
default n
endif
endif endif
if RT_USING_LIBC != y if RT_USING_LIBC != y

View File

@ -14,7 +14,9 @@
#include "dlmodule.h" #include "dlmodule.h"
#include "dlelf.h" #include "dlelf.h"
#if defined(RT_USING_POSIX)
#include <dfs_posix.h> #include <dfs_posix.h>
#endif
#define DBG_TAG "DLMD" #define DBG_TAG "DLMD"
#define DBG_LVL DBG_INFO #define DBG_LVL DBG_INFO
@ -419,11 +421,14 @@ struct rt_dlmodule *rt_module_self(void)
struct rt_dlmodule* dlmodule_load(const char* filename) struct rt_dlmodule* dlmodule_load(const char* filename)
{ {
int fd, length = 0; #if defined(RT_USING_POSIX)
int fd = -1, length = 0;
#endif
rt_err_t ret = RT_EOK; rt_err_t ret = RT_EOK;
rt_uint8_t *module_ptr = RT_NULL; rt_uint8_t *module_ptr = RT_NULL;
struct rt_dlmodule *module = RT_NULL; struct rt_dlmodule *module = RT_NULL;
#if defined(RT_USING_POSIX)
fd = open(filename, O_RDONLY, 0); fd = open(filename, O_RDONLY, 0);
if (fd >= 0) if (fd >= 0)
{ {
@ -446,6 +451,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename)
{ {
goto __exit; goto __exit;
} }
#endif
if (!module_ptr) goto __exit;
/* check ELF header */ /* check ELF header */
if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 && if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
@ -512,7 +520,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename)
return module; return module;
__exit: __exit:
#if defined(RT_USING_POSIX)
if (fd >= 0) close(fd); if (fd >= 0) close(fd);
#endif
if (module_ptr) rt_free(module_ptr); if (module_ptr) rt_free(module_ptr);
if (module) dlmodule_destroy(module); if (module) dlmodule_destroy(module);
@ -558,6 +568,184 @@ struct rt_dlmodule* dlmodule_exec(const char* pgname, const char* cmd, int cmd_s
return module; return module;
} }
#if defined(RT_USING_CUSTOM_DLMODULE)
struct rt_dlmodule* dlmodule_load_custom(const char* filename, struct rt_dlmodule_ops* ops)
{
#if defined(RT_USING_POSIX)
int fd = -1, length = 0;
#endif
rt_err_t ret = RT_EOK;
rt_uint8_t *module_ptr = RT_NULL;
struct rt_dlmodule *module = RT_NULL;
if (ops)
{
RT_ASSERT(ops->load);
RT_ASSERT(ops->unload);
module_ptr = ops->load(filename);
}
#if defined(RT_USING_POSIX)
else
{
fd = open(filename, O_RDONLY, 0);
if (fd >= 0)
{
length = lseek(fd, 0, SEEK_END);
lseek(fd, 0, SEEK_SET);
if (length == 0) goto __exit;
module_ptr = (uint8_t*) rt_malloc (length);
if (!module_ptr) goto __exit;
if (read(fd, module_ptr, length) != length)
goto __exit;
/* close file and release fd */
close(fd);
fd = -1;
}
else
{
goto __exit;
}
}
#endif
if (!module_ptr) goto __exit;
/* check ELF header */
if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0)
{
rt_kprintf("Module: magic error\n");
goto __exit;
}
/* check ELF class */
if (elf_module->e_ident[EI_CLASS] != ELFCLASS32)
{
rt_kprintf("Module: ELF class error\n");
goto __exit;
}
module = dlmodule_create();
if (!module) goto __exit;
/* set the name of module */
_dlmodule_set_name(module, filename);
LOG_D("rt_module_load: %.*s", RT_NAME_MAX, module->parent.name);
if (elf_module->e_type == ET_REL)
{
ret = dlmodule_load_relocated_object(module, module_ptr);
}
else if (elf_module->e_type == ET_DYN)
{
ret = dlmodule_load_shared_object(module, module_ptr);
}
else
{
rt_kprintf("Module: unsupported elf type\n");
goto __exit;
}
/* check return value */
if (ret != RT_EOK) goto __exit;
/* release module data */
if (ops)
{
ops->unload(module_ptr);
}
else
{
rt_free(module_ptr);
}
/* increase module reference count */
module->nref ++;
/* deal with cache */
#ifdef RT_USING_CACHE
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, module->mem_space, module->mem_size);
rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, module->mem_space, module->mem_size);
#endif
/* set module initialization and cleanup function */
module->init_func = dlsym(module, "module_init");
module->cleanup_func = dlsym(module, "module_cleanup");
module->stat = RT_DLMODULE_STAT_INIT;
/* do module initialization */
if (module->init_func)
{
module->init_func(module);
}
return module;
__exit:
#if defined(RT_USING_POSIX)
if (fd >= 0) close(fd);
#endif
if (module_ptr)
{
if (ops)
{
ops->unload(module_ptr);
}
else
{
rt_free(module_ptr);
}
}
if (module) dlmodule_destroy(module);
return RT_NULL;
}
struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops)
{
struct rt_dlmodule *module = RT_NULL;
module = dlmodule_load_custom(pgname, ops);
if (module)
{
if (module->entry_addr)
{
/* exec this module */
rt_thread_t tid;
module->cmd_line = rt_strdup(cmd);
/* check stack size and priority */
if (module->priority > RT_THREAD_PRIORITY_MAX) module->priority = RT_THREAD_PRIORITY_MAX - 1;
if (module->stack_size < 2048 || module->stack_size > (1024 * 32)) module->stack_size = 2048;
tid = rt_thread_create(module->parent.name, _dlmodule_thread_entry, (void*)module,
module->stack_size, module->priority, 10);
if (tid)
{
tid->module_id = module;
module->main_thread = tid;
rt_thread_startup(tid);
}
else
{
/* destory dl module */
dlmodule_destroy(module);
module = RT_NULL;
}
}
}
return module;
}
#endif
void dlmodule_exit(int ret_code) void dlmodule_exit(int ret_code)
{ {
rt_thread_t thread; rt_thread_t thread;

View File

@ -59,6 +59,12 @@ struct rt_dlmodule
struct rt_module_symtab *symtab; /* module symbol table */ struct rt_module_symtab *symtab; /* module symbol table */
}; };
struct rt_dlmodule_ops
{
rt_uint8_t *(*load)(const char* filename); /* load dlmodule file data */
rt_err_t (*unload)(rt_uint8_t *param); /* unload dlmodule file data */
};
struct rt_dlmodule *dlmodule_create(void); struct rt_dlmodule *dlmodule_create(void);
rt_err_t dlmodule_destroy(struct rt_dlmodule* module); rt_err_t dlmodule_destroy(struct rt_dlmodule* module);
@ -66,6 +72,12 @@ struct rt_dlmodule *dlmodule_self(void);
struct rt_dlmodule *dlmodule_load(const char* pgname); struct rt_dlmodule *dlmodule_load(const char* pgname);
struct rt_dlmodule *dlmodule_exec(const char* pgname, const char* cmd, int cmd_size); struct rt_dlmodule *dlmodule_exec(const char* pgname, const char* cmd, int cmd_size);
#if defined(RT_USING_CUSTOM_DLMODULE)
struct rt_dlmodule* dlmodule_load_custom(const char* filename, struct rt_dlmodule_ops* ops);
struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops);
#endif
void dlmodule_exit(int ret_code); void dlmodule_exit(int ret_code);
struct rt_dlmodule *dlmodule_find(const char *name); struct rt_dlmodule *dlmodule_find(const char *name);