lwp_elf.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-08-23 zhangsz first version
  9. */
  10. #include <rtthread.h>
  11. #ifdef RT_USING_LDSO
  12. #include <dfs_file.h>
  13. #include <unistd.h>
  14. #include <stdio.h>
  15. #include <fcntl.h>
  16. #include <lwp_elf.h>
  17. #include "lwp.h"
  18. #include "lwp_arch.h"
  19. #ifdef ARCH_MM_MMU
  20. #include <lwp_user_mm.h>
  21. #endif
  22. #ifdef RT_USING_VDSO
  23. #include <vdso.h>
  24. #endif
  25. #define DBG_TAG "load.elf"
  26. #ifdef ELF_DEBUG_ENABLE
  27. #define DBG_LVL DBG_LOG
  28. #else
  29. #define DBG_LVL DBG_INFO
  30. #endif
  31. #include <rtdbg.h>
  32. #define ELF_INVALID_FD -1
  33. #define ELF_PHDR_NUM_MAX 128
  34. #define FILE_LENGTH_MAX 0xC0000000
  35. #define MEM_SIZE_MAX 0xC0000000
  36. #define ELF_PATH_MAX 256
  37. #define FLF_PATH_MIN 1
  38. #define ELF_PAGESTART(_v) ((_v) & ~(rt_ubase_t)(ARCH_PAGE_SIZE - 1))
  39. #define ELF_PAGEOFFSET(_v) ((_v) & (ARCH_PAGE_SIZE - 1))
  40. #define ELF_PAGEALIGN(_v) (((_v) + ARCH_PAGE_SIZE - 1) & ~(ARCH_PAGE_SIZE - 1))
  41. #define ELF_EXEC_LOAD_ADDR USER_VADDR_START
  42. #define ELF_INTERP_LOAD_ADDR LDSO_LOAD_VADDR
  43. #define ELF_AUX_ENT(aux, id, val) \
  44. do \
  45. { \
  46. rt_base_t a = id; \
  47. lwp_data_put(lwp, aux++, &a, sizeof(rt_ubase_t)); \
  48. a = val; \
  49. lwp_data_put(lwp, aux++, &a, sizeof(rt_ubase_t)); \
  50. } while (0)
  51. typedef struct
  52. {
  53. int fd;
  54. char *filename;
  55. rt_size_t file_len;
  56. Elf_Ehdr ehdr;
  57. Elf_Phdr *phdr;
  58. rt_ubase_t map_size;
  59. } elf_info_t;
  60. typedef struct
  61. {
  62. struct rt_lwp *lwp;
  63. struct process_aux *aux;
  64. elf_info_t exec_info;
  65. elf_info_t interp_info;
  66. rt_ubase_t load_addr;
  67. rt_ubase_t e_entry;
  68. rt_ubase_t interp_base;
  69. } elf_load_info_t;
  70. static void elf_user_dump(struct rt_lwp *lwp, void *va, size_t len)
  71. {
  72. #ifdef ELF_DEBUG_DUMP
  73. uint8_t *k_va;
  74. int ret;
  75. if (len < 16)
  76. len = 16;
  77. rt_kprintf("\r\n");
  78. rt_kprintf("%s : user va : %p, len : 0x%x(%d)\n", __func__, va, len, len);
  79. k_va = rt_malloc(len);
  80. if (k_va == RT_NULL)
  81. {
  82. rt_kprintf("%s : malloc failed\n", __func__);
  83. return;
  84. }
  85. rt_memset(k_va, 0, len);
  86. ret = lwp_data_get(lwp, k_va, va, len);
  87. if (ret != len)
  88. {
  89. rt_kprintf("%s : lwp_get_from_user failed, ret = %d\n", __func__, ret);
  90. return;
  91. }
  92. rt_kprintf("%s : k_va : %p\n", __func__, k_va);
  93. for (size_t i = 0; i < len; i += 16)
  94. {
  95. rt_kprintf(" %02x %02x %02x %02x %02x %02x %02x %02x ", k_va[i], k_va[i+1], k_va[i+2], k_va[i+3],
  96. k_va[i+4], k_va[i+5], k_va[i+6], k_va[i+7]);
  97. rt_kprintf(" %02x %02x %02x %02x %02x %02x %02x %02x \n", k_va[i+8], k_va[i+9], k_va[i+10], k_va[i+11],
  98. k_va[i+12], k_va[i+13], k_va[i+14], k_va[i+15]);
  99. }
  100. rt_kprintf("\r\n");
  101. rt_free(k_va);
  102. #endif
  103. }
  104. rt_ubase_t elf_random_offset(void)
  105. {
  106. #ifdef ELF_LOAD_RANDOMIZE
  107. return (rt_tick_get() % 65535) * ARCH_PAGE_SIZE;
  108. #else
  109. return ELF_PAGEALIGN(0);
  110. #endif
  111. }
  112. static void *file_mmap(struct rt_lwp *lwp, int fd, rt_ubase_t load_addr,
  113. rt_ubase_t map_size, size_t prot, size_t flags, rt_ubase_t offset)
  114. {
  115. uint8_t *map_va;
  116. map_va = (uint8_t *)lwp_mmap2(lwp, (void *)load_addr, map_size, prot, flags, fd, offset >> ARCH_PAGE_SHIFT);
  117. if (!map_va || (map_va != (uint8_t *)load_addr))
  118. {
  119. LOG_E("%s : lwp map user failed!", __func__);
  120. return RT_NULL;
  121. }
  122. LOG_D(" %s : map va = %p load_addr : %p size : 0x%x", __func__, map_va, load_addr, map_size);
  123. return map_va;
  124. }
  125. static int elf_file_open(const char *filename)
  126. {
  127. int fd = -1;
  128. fd = open(filename, O_BINARY | O_RDONLY, 0);
  129. if (fd < 0)
  130. {
  131. LOG_E("%s : elf file [%s] open failed!", __func__, filename);
  132. }
  133. return fd;
  134. }
  135. static int elf_file_close(int fd)
  136. {
  137. return close(fd);
  138. }
  139. static int elf_file_length(char *filename, rt_size_t *file_len)
  140. {
  141. int ret;
  142. struct stat s = { 0 };
  143. ret = stat(filename, &s);
  144. if (ret != 0)
  145. {
  146. LOG_E("%s : error", __func__);
  147. return -RT_ERROR;
  148. }
  149. *file_len = (rt_size_t)s.st_size;
  150. return RT_EOK;
  151. }
  152. static int elf_file_read(rt_int32_t fd, rt_uint8_t *buffer, size_t size, off_t offset)
  153. {
  154. ssize_t read_len;
  155. off_t pos;
  156. if (size > 0)
  157. {
  158. pos = lseek(fd, offset, SEEK_SET);
  159. if (pos != offset)
  160. {
  161. LOG_E("%s : seek file offset: 0x%x failed", __func__, offset);
  162. return -RT_ERROR;
  163. }
  164. read_len = read(fd, buffer, size);
  165. if (read_len != size)
  166. {
  167. LOG_E("%s : read from offset: 0x%x error", __func__, offset);
  168. return -RT_ERROR;
  169. }
  170. }
  171. return RT_EOK;
  172. }
  173. static rt_int32_t elf_check_ehdr(const Elf_Ehdr *ehdr, rt_uint32_t file_len)
  174. {
  175. if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0)
  176. {
  177. LOG_E("%s : e_ident error", __func__);
  178. return -RT_ERROR;
  179. }
  180. if ((ehdr->e_type != ET_EXEC) && (ehdr->e_type != ET_DYN))
  181. {
  182. LOG_E("%s : e_type error", __func__);
  183. return -RT_ERROR;
  184. }
  185. if (ehdr->e_machine == EM_NONE)
  186. {
  187. LOG_E("%s : e_machine is EM_NONE", __func__);
  188. return -RT_ERROR;
  189. }
  190. if (ehdr->e_phnum > ELF_PHDR_NUM_MAX)
  191. {
  192. LOG_E("%s : e_phnum error", __func__);
  193. return -RT_ERROR;
  194. }
  195. if (ehdr->e_phoff > file_len)
  196. {
  197. LOG_E("%s : e_phoff error", __func__);
  198. return -RT_ERROR;
  199. }
  200. LOG_D("%s : e_entry : 0x%x", __func__, ehdr->e_entry);
  201. return RT_EOK;
  202. }
  203. static int elf_check_phdr(const Elf_Phdr *phdr)
  204. {
  205. if (phdr->p_filesz > FILE_LENGTH_MAX)
  206. {
  207. LOG_E("%s : phdr p_filesz 0x%x error", __func__, phdr->p_filesz);
  208. return -RT_ERROR;
  209. }
  210. if (phdr->p_offset > FILE_LENGTH_MAX)
  211. {
  212. LOG_E("%s : phdr p_offset 0x%x error", __func__, phdr->p_offset);
  213. return -RT_ERROR;
  214. }
  215. if (phdr->p_memsz > MEM_SIZE_MAX)
  216. {
  217. LOG_E("%s[%d], phdr p_memsz 0x%x error", __func__, phdr->p_memsz);
  218. return -RT_ERROR;
  219. }
  220. LOG_D("%s : phdr p_vaddr : 0x%x", __func__, phdr->p_vaddr);
  221. return RT_EOK;
  222. }
  223. static int elf_load_ehdr(elf_info_t *elf_info)
  224. {
  225. int ret;
  226. ret = elf_file_open(elf_info->filename);
  227. if (ret < 0)
  228. {
  229. LOG_E("%s : elf_file_open %s failed", __func__, elf_info->filename);
  230. return ret;
  231. }
  232. elf_info->fd = ret;
  233. ret = elf_file_length(elf_info->filename, &elf_info->file_len);
  234. if (ret != RT_EOK)
  235. {
  236. return -RT_ERROR;
  237. }
  238. ret = elf_file_read(elf_info->fd, (rt_uint8_t *)&elf_info->ehdr, sizeof(Elf_Ehdr), 0);
  239. if (ret != RT_EOK)
  240. {
  241. LOG_E("%s : elf_file_read failed, ret : %d", __func__, ret);
  242. return -RT_ERROR;
  243. }
  244. ret = elf_check_ehdr(&elf_info->ehdr, elf_info->file_len);
  245. if (ret != RT_EOK)
  246. {
  247. LOG_E("%s : elf_check_ehdr failed, ret : %d", __func__, ret);
  248. return -RT_ERROR;
  249. }
  250. return RT_EOK;
  251. }
  252. static int elf_load_phdr(elf_info_t *elf_info)
  253. {
  254. Elf_Ehdr *ehdr = &elf_info->ehdr;
  255. uint32_t size;
  256. int ret;
  257. if (ehdr->e_phnum < 1)
  258. {
  259. return -RT_ERROR;
  260. }
  261. if (ehdr->e_phentsize != sizeof(Elf_Phdr))
  262. {
  263. return -RT_ERROR;
  264. }
  265. size = sizeof(Elf_Phdr) * ehdr->e_phnum;
  266. if ((ehdr->e_phoff + size) > elf_info->file_len)
  267. {
  268. return -RT_ERROR;
  269. }
  270. elf_info->phdr = rt_malloc(size);
  271. if (elf_info->phdr == RT_NULL)
  272. {
  273. LOG_E("%s : alloc phdr failed", __func__);
  274. return -RT_ENOMEM;
  275. }
  276. ret = elf_file_read(elf_info->fd, (rt_uint8_t *)elf_info->phdr, size, ehdr->e_phoff);
  277. if (ret != RT_EOK)
  278. {
  279. rt_free(elf_info->phdr);
  280. elf_info->phdr = RT_NULL;
  281. LOG_E("%s : elf_file_read failed, ret = %d", __func__, ret);
  282. return -RT_ERROR;
  283. }
  284. return RT_EOK;
  285. }
  286. static int elf_load_interp(elf_load_info_t *load_info)
  287. {
  288. Elf_Phdr *phdr = load_info->exec_info.phdr;
  289. int ret;
  290. int i;
  291. for (i = 0; i < load_info->exec_info.ehdr.e_phnum; ++i, ++phdr)
  292. {
  293. if (phdr->p_type != PT_INTERP)
  294. {
  295. continue;
  296. }
  297. if (elf_check_phdr(phdr) != RT_EOK)
  298. {
  299. return -RT_ERROR;
  300. }
  301. if ((phdr->p_filesz > ELF_PATH_MAX) || (phdr->p_filesz < FLF_PATH_MIN))
  302. {
  303. LOG_E("%s : phdr p_filesz error", __func__, phdr->p_filesz);
  304. return -RT_ERROR;
  305. }
  306. if (phdr->p_offset + phdr->p_filesz > load_info->exec_info.file_len)
  307. {
  308. LOG_E("%s : phdr p_offset error", __func__, phdr->p_offset);
  309. return -RT_ERROR;
  310. }
  311. load_info->interp_info.filename = rt_malloc(phdr->p_filesz);
  312. if (load_info->interp_info.filename == RT_NULL)
  313. {
  314. LOG_E("%s : alloc elf interpreter failed", __func__);
  315. return -RT_ENOMEM;
  316. }
  317. ret = elf_file_read(load_info->exec_info.fd, (rt_uint8_t *)load_info->interp_info.filename,
  318. phdr->p_filesz, phdr->p_offset);
  319. if (ret != RT_EOK)
  320. {
  321. LOG_E("%s : elf_file_read failed, ret = %d", __func__, ret);
  322. ret = -RT_ERROR;
  323. goto error_exit;
  324. }
  325. if (load_info->interp_info.filename[phdr->p_filesz - 1] != '\0')
  326. {
  327. LOG_E("%s : elf interpreter is invalid", __func__);
  328. ret = -RT_ERROR;
  329. goto error_exit;
  330. }
  331. LOG_D("%s : elf interpreter : %s", __func__, load_info->interp_info.filename);
  332. ret = elf_load_ehdr(&load_info->interp_info);
  333. if (ret != RT_EOK)
  334. {
  335. LOG_E("%s : elf_load_ehdr failed, ret = %d", __func__, ret);
  336. goto error_exit;
  337. }
  338. ret = elf_load_phdr(&load_info->interp_info);
  339. if (ret != RT_EOK)
  340. {
  341. LOG_E("%s : elf_load_phdr failed, ret = %d", __func__, ret);
  342. goto error_exit;
  343. }
  344. break;
  345. }
  346. return RT_EOK;
  347. error_exit:
  348. return ret;
  349. }
  350. static int total_mapping_size(elf_info_t *elf_info)
  351. {
  352. int i;
  353. int first_idx = -1;
  354. int last_idx = -1;
  355. for (i = 0; i < elf_info->ehdr.e_phnum; i++)
  356. {
  357. if (elf_info->phdr[i].p_type == PT_LOAD)
  358. {
  359. last_idx = i;
  360. if (first_idx == -1)
  361. first_idx = i;
  362. }
  363. }
  364. if (first_idx == -1)
  365. return -1;
  366. elf_info->map_size = elf_info->phdr[last_idx].p_vaddr + elf_info->phdr[last_idx].p_memsz -
  367. ELF_PAGESTART(elf_info->phdr[first_idx].p_vaddr);
  368. return 0;
  369. }
  370. static rt_ubase_t elf_map(struct rt_lwp *lwp, const Elf_Phdr *elf_phdr, int fd, rt_ubase_t addr, size_t prot, size_t flags, rt_ubase_t map_size)
  371. {
  372. rt_ubase_t map_va = 0;
  373. rt_ubase_t va_offset;
  374. addr = ELF_PAGESTART(addr);
  375. va_offset = elf_phdr->p_offset - ELF_PAGEOFFSET(elf_phdr->p_vaddr);
  376. rt_ubase_t size;
  377. if (map_size != 0)
  378. {
  379. size = map_size;
  380. }
  381. else
  382. {
  383. size = elf_phdr->p_memsz + ELF_PAGEOFFSET(elf_phdr->p_vaddr);
  384. if (size == 0)
  385. {
  386. return addr;
  387. }
  388. }
  389. map_va = (rt_ubase_t)file_mmap(lwp, fd, addr, size, prot, flags, va_offset);
  390. return map_va;
  391. }
  392. static int elf_zero_bss(struct rt_lwp *lwp, int fd, const Elf_Phdr *phdr, rt_ubase_t bss_start,
  393. rt_ubase_t bss_end)
  394. {
  395. lwp_data_set(lwp, (void *)bss_start, 0, bss_end - bss_start);
  396. return RT_EOK;
  397. }
  398. static int elf_file_mmap(elf_load_info_t *load_info, elf_info_t *elf_info, rt_ubase_t *elfload_addr,
  399. rt_uint32_t map_size, rt_ubase_t *load_base)
  400. {
  401. int ret, i;
  402. rt_ubase_t map_va, bss_start, bss_end;
  403. Elf_Ehdr *ehdr = &elf_info->ehdr;
  404. Elf_Phdr *phdr = elf_info->phdr;
  405. const Elf_Phdr *tmp_phdr = phdr;
  406. int fd = elf_info->fd;
  407. rt_ubase_t load_addr;
  408. size_t prot = PROT_READ | PROT_WRITE;
  409. size_t flags = MAP_FIXED | MAP_PRIVATE;
  410. for (i = 0; i < ehdr->e_phnum; ++i, ++tmp_phdr)
  411. {
  412. if (tmp_phdr->p_type != PT_LOAD)
  413. {
  414. continue;
  415. }
  416. if (ehdr->e_type == ET_EXEC)
  417. {
  418. if (elf_check_phdr(tmp_phdr) != RT_EOK)
  419. {
  420. LOG_E("%s : elf_check_phdr failed", __func__);
  421. return -RT_ERROR;
  422. }
  423. }
  424. load_addr = tmp_phdr->p_vaddr + *load_base;
  425. LOG_D("%s : p_vaddr : 0x%x, load_addr : 0x%x", __func__, tmp_phdr->p_vaddr, load_addr);
  426. if ((tmp_phdr->p_vaddr == 0) && (*load_base == 0))
  427. {
  428. flags &= ~MAP_FIXED;
  429. }
  430. map_va = elf_map(load_info->lwp, tmp_phdr, fd, load_addr, prot, flags, map_size);
  431. if (!map_va)
  432. {
  433. LOG_E("%s : elf_map failed", __func__);
  434. return -ENOMEM;
  435. }
  436. map_size = 0;
  437. elf_user_dump(load_info->lwp, (void *)load_addr, 64);
  438. if ((tmp_phdr->p_memsz > tmp_phdr->p_filesz) && (tmp_phdr->p_flags & PF_W))
  439. {
  440. bss_start = load_addr + tmp_phdr->p_filesz;
  441. bss_end = load_addr + tmp_phdr->p_memsz;
  442. ret = elf_zero_bss(load_info->lwp, fd, tmp_phdr, bss_start, bss_end);
  443. if (ret)
  444. {
  445. LOG_E("%s : elf_zero_bss error", __func__);
  446. return ret;
  447. }
  448. }
  449. if (*elfload_addr == 0)
  450. {
  451. *elfload_addr = map_va + ELF_PAGEOFFSET(tmp_phdr->p_vaddr);
  452. LOG_D("%s elf_load_addr : %p, vAddr : %p, load_base : %p, map_va : %p", __func__,
  453. *elfload_addr, tmp_phdr->p_vaddr, *load_base, map_va);
  454. }
  455. if ((*load_base == 0) && (ehdr->e_type == ET_DYN))
  456. {
  457. *load_base = map_va;
  458. }
  459. }
  460. return RT_EOK;
  461. }
  462. static int load_elf_interp(elf_load_info_t *load_info, rt_ubase_t *interp_base)
  463. {
  464. int ret;
  465. rt_ubase_t load_base = ELF_INTERP_LOAD_ADDR + elf_random_offset();
  466. ret = total_mapping_size(&load_info->interp_info);
  467. if (ret)
  468. {
  469. LOG_E("%s : total_mapping_size failed", __func__);
  470. return -RT_ERROR;
  471. }
  472. LOG_D("%s : total_mapping_size 0x%x", __func__, load_info->interp_info.map_size);
  473. return elf_file_mmap(load_info, &load_info->interp_info, interp_base,
  474. load_info->interp_info.map_size, &load_base);
  475. }
  476. static int elf_aux_fill(elf_load_info_t *load_info)
  477. {
  478. uint8_t *random;
  479. struct process_aux *aux = load_info->aux;
  480. elf_addr_t *aux_info;
  481. uint32_t random_value = rt_tick_get();
  482. size_t prot = PROT_READ | PROT_WRITE;
  483. size_t flags = MAP_PRIVATE;
  484. rt_lwp_t lwp = load_info->lwp;
  485. void *va;
  486. if (!aux)
  487. {
  488. LOG_E("%s : aux is null", __func__);
  489. return -1;
  490. }
  491. aux_info = (elf_addr_t *)aux->item;
  492. ELF_AUX_ENT(aux_info, AT_PAGESZ, ARCH_PAGE_SIZE);
  493. va = lwp_mmap2(lwp, (void *)(USER_VADDR_TOP - ARCH_PAGE_SIZE * 2), ARCH_PAGE_SIZE, prot, flags, -1, 0);
  494. if (!va)
  495. {
  496. LOG_E("lwp map user failed!");
  497. return -RT_ERROR;
  498. }
  499. random = (uint8_t *)(USER_VADDR_TOP - ARCH_PAGE_SIZE - sizeof(char[16]));
  500. lwp_data_put(load_info->lwp, random, &random_value, sizeof(random_value));
  501. ELF_AUX_ENT(aux_info, AT_RANDOM, (size_t)random);
  502. ELF_AUX_ENT(aux_info, AT_PHDR, (size_t)load_info->load_addr + load_info->exec_info.ehdr.e_phoff);
  503. ELF_AUX_ENT(aux_info, AT_PHNUM, (size_t)load_info->exec_info.ehdr.e_phnum);
  504. ELF_AUX_ENT(aux_info, AT_PHENT, sizeof(Elf_Phdr));
  505. ELF_AUX_ENT(aux_info, AT_BASE, load_info->interp_base);
  506. ELF_AUX_ENT(aux_info, AT_FLAGS, 0);
  507. ELF_AUX_ENT(aux_info, AT_ENTRY, load_info->exec_info.ehdr.e_entry);
  508. ELF_AUX_ENT(aux_info, AT_UID, 0);
  509. ELF_AUX_ENT(aux_info, AT_EUID, 0);
  510. ELF_AUX_ENT(aux_info, AT_GID, 0);
  511. ELF_AUX_ENT(aux_info, AT_EGID, 0);
  512. ELF_AUX_ENT(aux_info, AT_HWCAP, 0);
  513. ELF_AUX_ENT(aux_info, AT_CLKTCK, 0);
  514. ELF_AUX_ENT(aux_info, AT_SECURE, 0);
  515. #ifdef RT_USING_VDSO
  516. if(RT_EOK == arch_setup_additional_pages(load_info->lwp))
  517. {
  518. ELF_AUX_ENT(aux_info, AT_SYSINFO_EHDR, (size_t)load_info->lwp->vdso_vbase);
  519. }
  520. else
  521. {
  522. LOG_W("vdso map error,VDSO currently only supports aarch64 architecture!");
  523. }
  524. #endif
  525. return 0;
  526. }
  527. static int elf_load_segment(elf_load_info_t *load_info)
  528. {
  529. int ret;
  530. rt_ubase_t app_load_base = 0;
  531. load_info->load_addr = 0;
  532. load_info->interp_base = 0;
  533. load_info->exec_info.map_size = 0;
  534. if (load_info->exec_info.ehdr.e_type == ET_DYN)
  535. {
  536. ret = total_mapping_size(&load_info->exec_info);
  537. if (ret)
  538. {
  539. LOG_E("%s : total_mapping_size failed", __func__);
  540. return -RT_ERROR;
  541. }
  542. LOG_D("%s : map_size : 0x%x", __func__, load_info->exec_info.map_size);
  543. app_load_base = ELF_EXEC_LOAD_ADDR + elf_random_offset();
  544. }
  545. ret = elf_file_mmap(load_info, &load_info->exec_info, &load_info->load_addr,
  546. load_info->exec_info.map_size, &app_load_base);
  547. elf_file_close(load_info->exec_info.fd);
  548. if (ret != RT_EOK)
  549. {
  550. LOG_W("%s : elf_file_close exec failed", __func__);
  551. }
  552. load_info->exec_info.fd = ELF_INVALID_FD;
  553. if (load_info->interp_info.fd != ELF_INVALID_FD)
  554. {
  555. ret = load_elf_interp(load_info, &load_info->interp_base);
  556. if (ret)
  557. {
  558. LOG_E("%s : load_elf_interp failed, ret = %d", __func__, ret);
  559. return ret;
  560. }
  561. elf_file_close(load_info->interp_info.fd);
  562. if (ret != RT_EOK)
  563. {
  564. LOG_W("%s : elf_file_close interp failed, ret = %d", __func__, ret);
  565. }
  566. load_info->interp_info.fd = ELF_INVALID_FD;
  567. load_info->e_entry = load_info->interp_info.ehdr.e_entry + load_info->interp_base;
  568. load_info->exec_info.ehdr.e_entry = load_info->exec_info.ehdr.e_entry + app_load_base;
  569. }
  570. else
  571. {
  572. load_info->e_entry = load_info->exec_info.ehdr.e_entry;
  573. }
  574. load_info->lwp->text_entry = (void *)load_info->e_entry;
  575. LOG_D("%s : lwp->text_entry : %p loadaddr : %p", __func__, load_info->lwp->text_entry, app_load_base);
  576. elf_user_dump(load_info->lwp, load_info->lwp->text_entry, 64);
  577. ret = elf_aux_fill(load_info);
  578. if (ret)
  579. {
  580. LOG_E("%s : elf_aux_fill failed", __func__);
  581. return ret;
  582. }
  583. return RT_EOK;
  584. }
  585. static void elf_load_deinit(elf_load_info_t *load_info)
  586. {
  587. if (load_info->exec_info.fd != ELF_INVALID_FD)
  588. {
  589. elf_file_close(load_info->exec_info.fd);
  590. }
  591. if (load_info->interp_info.fd != ELF_INVALID_FD)
  592. {
  593. elf_file_close(load_info->interp_info.fd);
  594. }
  595. if (load_info->exec_info.phdr != RT_NULL)
  596. {
  597. rt_free(load_info->exec_info.phdr);
  598. }
  599. if (load_info->exec_info.filename != RT_NULL)
  600. {
  601. rt_free(load_info->exec_info.filename);
  602. }
  603. if (load_info->interp_info.phdr != RT_NULL)
  604. {
  605. rt_free(load_info->interp_info.phdr);
  606. }
  607. if (load_info->interp_info.filename != RT_NULL)
  608. {
  609. rt_free(load_info->interp_info.filename);
  610. }
  611. }
  612. static int elf_load_app(elf_info_t *exec_info)
  613. {
  614. int ret;
  615. ret = elf_load_ehdr(exec_info);
  616. if (ret != RT_EOK)
  617. {
  618. return ret;
  619. }
  620. ret = elf_load_phdr(exec_info);
  621. if (ret != RT_EOK)
  622. {
  623. return ret;
  624. }
  625. return ret;
  626. }
  627. static int elf_file_load(elf_load_info_t *load_info)
  628. {
  629. int ret;
  630. ret = elf_load_app(&load_info->exec_info);
  631. if (ret != RT_EOK)
  632. {
  633. goto OUT;
  634. }
  635. ret = elf_load_interp(load_info);
  636. if (ret != RT_EOK)
  637. {
  638. goto OUT;
  639. }
  640. ret = elf_load_segment(load_info);
  641. if (ret != RT_EOK)
  642. {
  643. goto OUT;
  644. }
  645. OUT:
  646. elf_load_deinit(load_info);
  647. return ret;
  648. }
  649. int lwp_load(const char *filename, struct rt_lwp *lwp, uint8_t *load_addr, size_t addr_size,
  650. struct process_aux *aux_ua)
  651. {
  652. elf_load_info_t load_info = { 0 };
  653. int len;
  654. int ret;
  655. if (filename == RT_NULL)
  656. {
  657. LOG_E("%s : file is NULL", __func__);
  658. return -RT_ERROR;
  659. }
  660. len = rt_strlen(filename);
  661. if (len < FLF_PATH_MIN || len > ELF_PATH_MAX)
  662. {
  663. LOG_E("%s : file length (%d) invalid", __func__, len);
  664. return -RT_ERROR;
  665. }
  666. load_info.exec_info.filename = rt_malloc(len + 1);
  667. if (!load_info.exec_info.filename)
  668. {
  669. LOG_E("%s : alloc filename failed", __func__, len);
  670. return -RT_ERROR;
  671. }
  672. else
  673. {
  674. rt_memset(load_info.exec_info.filename, 0, len + 1);
  675. rt_strncpy(load_info.exec_info.filename, filename, len);
  676. }
  677. load_info.lwp = lwp;
  678. load_info.aux = aux_ua;
  679. load_info.exec_info.fd = ELF_INVALID_FD;
  680. load_info.interp_info.fd = ELF_INVALID_FD;
  681. load_info.load_addr = (rt_ubase_t)load_addr;
  682. /* copy file name to process name */
  683. rt_strncpy(lwp->cmd, filename, RT_NAME_MAX);
  684. lwp->exe_file = dfs_normalize_path(NULL, filename); // malloc
  685. ret = elf_file_load(&load_info);
  686. if (ret != RT_EOK)
  687. {
  688. LOG_E("%s : elf_file_load error, ret : %d", __func__, ret);
  689. return ret;
  690. }
  691. return RT_EOK;
  692. }
  693. #endif