1
0

dlelf.c 15 KB

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