Skip to content

Commit 121366d

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

File tree

2 files changed

+193
-1
lines changed

2 files changed

+193
-1
lines changed

components/libc/libdl/dlmodule.c

Lines changed: 183 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,12 @@ struct rt_dlmodule *rt_module_self(void)
419421

420422
struct rt_dlmodule* dlmodule_load(const char* filename)
421423
{
422-
int fd, length = 0;
424+
int fd = -1, length = 0;
423425
rt_err_t ret = RT_EOK;
424426
rt_uint8_t *module_ptr = RT_NULL;
425427
struct rt_dlmodule *module = RT_NULL;
426428

429+
#if defined(RT_USING_POSIX)
427430
fd = open(filename, O_RDONLY, 0);
428431
if (fd >= 0)
429432
{
@@ -446,6 +449,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename)
446449
{
447450
goto __exit;
448451
}
452+
#endif
453+
454+
if (!module_ptr) goto __exit;
449455

450456
/* check ELF header */
451457
if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
@@ -512,7 +518,9 @@ struct rt_dlmodule* dlmodule_load(const char* filename)
512518
return module;
513519

514520
__exit:
521+
#if defined(RT_USING_POSIX)
515522
if (fd >= 0) close(fd);
523+
#endif
516524
if (module_ptr) rt_free(module_ptr);
517525
if (module) dlmodule_destroy(module);
518526

@@ -558,6 +566,180 @@ struct rt_dlmodule* dlmodule_exec(const char* pgname, const char* cmd, int cmd_s
558566
return module;
559567
}
560568

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

components/libc/libdl/dlmodule.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,23 @@ 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+
struct rt_dlmodule* dlmodule_ext_load(const char* filename, struct rt_dlmodule_ops* ops);
77+
struct rt_dlmodule* dlmodule_ext_exec(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops);
78+
6979
void dlmodule_exit(int ret_code);
7080

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

0 commit comments

Comments
 (0)