dlelf.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493
  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. * 2021/04/23 chunyexixiaoyu distinguish 32-bit and 64-bit
  10. */
  11. #include "dlmodule.h"
  12. #include "dlelf.h"
  13. #define DBG_TAG "DLMD"
  14. #define DBG_LVL DBG_INFO
  15. #include <rtdbg.h> // must after of DEBUG_ENABLE or some other options
  16. rt_err_t dlmodule_load_shared_object(struct rt_dlmodule* module, void *module_ptr)
  17. {
  18. rt_bool_t linked = RT_FALSE;
  19. rt_ubase_t index, module_size = 0;
  20. Elf_Addr vstart_addr, vend_addr;
  21. rt_bool_t has_vstart;
  22. RT_ASSERT(module_ptr != RT_NULL);
  23. if (rt_memcmp(elf_module->e_ident, RTMMAG, SELFMAG) == 0)
  24. {
  25. /* rtmlinker finished */
  26. linked = RT_TRUE;
  27. }
  28. /* get the ELF image size */
  29. has_vstart = RT_FALSE;
  30. vstart_addr = vend_addr = RT_NULL;
  31. for (index = 0; index < elf_module->e_phnum; index++)
  32. {
  33. if (phdr[index].p_type != PT_LOAD)
  34. continue;
  35. LOG_D("LOAD segment: %d, 0x%p, 0x%08x", index, phdr[index].p_vaddr, phdr[index].p_memsz);
  36. if (phdr[index].p_memsz < phdr[index].p_filesz)
  37. {
  38. rt_kprintf("invalid elf: segment %d: p_memsz: %d, p_filesz: %d\n",
  39. index, phdr[index].p_memsz, phdr[index].p_filesz);
  40. return RT_NULL;
  41. }
  42. if (!has_vstart)
  43. {
  44. vstart_addr = phdr[index].p_vaddr;
  45. vend_addr = phdr[index].p_vaddr + phdr[index].p_memsz;
  46. has_vstart = RT_TRUE;
  47. if (vend_addr < vstart_addr)
  48. {
  49. LOG_E("invalid elf: segment %d: p_vaddr: %d, p_memsz: %d\n",
  50. index, phdr[index].p_vaddr, phdr[index].p_memsz);
  51. return RT_NULL;
  52. }
  53. }
  54. else
  55. {
  56. if (phdr[index].p_vaddr < vend_addr)
  57. {
  58. LOG_E("invalid elf: segment should be sorted and not overlapped\n");
  59. return RT_NULL;
  60. }
  61. if (phdr[index].p_vaddr > vend_addr + 16)
  62. {
  63. /* There should not be too much padding in the object files. */
  64. LOG_W("warning: too much padding before segment %d", index);
  65. }
  66. vend_addr = phdr[index].p_vaddr + phdr[index].p_memsz;
  67. if (vend_addr < phdr[index].p_vaddr)
  68. {
  69. LOG_E("invalid elf: "
  70. "segment %d address overflow\n", index);
  71. return RT_NULL;
  72. }
  73. }
  74. }
  75. module_size = vend_addr - vstart_addr;
  76. LOG_D("module size: %d, vstart_addr: 0x%p", module_size, vstart_addr);
  77. if (module_size == 0)
  78. {
  79. LOG_E("Module: size error\n");
  80. return -RT_ERROR;
  81. }
  82. module->vstart_addr = vstart_addr;
  83. module->nref = 0;
  84. /* allocate module space */
  85. module->mem_space = rt_malloc(module_size);
  86. if (module->mem_space == RT_NULL)
  87. {
  88. LOG_E("Module: allocate space failed.\n");
  89. return -RT_ERROR;
  90. }
  91. module->mem_size = module_size;
  92. /* zero all space */
  93. rt_memset(module->mem_space, 0, module_size);
  94. for (index = 0; index < elf_module->e_phnum; index++)
  95. {
  96. if (phdr[index].p_type == PT_LOAD)
  97. {
  98. rt_memcpy(module->mem_space + phdr[index].p_vaddr - vstart_addr,
  99. (rt_uint8_t *)elf_module + phdr[index].p_offset,
  100. phdr[index].p_filesz);
  101. }
  102. }
  103. /* set module entry */
  104. module->entry_addr = module->mem_space + elf_module->e_entry - vstart_addr;
  105. /* handle relocation section */
  106. for (index = 0; index < elf_module->e_shnum; index ++)
  107. {
  108. rt_ubase_t i, nr_reloc;
  109. Elf_Sym *symtab;
  110. Elf_Rel *rel;
  111. rt_uint8_t *strtab;
  112. static rt_bool_t unsolved = RT_FALSE;
  113. #if (defined(__arm__) || defined(__i386__) || (__riscv_xlen == 32))
  114. if (!IS_REL(shdr[index]))
  115. continue;
  116. #elif (defined(__aarch64__) || defined(__x86_64__) || (__riscv_xlen == 64))
  117. if (!IS_RELA(shdr[index]))
  118. continue;
  119. #endif
  120. /* get relocate item */
  121. rel = (Elf_Rel *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset);
  122. /* locate .rel.plt and .rel.dyn section */
  123. symtab = (Elf_Sym *)((rt_uint8_t *)module_ptr +
  124. shdr[shdr[index].sh_link].sh_offset);
  125. strtab = (rt_uint8_t *)module_ptr +
  126. shdr[shdr[shdr[index].sh_link].sh_link].sh_offset;
  127. nr_reloc = (rt_ubase_t)(shdr[index].sh_size / sizeof(Elf_Rel));
  128. /* relocate every items */
  129. for (i = 0; i < nr_reloc; i ++)
  130. {
  131. #if (defined(__arm__) || defined(__i386__) || (__riscv_xlen == 32))
  132. Elf_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)];
  133. #elif (defined(__aarch64__) || defined(__x86_64__) || (__riscv_xlen == 64))
  134. Elf_Sym *sym = &symtab[ELF64_R_SYM(rel->r_info)];
  135. #endif
  136. LOG_D("relocate symbol %s shndx %d", strtab + sym->st_name, sym->st_shndx);
  137. if ((sym->st_shndx != SHT_NULL) ||(ELF_ST_BIND(sym->st_info) == STB_LOCAL))
  138. {
  139. Elf_Addr addr;
  140. addr = (Elf_Addr)(module->mem_space + sym->st_value - vstart_addr);
  141. dlmodule_relocate(module, rel, addr);
  142. }
  143. else if (!linked)
  144. {
  145. Elf_Addr addr;
  146. LOG_D("relocate symbol: %s", strtab + sym->st_name);
  147. /* need to resolve symbol in kernel symbol table */
  148. addr = dlmodule_symbol_find((const char *)(strtab + sym->st_name));
  149. if (addr == 0)
  150. {
  151. LOG_E("Module: can't find %s in kernel symbol table", strtab + sym->st_name);
  152. unsolved = RT_TRUE;
  153. }
  154. else
  155. {
  156. dlmodule_relocate(module, rel, addr);
  157. }
  158. }
  159. rel ++;
  160. }
  161. if (unsolved)
  162. return -RT_ERROR;
  163. }
  164. /* construct module symbol table */
  165. for (index = 0; index < elf_module->e_shnum; index ++)
  166. {
  167. /* find .dynsym section */
  168. rt_uint8_t *shstrab;
  169. shstrab = (rt_uint8_t *)module_ptr +
  170. shdr[elf_module->e_shstrndx].sh_offset;
  171. if (rt_strcmp((const char *)(shstrab + shdr[index].sh_name), ELF_DYNSYM) == 0)
  172. break;
  173. }
  174. /* found .dynsym section */
  175. if (index != elf_module->e_shnum)
  176. {
  177. int i, count = 0;
  178. Elf_Sym *symtab = RT_NULL;
  179. rt_uint8_t *strtab = RT_NULL;
  180. symtab = (Elf_Sym *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset);
  181. strtab = (rt_uint8_t *)module_ptr + shdr[shdr[index].sh_link].sh_offset;
  182. for (i = 0; i < shdr[index].sh_size / sizeof(Elf_Sym); i++)
  183. {
  184. if ((ELF_ST_BIND(symtab[i].st_info) == STB_GLOBAL) &&
  185. (ELF_ST_TYPE(symtab[i].st_info) == STT_FUNC))
  186. count ++;
  187. }
  188. module->symtab = (struct rt_module_symtab *)rt_malloc
  189. (count * sizeof(struct rt_module_symtab));
  190. module->nsym = count;
  191. for (i = 0, count = 0; i < shdr[index].sh_size / sizeof(Elf_Sym); i++)
  192. {
  193. rt_size_t length;
  194. if ((ELF_ST_BIND(symtab[i].st_info) != STB_GLOBAL) ||
  195. (ELF_ST_TYPE(symtab[i].st_info) != STT_FUNC))
  196. continue;
  197. length = rt_strlen((const char *)(strtab + symtab[i].st_name)) + 1;
  198. module->symtab[count].addr =
  199. (void *)(module->mem_space + symtab[i].st_value - module->vstart_addr);
  200. module->symtab[count].name = rt_malloc(length);
  201. rt_memset((void *)module->symtab[count].name, 0, length);
  202. rt_memcpy((void *)module->symtab[count].name,
  203. strtab + symtab[i].st_name,
  204. length);
  205. count ++;
  206. }
  207. /* get priority & stack size params*/
  208. rt_uint32_t flag = 0;
  209. rt_uint16_t priority;
  210. rt_uint32_t stacksize;
  211. for (i = 0; i < shdr[index].sh_size / sizeof(Elf_Sym); i++)
  212. {
  213. if (((flag & 0x01) == 0) &&
  214. (rt_strcmp((const char *)(strtab + symtab[i].st_name), "dlmodule_thread_priority") == 0))
  215. {
  216. flag |= 0x01;
  217. priority = *(rt_uint16_t*)(module->mem_space + symtab[i].st_value - module->vstart_addr);
  218. if (priority < RT_THREAD_PRIORITY_MAX)
  219. {
  220. module->priority = priority;
  221. }
  222. }
  223. if (((flag & 0x02) == 0) &&
  224. (rt_strcmp((const char *)(strtab + symtab[i].st_name), "dlmodule_thread_stacksize") == 0))
  225. {
  226. flag |= 0x02;
  227. stacksize = *(rt_uint32_t*)(module->mem_space + symtab[i].st_value - module->vstart_addr);
  228. if ((stacksize < 2048) || (stacksize > 1024 * 32))
  229. {
  230. module->stack_size = stacksize;
  231. }
  232. }
  233. if ((flag & 0x03) == 0x03)
  234. {
  235. break;
  236. }
  237. }
  238. }
  239. return RT_EOK;
  240. }
  241. rt_err_t dlmodule_load_relocated_object(struct rt_dlmodule* module, void *module_ptr)
  242. {
  243. rt_ubase_t index, rodata_addr = 0, bss_addr = 0, data_addr = 0;
  244. rt_ubase_t module_addr = 0, module_size = 0;
  245. rt_uint8_t *ptr, *strtab, *shstrab;
  246. /* get the ELF image size */
  247. for (index = 0; index < elf_module->e_shnum; index ++)
  248. {
  249. /* text */
  250. if (IS_PROG(shdr[index]) && IS_AX(shdr[index]))
  251. {
  252. module_size += shdr[index].sh_size;
  253. module_addr = shdr[index].sh_addr;
  254. }
  255. /* rodata */
  256. if (IS_PROG(shdr[index]) && IS_ALLOC(shdr[index]))
  257. {
  258. module_size += shdr[index].sh_size;
  259. }
  260. /* data */
  261. if (IS_PROG(shdr[index]) && IS_AW(shdr[index]))
  262. {
  263. module_size += shdr[index].sh_size;
  264. }
  265. /* bss */
  266. if (IS_NOPROG(shdr[index]) && IS_AW(shdr[index]))
  267. {
  268. module_size += shdr[index].sh_size;
  269. }
  270. }
  271. /* no text, data and bss on image */
  272. if (module_size == 0) return RT_NULL;
  273. module->vstart_addr = 0;
  274. /* allocate module space */
  275. module->mem_space = rt_malloc(module_size);
  276. if (module->mem_space == RT_NULL)
  277. {
  278. LOG_E("Module: allocate space failed.\n");
  279. return -RT_ERROR;
  280. }
  281. module->mem_size = module_size;
  282. /* zero all space */
  283. ptr = module->mem_space;
  284. rt_memset(ptr, 0, module_size);
  285. /* load text and data section */
  286. for (index = 0; index < elf_module->e_shnum; index ++)
  287. {
  288. /* load text section */
  289. if (IS_PROG(shdr[index]) && IS_AX(shdr[index]))
  290. {
  291. rt_memcpy(ptr,
  292. (rt_uint8_t *)elf_module + shdr[index].sh_offset,
  293. shdr[index].sh_size);
  294. LOG_D("load text 0x%x, size %d", ptr, shdr[index].sh_size);
  295. ptr += shdr[index].sh_size;
  296. }
  297. /* load rodata section */
  298. if (IS_PROG(shdr[index]) && IS_ALLOC(shdr[index]))
  299. {
  300. rt_memcpy(ptr,
  301. (rt_uint8_t *)elf_module + shdr[index].sh_offset,
  302. shdr[index].sh_size);
  303. rodata_addr = (rt_uint32_t)ptr;
  304. LOG_D("load rodata 0x%x, size %d, rodata 0x%x", ptr,
  305. shdr[index].sh_size, *(rt_uint32_t *)data_addr);
  306. ptr += shdr[index].sh_size;
  307. }
  308. /* load data section */
  309. if (IS_PROG(shdr[index]) && IS_AW(shdr[index]))
  310. {
  311. rt_memcpy(ptr,
  312. (rt_uint8_t *)elf_module + shdr[index].sh_offset,
  313. shdr[index].sh_size);
  314. data_addr = (rt_uint32_t)ptr;
  315. LOG_D("load data 0x%x, size %d, data 0x%x", ptr,
  316. shdr[index].sh_size, *(rt_uint32_t *)data_addr);
  317. ptr += shdr[index].sh_size;
  318. }
  319. /* load bss section */
  320. if (IS_NOPROG(shdr[index]) && IS_AW(shdr[index]))
  321. {
  322. rt_memset(ptr, 0, shdr[index].sh_size);
  323. bss_addr = (rt_uint32_t)ptr;
  324. LOG_D("load bss 0x%x, size %d", ptr, shdr[index].sh_size);
  325. }
  326. }
  327. /* set module entry */
  328. module->entry_addr = (rt_dlmodule_entry_func_t)((rt_uint8_t *)module->mem_space + elf_module->e_entry - module_addr);
  329. /* handle relocation section */
  330. for (index = 0; index < elf_module->e_shnum; index ++)
  331. {
  332. rt_ubase_t i, nr_reloc;
  333. Elf_Sym *symtab;
  334. Elf_Rel *rel;
  335. #if (defined(__arm__) || defined(__i386__) || (__riscv_xlen == 32))
  336. if (!IS_REL(shdr[index]))
  337. continue;
  338. #elif (defined(__aarch64__) || defined(__x86_64__) || (__riscv_xlen == 64))
  339. if (!IS_RELA(shdr[index]))
  340. continue;
  341. #endif
  342. /* get relocate item */
  343. rel = (Elf_Rel *)((rt_uint8_t *)module_ptr + shdr[index].sh_offset);
  344. /* locate .dynsym and .dynstr */
  345. symtab = (Elf_Sym *)((rt_uint8_t *)module_ptr +
  346. shdr[shdr[index].sh_link].sh_offset);
  347. strtab = (rt_uint8_t *)module_ptr +
  348. shdr[shdr[shdr[index].sh_link].sh_link].sh_offset;
  349. shstrab = (rt_uint8_t *)module_ptr +
  350. shdr[elf_module->e_shstrndx].sh_offset;
  351. nr_reloc = (rt_uint32_t)(shdr[index].sh_size / sizeof(Elf_Rel));
  352. /* relocate every items */
  353. for (i = 0; i < nr_reloc; i ++)
  354. {
  355. #if (defined(__arm__) || defined(__i386__) || (__riscv_xlen == 32))
  356. Elf_Sym *sym = &symtab[ELF32_R_SYM(rel->r_info)];
  357. #elif (defined(__aarch64__) || defined(__x86_64__) || (__riscv_xlen == 64))
  358. Elf_Sym *sym = &symtab[ELF64_R_SYM(rel->r_info)];
  359. #endif
  360. LOG_D("relocate symbol: %s", strtab + sym->st_name);
  361. if (sym->st_shndx != STN_UNDEF)
  362. {
  363. Elf_Addr addr = 0;
  364. if ((ELF_ST_TYPE(sym->st_info) == STT_SECTION) ||
  365. (ELF_ST_TYPE(sym->st_info) == STT_OBJECT))
  366. {
  367. if (rt_strncmp((const char *)(shstrab +
  368. shdr[sym->st_shndx].sh_name), ELF_RODATA, 8) == 0)
  369. {
  370. /* relocate rodata section */
  371. LOG_D("rodata");
  372. addr = (Elf_Addr)(rodata_addr + sym->st_value);
  373. }
  374. else if (rt_strncmp((const char *)
  375. (shstrab + shdr[sym->st_shndx].sh_name), ELF_BSS, 5) == 0)
  376. {
  377. /* relocate bss section */
  378. LOG_D("bss");
  379. addr = (Elf_Addr)bss_addr + sym->st_value;
  380. }
  381. else if (rt_strncmp((const char *)(shstrab + shdr[sym->st_shndx].sh_name),
  382. ELF_DATA, 6) == 0)
  383. {
  384. /* relocate data section */
  385. LOG_D("data");
  386. addr = (Elf_Addr)data_addr + sym->st_value;
  387. }
  388. if (addr != 0) dlmodule_relocate(module, rel, addr);
  389. }
  390. else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
  391. {
  392. addr = (Elf_Addr)((rt_uint8_t *) module->mem_space - module_addr + sym->st_value);
  393. /* relocate function */
  394. dlmodule_relocate(module, rel, addr);
  395. }
  396. }
  397. else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC)
  398. {
  399. /* relocate function */
  400. dlmodule_relocate(module, rel,
  401. (Elf_Addr)((rt_uint8_t *)
  402. module->mem_space
  403. - module_addr
  404. + sym->st_value));
  405. }
  406. else
  407. {
  408. Elf_Addr addr;
  409. if (ELF32_R_TYPE(rel->r_info) != R_ARM_V4BX)
  410. {
  411. LOG_D("relocate symbol: %s", strtab + sym->st_name);
  412. /* need to resolve symbol in kernel symbol table */
  413. addr = dlmodule_symbol_find((const char *)(strtab + sym->st_name));
  414. if (addr != (Elf_Addr)RT_NULL)
  415. {
  416. dlmodule_relocate(module, rel, addr);
  417. LOG_D("symbol addr 0x%x", addr);
  418. }
  419. else
  420. LOG_E("Module: can't find %s in kernel symbol table",
  421. strtab + sym->st_name);
  422. }
  423. else
  424. {
  425. addr = (Elf_Addr)((rt_uint8_t *) module->mem_space - module_addr + sym->st_value);
  426. dlmodule_relocate(module, rel, addr);
  427. }
  428. }
  429. rel ++;
  430. }
  431. }
  432. return RT_EOK;
  433. }