Merge pull request #3294 from tonyzheng-rockchip/fix-dlmodule
Fix dlmodule must depends on file system issue
This commit is contained in:
commit
c2322353aa
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue