dlelf.c 15 KB

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