lwp_elf.c 20 KB

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