dlmodule.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2018/08/29 Bernard first version
  9. */
  10. #include <rthw.h>
  11. #include "dlfcn.h"
  12. #include "dlmodule.h"
  13. #include "dlelf.h"
  14. #ifdef RT_USING_POSIX_FS
  15. #include <fcntl.h>
  16. #include <unistd.h>
  17. #include <sys/stat.h>
  18. #include <sys/statfs.h>
  19. #endif
  20. #define DBG_TAG "DLMD"
  21. #define DBG_LVL DBG_INFO
  22. #include <rtdbg.h> // must after of DEBUG_ENABLE or some other options
  23. static struct rt_module_symtab *_rt_module_symtab_begin = RT_NULL;
  24. static struct rt_module_symtab *_rt_module_symtab_end = RT_NULL;
  25. #if defined(__IAR_SYSTEMS_ICC__) /* for IAR compiler */
  26. #pragma section="RTMSymTab"
  27. #endif
  28. /* set the name of module */
  29. static void _dlmodule_set_name(struct rt_dlmodule *module, const char *path)
  30. {
  31. int size;
  32. struct rt_object *object;
  33. const char *first, *end, *ptr;
  34. object = &(module->parent);
  35. ptr = first = (char *)path;
  36. end = path + rt_strlen(path);
  37. while (*ptr != '\0')
  38. {
  39. if (*ptr == '/')
  40. first = ptr + 1;
  41. if (*ptr == '.')
  42. end = ptr - 1;
  43. ptr ++;
  44. }
  45. size = end - first + 1;
  46. if (size > RT_NAME_MAX) size = RT_NAME_MAX;
  47. rt_strncpy(object->name, first, size);
  48. object->name[size] = '\0';
  49. }
  50. #define RT_MODULE_ARG_MAX 8
  51. static int _rt_module_split_arg(char *cmd, rt_size_t length, char *argv[])
  52. {
  53. int argc = 0;
  54. char *ptr = cmd;
  55. while ((ptr - cmd) < length)
  56. {
  57. /* strip bank and tab */
  58. while ((*ptr == ' ' || *ptr == '\t') && (ptr - cmd) < length)
  59. *ptr++ = '\0';
  60. /* check whether it's the end of line */
  61. if ((ptr - cmd) >= length) break;
  62. /* handle string with quote */
  63. if (*ptr == '"')
  64. {
  65. argv[argc++] = ++ptr;
  66. /* skip this string */
  67. while (*ptr != '"' && (ptr - cmd) < length)
  68. if (*ptr ++ == '\\') ptr ++;
  69. if ((ptr - cmd) >= length) break;
  70. /* skip '"' */
  71. *ptr ++ = '\0';
  72. }
  73. else
  74. {
  75. argv[argc++] = ptr;
  76. while ((*ptr != ' ' && *ptr != '\t') && (ptr - cmd) < length)
  77. ptr ++;
  78. }
  79. if (argc >= RT_MODULE_ARG_MAX) break;
  80. }
  81. return argc;
  82. }
  83. /* invoked by main thread for exit */
  84. static void _dlmodule_exit(void)
  85. {
  86. struct rt_dlmodule *module;
  87. module = dlmodule_self();
  88. if (!module) return; /* not a module thread */
  89. rt_enter_critical();
  90. if (module->stat == RT_DLMODULE_STAT_RUNNING)
  91. {
  92. struct rt_object *object = RT_NULL;
  93. struct rt_list_node *node = RT_NULL;
  94. /* set stat to closing */
  95. module->stat = RT_DLMODULE_STAT_CLOSING;
  96. /* suspend all threads in this module */
  97. for (node = module->object_list.next; node != &(module->object_list); node = node->next)
  98. {
  99. object = rt_list_entry(node, struct rt_object, list);
  100. if ((object->type & ~RT_Object_Class_Static) == RT_Object_Class_Thread)
  101. {
  102. rt_thread_t thread = (rt_thread_t)object;
  103. /* stop timer and suspend thread*/
  104. if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_CLOSE &&
  105. (thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_INIT)
  106. {
  107. rt_timer_stop(&(thread->thread_timer));
  108. rt_thread_suspend(thread);
  109. }
  110. }
  111. }
  112. }
  113. rt_exit_critical();
  114. return;
  115. }
  116. static void _dlmodule_thread_entry(void* parameter)
  117. {
  118. int argc = 0;
  119. char *argv[RT_MODULE_ARG_MAX];
  120. struct rt_dlmodule *module = (struct rt_dlmodule*)parameter;
  121. if (module == RT_NULL || module->cmd_line == RT_NULL)
  122. /* malloc for module_cmd_line failed. */
  123. return;
  124. if (module->cmd_line)
  125. {
  126. rt_memset(argv, 0x00, sizeof(argv));
  127. argc = _rt_module_split_arg((char *)module->cmd_line, rt_strlen(module->cmd_line), argv);
  128. if (argc == 0) goto __exit;
  129. }
  130. /* set status of module */
  131. module->stat = RT_DLMODULE_STAT_RUNNING;
  132. LOG_D("run main entry: 0x%p with %s",
  133. module->entry_addr,
  134. module->cmd_line);
  135. if (module->entry_addr)
  136. module->entry_addr(argc, argv);
  137. __exit:
  138. _dlmodule_exit();
  139. return ;
  140. }
  141. struct rt_dlmodule *dlmodule_create(void)
  142. {
  143. struct rt_dlmodule *module = RT_NULL;
  144. module = (struct rt_dlmodule*) rt_object_allocate(RT_Object_Class_Module, "module");
  145. if (module)
  146. {
  147. module->stat = RT_DLMODULE_STAT_INIT;
  148. /* set initial priority and stack size */
  149. module->priority = RT_THREAD_PRIORITY_MAX - 1;
  150. module->stack_size = 2048;
  151. rt_list_init(&(module->object_list));
  152. }
  153. return module;
  154. }
  155. void dlmodule_destroy_subthread(struct rt_dlmodule *module, rt_thread_t thread)
  156. {
  157. RT_ASSERT(thread->module_id == module);
  158. /* lock scheduler to prevent scheduling in cleanup function. */
  159. rt_enter_critical();
  160. /* remove thread from thread_list (ready or defunct thread list) */
  161. rt_list_remove(&(thread->tlist));
  162. if ((thread->stat & RT_THREAD_STAT_MASK) != RT_THREAD_CLOSE &&
  163. (thread->thread_timer.parent.type == (RT_Object_Class_Static | RT_Object_Class_Timer)))
  164. {
  165. /* release thread timer */
  166. rt_timer_detach(&(thread->thread_timer));
  167. }
  168. /* change stat */
  169. thread->stat = RT_THREAD_CLOSE;
  170. /* invoke thread cleanup */
  171. if (thread->cleanup != RT_NULL)
  172. thread->cleanup(thread);
  173. rt_exit_critical();
  174. #ifdef RT_USING_SIGNALS
  175. rt_thread_free_sig(thread);
  176. #endif
  177. if (thread->type & RT_Object_Class_Static)
  178. {
  179. /* detach object */
  180. rt_object_detach((rt_object_t)thread);
  181. }
  182. #ifdef RT_USING_HEAP
  183. else
  184. {
  185. /* release thread's stack */
  186. RT_KERNEL_FREE(thread->stack_addr);
  187. /* delete thread object */
  188. rt_object_delete((rt_object_t)thread);
  189. }
  190. #endif
  191. }
  192. rt_err_t dlmodule_destroy(struct rt_dlmodule* module)
  193. {
  194. int i;
  195. RT_DEBUG_NOT_IN_INTERRUPT;
  196. /* check parameter */
  197. if (module == RT_NULL)
  198. return -RT_ERROR;
  199. /* can not destroy a running module */
  200. if (module->stat == RT_DLMODULE_STAT_RUNNING)
  201. return -RT_EBUSY;
  202. /* do module cleanup */
  203. if (module->cleanup_func)
  204. {
  205. rt_enter_critical();
  206. module->cleanup_func(module);
  207. rt_exit_critical();
  208. }
  209. // list_object(&(module->object_list));
  210. /* cleanup for all kernel objects inside module*/
  211. {
  212. struct rt_object *object = RT_NULL;
  213. struct rt_list_node *node = RT_NULL;
  214. /* detach/delete all threads in this module */
  215. for (node = module->object_list.next; node != &(module->object_list); )
  216. {
  217. int object_type;
  218. object = rt_list_entry(node, struct rt_object, list);
  219. object_type = object->type & ~RT_Object_Class_Static;
  220. /* to next node */
  221. node = node->next;
  222. if (object->type & RT_Object_Class_Static)
  223. {
  224. switch (object_type)
  225. {
  226. case RT_Object_Class_Thread:
  227. dlmodule_destroy_subthread(module, (rt_thread_t)object);
  228. break;
  229. #ifdef RT_USING_SEMAPHORE
  230. case RT_Object_Class_Semaphore:
  231. rt_sem_detach((rt_sem_t)object);
  232. break;
  233. #endif
  234. #ifdef RT_USING_MUTEX
  235. case RT_Object_Class_Mutex:
  236. rt_mutex_detach((rt_mutex_t)object);
  237. break;
  238. #endif
  239. #ifdef RT_USING_EVENT
  240. case RT_Object_Class_Event:
  241. rt_event_detach((rt_event_t)object);
  242. break;
  243. #endif
  244. #ifdef RT_USING_MAILBOX
  245. case RT_Object_Class_MailBox:
  246. rt_mb_detach((rt_mailbox_t)object);
  247. break;
  248. #endif
  249. #ifdef RT_USING_MESSAGEQUEUE
  250. case RT_Object_Class_MessageQueue:
  251. rt_mq_detach((rt_mq_t)object);
  252. break;
  253. #endif
  254. #ifdef RT_USING_MEMHEAP
  255. case RT_Object_Class_MemHeap:
  256. rt_memheap_detach((struct rt_memheap*)object);
  257. break;
  258. #endif
  259. #ifdef RT_USING_MEMPOOL
  260. case RT_Object_Class_MemPool:
  261. rt_mp_detach((struct rt_mempool*)object);
  262. break;
  263. #endif
  264. case RT_Object_Class_Timer:
  265. rt_timer_detach((rt_timer_t)object);
  266. break;
  267. default:
  268. LOG_E("Unsupported oject type in module.");
  269. break;
  270. }
  271. }
  272. else
  273. {
  274. switch (object_type)
  275. {
  276. case RT_Object_Class_Thread:
  277. dlmodule_destroy_subthread(module, (rt_thread_t)object);
  278. break;
  279. #ifdef RT_USING_SEMAPHORE
  280. case RT_Object_Class_Semaphore:
  281. rt_sem_delete((rt_sem_t)object);
  282. break;
  283. #endif
  284. #ifdef RT_USING_MUTEX
  285. case RT_Object_Class_Mutex:
  286. rt_mutex_delete((rt_mutex_t)object);
  287. break;
  288. #endif
  289. #ifdef RT_USING_EVENT
  290. case RT_Object_Class_Event:
  291. rt_event_delete((rt_event_t)object);
  292. break;
  293. #endif
  294. #ifdef RT_USING_MAILBOX
  295. case RT_Object_Class_MailBox:
  296. rt_mb_delete((rt_mailbox_t)object);
  297. break;
  298. #endif
  299. #ifdef RT_USING_MESSAGEQUEUE
  300. case RT_Object_Class_MessageQueue:
  301. rt_mq_delete((rt_mq_t)object);
  302. break;
  303. #endif
  304. #ifdef RT_USING_MEMHEAP
  305. /* no delete operation */
  306. #endif
  307. #ifdef RT_USING_MEMPOOL
  308. case RT_Object_Class_MemPool:
  309. rt_mp_delete((struct rt_mempool*)object);
  310. break;
  311. #endif
  312. case RT_Object_Class_Timer:
  313. rt_timer_delete((rt_timer_t)object);
  314. break;
  315. default:
  316. LOG_E("Unsupported oject type in module.");
  317. break;
  318. }
  319. }
  320. }
  321. }
  322. if (module->cmd_line) rt_free(module->cmd_line);
  323. /* release module symbol table */
  324. for (i = 0; i < module->nsym; i ++)
  325. {
  326. rt_free((void *)module->symtab[i].name);
  327. }
  328. if (module->symtab != RT_NULL)
  329. {
  330. rt_free(module->symtab);
  331. }
  332. /* destory module */
  333. rt_free(module->mem_space);
  334. /* delete module object */
  335. rt_object_delete((rt_object_t)module);
  336. return RT_EOK;
  337. }
  338. struct rt_dlmodule *dlmodule_self(void)
  339. {
  340. rt_thread_t tid;
  341. struct rt_dlmodule *ret = RT_NULL;
  342. tid = rt_thread_self();
  343. if (tid)
  344. {
  345. ret = (struct rt_dlmodule*) tid->module_id;
  346. }
  347. return ret;
  348. }
  349. /*
  350. * Compatible with old API
  351. */
  352. struct rt_dlmodule *rt_module_self(void)
  353. {
  354. return dlmodule_self();
  355. }
  356. struct rt_dlmodule* dlmodule_load(const char* filename)
  357. {
  358. #ifdef RT_USING_POSIX_FS
  359. int fd = -1, length = 0;
  360. #endif
  361. rt_err_t ret = RT_EOK;
  362. rt_uint8_t *module_ptr = RT_NULL;
  363. struct rt_dlmodule *module = RT_NULL;
  364. #ifdef RT_USING_POSIX_FS
  365. fd = open(filename, O_RDONLY, 0);
  366. if (fd >= 0)
  367. {
  368. length = lseek(fd, 0, SEEK_END);
  369. lseek(fd, 0, SEEK_SET);
  370. if (length == 0) goto __exit;
  371. module_ptr = (uint8_t*) rt_malloc (length);
  372. if (!module_ptr) goto __exit;
  373. if (read(fd, module_ptr, length) != length)
  374. goto __exit;
  375. /* close file and release fd */
  376. close(fd);
  377. fd = -1;
  378. }
  379. else
  380. {
  381. goto __exit;
  382. }
  383. #endif
  384. if (!module_ptr) goto __exit;
  385. /* check ELF header */
  386. if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
  387. rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0)
  388. {
  389. rt_kprintf("Module: magic error\n");
  390. goto __exit;
  391. }
  392. /* check ELF class */
  393. if ((elf_module->e_ident[EI_CLASS] != ELFCLASS32)&&(elf_module->e_ident[EI_CLASS] != ELFCLASS64))
  394. {
  395. rt_kprintf("Module: ELF class error\n");
  396. goto __exit;
  397. }
  398. module = dlmodule_create();
  399. if (!module) goto __exit;
  400. /* set the name of module */
  401. _dlmodule_set_name(module, filename);
  402. LOG_D("rt_module_load: %.*s", RT_NAME_MAX, module->parent.name);
  403. if (elf_module->e_type == ET_REL)
  404. {
  405. ret = dlmodule_load_relocated_object(module, module_ptr);
  406. }
  407. else if (elf_module->e_type == ET_DYN)
  408. {
  409. ret = dlmodule_load_shared_object(module, module_ptr);
  410. }
  411. else
  412. {
  413. rt_kprintf("Module: unsupported elf type\n");
  414. goto __exit;
  415. }
  416. /* check return value */
  417. if (ret != RT_EOK) goto __exit;
  418. /* release module data */
  419. rt_free(module_ptr);
  420. /* increase module reference count */
  421. module->nref ++;
  422. /* deal with cache */
  423. #ifdef RT_USING_CACHE
  424. rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, module->mem_space, module->mem_size);
  425. rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, module->mem_space, module->mem_size);
  426. #endif
  427. /* set module initialization and cleanup function */
  428. module->init_func = dlsym(module, "module_init");
  429. module->cleanup_func = dlsym(module, "module_cleanup");
  430. module->stat = RT_DLMODULE_STAT_INIT;
  431. /* do module initialization */
  432. if (module->init_func)
  433. {
  434. module->init_func(module);
  435. }
  436. return module;
  437. __exit:
  438. #ifdef RT_USING_POSIX_FS
  439. if (fd >= 0) close(fd);
  440. #endif
  441. if (module_ptr) rt_free(module_ptr);
  442. if (module) dlmodule_destroy(module);
  443. return RT_NULL;
  444. }
  445. struct rt_dlmodule* dlmodule_exec(const char* pgname, const char* cmd, int cmd_size)
  446. {
  447. struct rt_dlmodule *module = RT_NULL;
  448. module = dlmodule_load(pgname);
  449. if (module)
  450. {
  451. if (module->entry_addr)
  452. {
  453. /* exec this module */
  454. rt_thread_t tid;
  455. module->cmd_line = rt_strdup(cmd);
  456. /* check stack size and priority */
  457. if (module->priority > RT_THREAD_PRIORITY_MAX) module->priority = RT_THREAD_PRIORITY_MAX - 1;
  458. if (module->stack_size < 2048 || module->stack_size > (1024 * 32)) module->stack_size = 2048;
  459. tid = rt_thread_create(module->parent.name, _dlmodule_thread_entry, (void*)module,
  460. module->stack_size, module->priority, 10);
  461. if (tid)
  462. {
  463. tid->module_id = module;
  464. module->main_thread = tid;
  465. rt_thread_startup(tid);
  466. }
  467. else
  468. {
  469. /* destory dl module */
  470. dlmodule_destroy(module);
  471. module = RT_NULL;
  472. }
  473. }
  474. }
  475. return module;
  476. }
  477. #if defined(RT_USING_CUSTOM_DLMODULE)
  478. struct rt_dlmodule* dlmodule_load_custom(const char* filename, struct rt_dlmodule_ops* ops)
  479. {
  480. #ifdef RT_USING_POSIX_FS
  481. int fd = -1, length = 0;
  482. #endif
  483. rt_err_t ret = RT_EOK;
  484. rt_uint8_t *module_ptr = RT_NULL;
  485. struct rt_dlmodule *module = RT_NULL;
  486. if (ops)
  487. {
  488. RT_ASSERT(ops->load);
  489. RT_ASSERT(ops->unload);
  490. module_ptr = ops->load(filename);
  491. }
  492. #ifdef RT_USING_POSIX_FS
  493. else
  494. {
  495. fd = open(filename, O_RDONLY, 0);
  496. if (fd >= 0)
  497. {
  498. length = lseek(fd, 0, SEEK_END);
  499. lseek(fd, 0, SEEK_SET);
  500. if (length == 0) goto __exit;
  501. module_ptr = (uint8_t*) rt_malloc (length);
  502. if (!module_ptr) goto __exit;
  503. if (read(fd, module_ptr, length) != length)
  504. goto __exit;
  505. /* close file and release fd */
  506. close(fd);
  507. fd = -1;
  508. }
  509. else
  510. {
  511. goto __exit;
  512. }
  513. }
  514. #endif
  515. if (!module_ptr) goto __exit;
  516. /* check ELF header */
  517. if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) != 0 &&
  518. rt_memcmp(elf_module->e_ident, ELFMAG, SELFMAG) != 0)
  519. {
  520. rt_kprintf("Module: magic error\n");
  521. goto __exit;
  522. }
  523. /* check ELF class */
  524. if (elf_module->e_ident[EI_CLASS] != ELFCLASS32)
  525. {
  526. rt_kprintf("Module: ELF class error\n");
  527. goto __exit;
  528. }
  529. module = dlmodule_create();
  530. if (!module) goto __exit;
  531. /* set the name of module */
  532. _dlmodule_set_name(module, filename);
  533. LOG_D("rt_module_load: %.*s", RT_NAME_MAX, module->parent.name);
  534. if (elf_module->e_type == ET_REL)
  535. {
  536. ret = dlmodule_load_relocated_object(module, module_ptr);
  537. }
  538. else if (elf_module->e_type == ET_DYN)
  539. {
  540. ret = dlmodule_load_shared_object(module, module_ptr);
  541. }
  542. else
  543. {
  544. rt_kprintf("Module: unsupported elf type\n");
  545. goto __exit;
  546. }
  547. /* check return value */
  548. if (ret != RT_EOK) goto __exit;
  549. /* release module data */
  550. if (ops)
  551. {
  552. ops->unload(module_ptr);
  553. }
  554. else
  555. {
  556. rt_free(module_ptr);
  557. }
  558. /* increase module reference count */
  559. module->nref ++;
  560. /* deal with cache */
  561. #ifdef RT_USING_CACHE
  562. rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, module->mem_space, module->mem_size);
  563. rt_hw_cpu_icache_ops(RT_HW_CACHE_INVALIDATE, module->mem_space, module->mem_size);
  564. #endif
  565. /* set module initialization and cleanup function */
  566. module->init_func = dlsym(module, "module_init");
  567. module->cleanup_func = dlsym(module, "module_cleanup");
  568. module->stat = RT_DLMODULE_STAT_INIT;
  569. /* do module initialization */
  570. if (module->init_func)
  571. {
  572. module->init_func(module);
  573. }
  574. return module;
  575. __exit:
  576. #ifdef RT_USING_POSIX_FS
  577. if (fd >= 0) close(fd);
  578. #endif
  579. if (module_ptr)
  580. {
  581. if (ops)
  582. {
  583. ops->unload(module_ptr);
  584. }
  585. else
  586. {
  587. rt_free(module_ptr);
  588. }
  589. }
  590. if (module) dlmodule_destroy(module);
  591. return RT_NULL;
  592. }
  593. struct rt_dlmodule* dlmodule_exec_custom(const char* pgname, const char* cmd, int cmd_size, struct rt_dlmodule_ops* ops)
  594. {
  595. struct rt_dlmodule *module = RT_NULL;
  596. module = dlmodule_load_custom(pgname, ops);
  597. if (module)
  598. {
  599. if (module->entry_addr)
  600. {
  601. /* exec this module */
  602. rt_thread_t tid;
  603. module->cmd_line = rt_strdup(cmd);
  604. /* check stack size and priority */
  605. if (module->priority > RT_THREAD_PRIORITY_MAX) module->priority = RT_THREAD_PRIORITY_MAX - 1;
  606. if (module->stack_size < 2048 || module->stack_size > (1024 * 32)) module->stack_size = 2048;
  607. tid = rt_thread_create(module->parent.name, _dlmodule_thread_entry, (void*)module,
  608. module->stack_size, module->priority, 10);
  609. if (tid)
  610. {
  611. tid->module_id = module;
  612. module->main_thread = tid;
  613. rt_thread_startup(tid);
  614. }
  615. else
  616. {
  617. /* destory dl module */
  618. dlmodule_destroy(module);
  619. module = RT_NULL;
  620. }
  621. }
  622. }
  623. return module;
  624. }
  625. #endif
  626. void dlmodule_exit(int ret_code)
  627. {
  628. rt_thread_t thread;
  629. struct rt_dlmodule *module;
  630. module = dlmodule_self();
  631. if (!module) return;
  632. /* disable scheduling */
  633. rt_enter_critical();
  634. /* module is not running */
  635. if (module->stat != RT_DLMODULE_STAT_RUNNING)
  636. {
  637. /* restore scheduling */
  638. rt_exit_critical();
  639. return;
  640. }
  641. /* set return code */
  642. module->ret_code = ret_code;
  643. /* do exit for this module */
  644. _dlmodule_exit();
  645. /* the stat of module was changed to CLOSING in _dlmodule_exit */
  646. thread = module->main_thread;
  647. if ((thread->stat & RT_THREAD_STAT_MASK) == RT_THREAD_CLOSE)
  648. {
  649. /* main thread already closed */
  650. rt_exit_critical();
  651. return ;
  652. }
  653. /* delete thread: insert to defunct thread list */
  654. rt_thread_delete(thread);
  655. /* enable scheduling */
  656. rt_exit_critical();
  657. }
  658. rt_uint32_t dlmodule_symbol_find(const char *sym_str)
  659. {
  660. /* find in kernel symbol table */
  661. struct rt_module_symtab *index;
  662. for (index = _rt_module_symtab_begin; index != _rt_module_symtab_end; index ++)
  663. {
  664. if (rt_strcmp(index->name, sym_str) == 0)
  665. return (rt_uint32_t)index->addr;
  666. }
  667. return 0;
  668. }
  669. int rt_system_dlmodule_init(void)
  670. {
  671. #if defined(__GNUC__) && !defined(__CC_ARM)
  672. extern int __rtmsymtab_start;
  673. extern int __rtmsymtab_end;
  674. _rt_module_symtab_begin = (struct rt_module_symtab *)&__rtmsymtab_start;
  675. _rt_module_symtab_end = (struct rt_module_symtab *)&__rtmsymtab_end;
  676. #elif defined (__CC_ARM)
  677. extern int RTMSymTab$$Base;
  678. extern int RTMSymTab$$Limit;
  679. _rt_module_symtab_begin = (struct rt_module_symtab *)&RTMSymTab$$Base;
  680. _rt_module_symtab_end = (struct rt_module_symtab *)&RTMSymTab$$Limit;
  681. #elif defined (__IAR_SYSTEMS_ICC__)
  682. _rt_module_symtab_begin = __section_begin("RTMSymTab");
  683. _rt_module_symtab_end = __section_end("RTMSymTab");
  684. #endif
  685. return 0;
  686. }
  687. INIT_COMPONENT_EXPORT(rt_system_dlmodule_init);
  688. /**
  689. * This function will find the specified module.
  690. *
  691. * @param name the name of module finding
  692. *
  693. * @return the module
  694. */
  695. struct rt_dlmodule *dlmodule_find(const char *name)
  696. {
  697. rt_object_t object;
  698. struct rt_dlmodule *ret = RT_NULL;
  699. object = rt_object_find(name, RT_Object_Class_Module);
  700. if (object)
  701. {
  702. ret = (struct rt_dlmodule*) object;
  703. }
  704. return ret;
  705. }
  706. RTM_EXPORT(dlmodule_find);
  707. int list_symbols(void)
  708. {
  709. extern int __rtmsymtab_start;
  710. extern int __rtmsymtab_end;
  711. /* find in kernel symbol table */
  712. struct rt_module_symtab *index;
  713. for (index = _rt_module_symtab_begin;
  714. index != _rt_module_symtab_end;
  715. index ++)
  716. {
  717. rt_kprintf("%s => 0x%08x\n", index->name, index->addr);
  718. }
  719. return 0;
  720. }
  721. MSH_CMD_EXPORT(list_symbols, list symbols information);
  722. int list_module(void)
  723. {
  724. struct rt_dlmodule *module;
  725. struct rt_list_node *list, *node;
  726. struct rt_object_information *info;
  727. info = rt_object_get_information(RT_Object_Class_Module);
  728. list = &info->object_list;
  729. rt_kprintf("module ref address \n");
  730. rt_kprintf("-------- -------- ------------\n");
  731. for (node = list->next; node != list; node = node->next)
  732. {
  733. module = (struct rt_dlmodule *)(rt_list_entry(node, struct rt_object, list));
  734. rt_kprintf("%-*.*s %-04d 0x%08x\n",
  735. RT_NAME_MAX, RT_NAME_MAX, module->parent.name, module->nref, module->mem_space);
  736. }
  737. return 0;
  738. }
  739. MSH_CMD_EXPORT(list_module, list modules in system);