Skip to content

Commit d910372

Browse files
Fix dlmodule must depends on file system issue
解决dlmodule只能依赖于文件系统的问题; 增加dlmodule扩展接口,以适应更多需求;
1 parent 20d1c13 commit d910372

File tree

3 files changed

+211
-1
lines changed

3 files changed

+211
-1
lines changed

components/libc/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,19 @@ if RT_USING_LIBC && RT_USING_DFS
3434
default n
3535
endif
3636

37+
endif
38+
39+
if RT_USING_LIBC
3740
config RT_USING_MODULE
3841
bool "Enable dynamic module with dlopen/dlsym/dlclose feature"
3942
default n
43+
44+
if RT_USING_MODULE
45+
config RT_USING_CUSTOM_DLMODULE
46+
bool "Enable load dynamic module by custom"
47+
default n
48+
endif
49+
4050
endif
4151

4252
if RT_USING_LIBC != y

components/libc/libdl/dlmodule.c

Lines changed: 189 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
#include "dlmodule.h"
1515
#include "dlelf.h"
1616

17+
#if defined(RT_USING_POSIX)
1718
#include <dfs_posix.h>
19+
#endif
1820

1921
#define DBG_TAG "DLMD"
2022
#define DBG_LVL DBG_INFO
@@ -419,11 +421,14 @@ struct rt_dlmodule *rt_module_self(void)
419421

420422
struct rt_dlmodule* dlmodule_load(const char* filename)
421423
{
422-
int fd, length = 0;
424+
#if defined(RT_USING_POSIX)
425+
int fd = -1, length = 0;
426+
#endif
423427
rt_err_t ret = RT_EOK;
424428
rt_uint8_t *module_ptr = RT_NULL;
425429
struct rt_dlmodule *module = RT_NULL;
426430

431+
#if defined(RT_USING_POSIX)
427432
fd = open(filename, O_RDONLY, 0);
428433
if (fd >= 0)
429434
{
@@ -446,6 +451,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename)
446451
{
447452
goto __exit;
448453
}
454+
#endif
455+
456+
if (!module_ptr) goto __exit;
449457

450458
/* check ELF header */
451459
if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
@@ -512,7 +520,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename)
512520
return module;
513521

514522
__exit:
523+
#if defined(RT_USING_POSIX)
515524
if (fd >= 0) close(fd);
525+
#endif
516526
if (module_ptr) rt_free(module_ptr);
517527
if (module) dlmodule_destroy(module);
518528

@@ -558,6 +568,184 @@ struct rt_dlmodule* dlmodule_exec(const char* pgname, const char* cmd, int cmd_s
558568
return module;
559569
}
560570

571+
#if defined(RT_USING_CUSTOM_DLMODULE)
572+
struct rt_dlmodule* dlmodule_load_custom(const char* filename, struct rt_dlmodule_ops* ops)
573+
{
574+
#if defined(RT_USING_POSIX)
575+
int fd = -1, length = 0;
576+
#endif
577+
rt_err_t ret = RT_EOK;
578+
rt_uint8_t *module_ptr = RT_NULL;
579+
struct rt_dlmodule *module = RT_NULL;
580+
581+
if (ops)
582+
{
583+
RT_ASSERT(ops->load);
584+
RT_ASSERT(ops->unload);
585+
module_ptr = ops->load(filename);
586+
}
587+
#if defined(RT_USING_POSIX)
588+
else
589+
{
590+
fd = open(filename, O_RDONLY, 0);
591+
if (fd >= 0)
592+
{
593+
length = lseek(fd, 0, SEEK_END);
594+
lseek(fd, 0, SEEK_SET);
595+
596+
if (length == 0) goto __exit;
597+
598+
module_ptr = (uint8_t*) rt_malloc (length);
599+
if (!module_ptr) goto __exit;
600+
601+
if (read(fd, module_ptr, length) != length)
602+
goto __exit;
603+
604+
/* close file and release fd */
605+
close(fd);
606+
fd = -1;
607+
}
608+
else
609+
{
610+
goto __exit;
611+
}
612+
}
613+
#endif
614+
615+
if (!module_ptr) goto __exit;
616+
617+
/* check ELF header */
618+
if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
619+
rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0)
620+
{
621+
rt_kprintf("Module: magic error\n");
622+
goto __exit;
623+
}
624+
625+
/* check ELF class */
626+
if (elf_module->e_ident[EI_CLASS] != ELFCLASS32)
627+
{
628+
rt_kprintf("Module: ELF class error\n");
629+
goto __exit;
630+
}
631+
632+
module = dlmodule_create();
633+
if (!module) goto __exit;
634+
635+
/* set the name of module */
636+
_dlmodule_set_name(module, filename);
637+
638+
LOG_D("rt_module_load: %.*s", RT_NAME_MAX, module->parent.name);
639+
640+
if (elf_module->e_type == ET_REL)
641+
{
642+
ret = dlmodule_load_relocated_object(module, module_ptr);
643+
}
644+
else if (elf_module->e_type == ET_DYN)
645+
{
646+
ret = dlmodule_load_shared_object(module, module_ptr);
647+
}
648+
else
649+
{
650+
rt_kprintf("Module: unsupported elf type\n");
651+
goto __exit;
652+
}
653+
654+
/* check return value */
655+
if (ret != RT_EOK) goto __exit;
656+
657+
/* release module data */
658+
if (ops)
659+
{
660+
ops->unload(module_ptr);
661+
}
662+
else
663+
{
664+
rt_free(module_ptr);
665+
}
666+
667+
/* increase module reference count */
668+
module->nref ++;
669+
670+
/* deal with cache */
671+
#ifdef RT_USING_CACHE
672+
rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, module->mem_space, module->mem_size);
673+
rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, module->mem_space, module->mem_size);
674+
#endif
675+
676+
/* set module initialization and cleanup function */
677+
module->init_func = dlsym(module, "module_init");
678+
module->cleanup_func = dlsym(module, "module_cleanup");
679+
module->stat = RT_DLMODULE_STAT_INIT;
680+
/* do module initialization */
681+
if (module->init_func)
682+
{
683+
module->init_func(module);
684+
}
685+
686+
return module;
687+
688+
__exit:
689+
#if defined(RT_USING_POSIX)
690+
if (fd >= 0) close(fd);
691+
#endif
692+
if (module_ptr)
693+
{
694+
if (ops)
695+
{
696+
ops->unload(module_ptr);
697+
}
698+
else
699+
{
700+
rt_free(module_ptr);
701+
}
702+
}
703+
704+
if (module) dlmodule_destroy(module);
705+
706+
return RT_NULL;
707+
}
708+
709+
struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops)
710+
{
711+
struct rt_dlmodule *module = RT_NULL;
712+
713+
module = dlmodule_load_custom(pgname, ops);
714+
if (module)
715+
{
716+
if (module->entry_addr)
717+
{
718+
/* exec this module */
719+
rt_thread_t tid;
720+
721+
module->cmd_line = rt_strdup(cmd);
722+
723+
/* check stack size and priority */
724+
if (module->priority > RT_THREAD_PRIORITY_MAX) module->priority = RT_THREAD_PRIORITY_MAX - 1;
725+
if (module->stack_size < 2048 || module->stack_size > (1024 * 32)) module->stack_size = 2048;
726+
727+
tid = rt_thread_create(module->parent.name, _dlmodule_thread_entry, (void*)module,
728+
module->stack_size, module->priority, 10);
729+
if (tid)
730+
{
731+
tid->module_id = module;
732+
module->main_thread = tid;
733+
734+
rt_thread_startup(tid);
735+
}
736+
else
737+
{
738+
/* destory dl module */
739+
dlmodule_destroy(module);
740+
module = RT_NULL;
741+
}
742+
}
743+
}
744+
745+
return module;
746+
}
747+
#endif
748+
561749
void dlmodule_exit(int ret_code)
562750
{
563751
rt_thread_t thread;

components/libc/libdl/dlmodule.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,25 @@ struct rt_dlmodule
5959
struct rt_module_symtab *symtab; /* module symbol table */
6060
};
6161

62+
struct rt_dlmodule_ops
63+
{
64+
rt_uint8_t *(*load)(const char* filename); /* load dlmodule file data */
65+
rt_err_t (*unload)(rt_uint8_t *param); /* unload dlmodule file data */
66+
};
67+
6268
struct rt_dlmodule *dlmodule_create(void);
6369
rt_err_t dlmodule_destroy(struct rt_dlmodule* module);
6470

6571
struct rt_dlmodule *dlmodule_self(void);
6672

6773
struct rt_dlmodule *dlmodule_load(const char* pgname);
6874
struct rt_dlmodule *dlmodule_exec(const char* pgname, const char* cmd, int cmd_size);
75+
76+
#if defined(RT_USING_CUSTOM_DLMODULE)
77+
struct rt_dlmodule* dlmodule_load_custom(const char* filename, struct rt_dlmodule_ops* ops);
78+
struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops);
79+
#endif
80+
6981
void dlmodule_exit(int ret_code);
7082

7183
struct rt_dlmodule *dlmodule_find(const char *name);

0 commit comments

Comments
 (0)