lwp_elf.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  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. *aux++ = id; \
  44. *aux++ = val; \
  45. } while (0)
  46. typedef struct
  47. {
  48. int fd;
  49. char *filename;
  50. rt_size_t file_len;
  51. Elf_Ehdr ehdr;
  52. Elf_Phdr *phdr;
  53. rt_ubase_t map_size;
  54. } elf_info_t;
  55. typedef struct
  56. {
  57. struct rt_lwp *lwp;
  58. struct process_aux *aux;
  59. elf_info_t exec_info;
  60. elf_info_t interp_info;
  61. rt_ubase_t load_addr;
  62. rt_ubase_t e_entry;
  63. rt_ubase_t interp_base;
  64. } elf_load_info_t;
  65. static void elf_user_dump(struct rt_lwp *lwp, void *va, size_t len)
  66. {
  67. #ifdef ELF_DEBUG_DUMP
  68. uint8_t *k_va;
  69. int ret;
  70. if (len < 16)
  71. len = 16;
  72. rt_kprintf("\r\n");
  73. rt_kprintf("%s : user va : %p, len : 0x%x(%d)\n", __func__, va, len, len);
  74. k_va = rt_malloc(len);
  75. if (k_va == RT_NULL)
  76. {
  77. rt_kprintf("%s : malloc failed\n", __func__);
  78. return;
  79. }
  80. rt_memset(k_va, 0, len);
  81. ret = lwp_data_get(lwp, k_va, va, len);
  82. if (ret != len)
  83. {
  84. rt_kprintf("%s : lwp_get_from_user failed, ret = %d\n", __func__, ret);
  85. return;
  86. }
  87. rt_kprintf("%s : k_va : %p\n", __func__, k_va);
  88. for (size_t i = 0; i < len; i += 16)
  89. {
  90. 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],
  91. k_va[i+4], k_va[i+5], k_va[i+6], k_va[i+7]);
  92. 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],
  93. k_va[i+12], k_va[i+13], k_va[i+14], k_va[i+15]);
  94. }
  95. rt_kprintf("\r\n");
  96. rt_free(k_va);
  97. #endif
  98. }
  99. rt_ubase_t elf_random_offset(void)
  100. {
  101. #ifdef ELF_LOAD_RANDOMIZE
  102. return (rt_tick_get() % 65535) * ARCH_PAGE_SIZE;
  103. #else
  104. return ELF_PAGEALIGN(0);
  105. #endif
  106. }
  107. static void *file_mmap(struct rt_lwp *lwp, int fd, rt_ubase_t load_addr,
  108. rt_ubase_t map_size, size_t prot, size_t flags, rt_ubase_t offset)
  109. {
  110. uint8_t *map_va;
  111. map_va = (uint8_t *)lwp_mmap2(lwp, (void *)load_addr, map_size, prot, flags, fd, offset >> ARCH_PAGE_SHIFT);
  112. if (!map_va || (map_va != (uint8_t *)load_addr))
  113. {
  114. LOG_E("%s : lwp map user failed!", __func__);
  115. return RT_NULL;
  116. }
  117. LOG_D(" %s : map va = %p load_addr : %p size : 0x%x", __func__, map_va, load_addr, map_size);
  118. return map_va;
  119. }
  120. static int elf_file_open(const char *filename)
  121. {
  122. int fd = -1;
  123. fd = open(filename, O_BINARY | O_RDONLY, 0);
  124. if (fd < 0)
  125. {
  126. LOG_E("%s : elf file [%s] open failed!", __func__, filename);
  127. }
  128. return fd;
  129. }
  130. static int elf_file_close(int fd)
  131. {
  132. return close(fd);
  133. }
  134. static int elf_file_length(char *filename, rt_size_t *file_len)
  135. {
  136. int ret;
  137. struct stat s = { 0 };
  138. ret = stat(filename, &s);
  139. if (ret != 0)
  140. {
  141. LOG_E("%s : error", __func__);
  142. return -RT_ERROR;
  143. }
  144. *file_len = (rt_size_t)s.st_size;
  145. return RT_EOK;
  146. }
  147. static int elf_file_read(rt_int32_t fd, rt_uint8_t *buffer, size_t size, off_t offset)
  148. {
  149. ssize_t read_len;
  150. off_t pos;
  151. if (size > 0)
  152. {
  153. pos = lseek(fd, offset, SEEK_SET);
  154. if (pos != offset)
  155. {
  156. LOG_E("%s : seek file offset: 0x%x failed", __func__, offset);
  157. return -RT_ERROR;
  158. }
  159. read_len = read(fd, buffer, size);
  160. if (read_len != size)
  161. {
  162. LOG_E("%s : read from offset: 0x%x error", __func__, offset);
  163. return -RT_ERROR;
  164. }
  165. }
  166. return RT_EOK;
  167. }
  168. static rt_int32_t elf_check_ehdr(const Elf_Ehdr *ehdr, rt_uint32_t file_len)
  169. {
  170. if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0)
  171. {
  172. LOG_E("%s : e_ident error", __func__);
  173. return -RT_ERROR;
  174. }
  175. if ((ehdr->e_type != ET_EXEC) && (ehdr->e_type != ET_DYN))
  176. {
  177. LOG_E("%s : e_type error", __func__);
  178. return -RT_ERROR;
  179. }
  180. if (ehdr->e_machine == EM_NONE)
  181. {
  182. LOG_E("%s : e_machine is EM_NONE", __func__);
  183. return -RT_ERROR;
  184. }
  185. if (ehdr->e_phnum > ELF_PHDR_NUM_MAX)
  186. {
  187. LOG_E("%s : e_phnum error", __func__);
  188. return -RT_ERROR;
  189. }
  190. if (ehdr->e_phoff > file_len)
  191. {
  192. LOG_E("%s : e_phoff error", __func__);
  193. return -RT_ERROR;
  194. }
  195. LOG_D("%s : e_entry : 0x%x", __func__, ehdr->e_entry);
  196. return RT_EOK;
  197. }
  198. static int elf_check_phdr(const Elf_Phdr *phdr)
  199. {
  200. if (phdr->p_filesz > FILE_LENGTH_MAX)
  201. {
  202. LOG_E("%s : phdr p_filesz 0x%x error", __func__, phdr->p_filesz);
  203. return -RT_ERROR;
  204. }
  205. if (phdr->p_offset > FILE_LENGTH_MAX)
  206. {
  207. LOG_E("%s : phdr p_offset 0x%x error", __func__, phdr->p_offset);
  208. return -RT_ERROR;
  209. }
  210. if (phdr->p_memsz > MEM_SIZE_MAX)
  211. {
  212. LOG_E("%s[%d], phdr p_memsz 0x%x error", __func__, phdr->p_memsz);
  213. return -RT_ERROR;
  214. }
  215. LOG_D("%s : phdr p_vaddr : 0x%x", __func__, phdr->p_vaddr);
  216. return RT_EOK;
  217. }
  218. static int elf_load_ehdr(elf_info_t *elf_info)
  219. {
  220. int ret;
  221. ret = elf_file_open(elf_info->filename);
  222. if (ret < 0)
  223. {
  224. LOG_E("%s : elf_file_open %s failed", __func__, elf_info->filename);
  225. return ret;
  226. }
  227. elf_info->fd = ret;
  228. ret = elf_file_length(elf_info->filename, &elf_info->file_len);
  229. if (ret != RT_EOK)
  230. {
  231. return -RT_ERROR;
  232. }
  233. ret = elf_file_read(elf_info->fd, (rt_uint8_t *)&elf_info->ehdr, sizeof(Elf_Ehdr), 0);
  234. if (ret != RT_EOK)
  235. {
  236. LOG_E("%s : elf_file_read failed, ret : %d", __func__, ret);
  237. return -RT_ERROR;
  238. }
  239. ret = elf_check_ehdr(&elf_info->ehdr, elf_info->file_len);
  240. if (ret != RT_EOK)
  241. {
  242. LOG_E("%s : elf_check_ehdr failed, ret : %d", __func__, ret);
  243. return -RT_ERROR;
  244. }
  245. return RT_EOK;
  246. }
  247. static int elf_load_phdr(elf_info_t *elf_info)
  248. {
  249. Elf_Ehdr *ehdr = &elf_info->ehdr;
  250. uint32_t size;
  251. int ret;
  252. if (ehdr->e_phnum < 1)
  253. {
  254. return -RT_ERROR;
  255. }
  256. if (ehdr->e_phentsize != sizeof(Elf_Phdr))
  257. {
  258. return -RT_ERROR;
  259. }
  260. size = sizeof(Elf_Phdr) * ehdr->e_phnum;
  261. if ((ehdr->e_phoff + size) > elf_info->file_len)
  262. {
  263. return -RT_ERROR;
  264. }
  265. elf_info->phdr = rt_malloc(size);
  266. if (elf_info->phdr == RT_NULL)
  267. {
  268. LOG_E("%s : alloc phdr failed", __func__);
  269. return -RT_ENOMEM;
  270. }
  271. ret = elf_file_read(elf_info->fd, (rt_uint8_t *)elf_info->phdr, size, ehdr->e_phoff);
  272. if (ret != RT_EOK)
  273. {
  274. rt_free(elf_info->phdr);
  275. elf_info->phdr = RT_NULL;
  276. LOG_E("%s : elf_file_read failed, ret = %d", __func__, ret);
  277. return -RT_ERROR;
  278. }
  279. return RT_EOK;
  280. }
  281. static int elf_load_interp(elf_load_info_t *load_info)
  282. {
  283. Elf_Phdr *phdr = load_info->exec_info.phdr;
  284. int ret;
  285. int i;
  286. for (i = 0; i < load_info->exec_info.ehdr.e_phnum; ++i, ++phdr)
  287. {
  288. if (phdr->p_type != PT_INTERP)
  289. {
  290. continue;
  291. }
  292. if (elf_check_phdr(phdr) != RT_EOK)
  293. {
  294. return -RT_ERROR;
  295. }
  296. if ((phdr->p_filesz > ELF_PATH_MAX) || (phdr->p_filesz < FLF_PATH_MIN))
  297. {
  298. LOG_E("%s : phdr p_filesz error", __func__, phdr->p_filesz);
  299. return -RT_ERROR;
  300. }
  301. if (phdr->p_offset + phdr->p_filesz > load_info->exec_info.file_len)
  302. {
  303. LOG_E("%s : phdr p_offset error", __func__, phdr->p_offset);
  304. return -RT_ERROR;
  305. }
  306. load_info->interp_info.filename = rt_malloc(phdr->p_filesz);
  307. if (load_info->interp_info.filename == RT_NULL)
  308. {
  309. LOG_E("%s : alloc elf interpreter failed", __func__);
  310. return -RT_ENOMEM;
  311. }
  312. ret = elf_file_read(load_info->exec_info.fd, (rt_uint8_t *)load_info->interp_info.filename,
  313. phdr->p_filesz, phdr->p_offset);
  314. if (ret != RT_EOK)
  315. {
  316. LOG_E("%s : elf_file_read failed, ret = %d", __func__, ret);
  317. ret = -RT_ERROR;
  318. goto error_exit;
  319. }
  320. if (load_info->interp_info.filename[phdr->p_filesz - 1] != '\0')
  321. {
  322. LOG_E("%s : elf interpreter is invalid", __func__);
  323. ret = -RT_ERROR;
  324. goto error_exit;
  325. }
  326. LOG_D("%s : elf interpreter : %s", __func__, load_info->interp_info.filename);
  327. ret = elf_load_ehdr(&load_info->interp_info);
  328. if (ret != RT_EOK)
  329. {
  330. LOG_E("%s : elf_load_ehdr failed, ret = %d", __func__, ret);
  331. goto error_exit;
  332. }
  333. ret = elf_load_phdr(&load_info->interp_info);
  334. if (ret != RT_EOK)
  335. {
  336. LOG_E("%s : elf_load_phdr failed, ret = %d", __func__, ret);
  337. goto error_exit;
  338. }
  339. break;
  340. }
  341. return RT_EOK;
  342. error_exit:
  343. return ret;
  344. }
  345. static int total_mapping_size(elf_info_t *elf_info)
  346. {
  347. int i;
  348. int first_idx = -1;
  349. int last_idx = -1;
  350. for (i = 0; i < elf_info->ehdr.e_phnum; i++)
  351. {
  352. if (elf_info->phdr[i].p_type == PT_LOAD)
  353. {
  354. last_idx = i;
  355. if (first_idx == -1)
  356. first_idx = i;
  357. }
  358. }
  359. if (first_idx == -1)
  360. return -1;
  361. elf_info->map_size = elf_info->phdr[last_idx].p_vaddr + elf_info->phdr[last_idx].p_memsz -
  362. ELF_PAGESTART(elf_info->phdr[first_idx].p_vaddr);
  363. return 0;
  364. }
  365. 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)
  366. {
  367. rt_ubase_t map_va = 0;
  368. rt_ubase_t va_offset;
  369. addr = ELF_PAGESTART(addr);
  370. va_offset = elf_phdr->p_offset - ELF_PAGEOFFSET(elf_phdr->p_vaddr);
  371. rt_ubase_t size;
  372. if (map_size != 0)
  373. {
  374. size = map_size;
  375. }
  376. else
  377. {
  378. size = elf_phdr->p_memsz + ELF_PAGEOFFSET(elf_phdr->p_vaddr);
  379. if (size == 0)
  380. {
  381. return addr;
  382. }
  383. }
  384. map_va = (rt_ubase_t)file_mmap(lwp, fd, addr, size, prot, flags, va_offset);
  385. return map_va;
  386. }
  387. static int elf_zero_bss(struct rt_lwp *lwp, int fd, const Elf_Phdr *phdr, rt_ubase_t bss_start,
  388. rt_ubase_t bss_end)
  389. {
  390. lwp_data_set(lwp, (void *)bss_start, 0, bss_end - bss_start);
  391. return RT_EOK;
  392. }
  393. static int elf_file_mmap(elf_load_info_t *load_info, elf_info_t *elf_info, rt_ubase_t *elfload_addr,
  394. rt_uint32_t map_size, rt_ubase_t *load_base)
  395. {
  396. int ret, i;
  397. rt_ubase_t map_va, bss_start, bss_end;
  398. Elf_Ehdr *ehdr = &elf_info->ehdr;
  399. Elf_Phdr *phdr = elf_info->phdr;
  400. const Elf_Phdr *tmp_phdr = phdr;
  401. int fd = elf_info->fd;
  402. rt_ubase_t load_addr;
  403. size_t prot = PROT_READ | PROT_WRITE;
  404. size_t flags = MAP_FIXED | MAP_PRIVATE;
  405. for (i = 0; i < ehdr->e_phnum; ++i, ++tmp_phdr)
  406. {
  407. if (tmp_phdr->p_type != PT_LOAD)
  408. {
  409. continue;
  410. }
  411. if (ehdr->e_type == ET_EXEC)
  412. {
  413. if (elf_check_phdr(tmp_phdr) != RT_EOK)
  414. {
  415. LOG_E("%s : elf_check_phdr failed", __func__);
  416. return -RT_ERROR;
  417. }
  418. }
  419. load_addr = tmp_phdr->p_vaddr + *load_base;
  420. LOG_D("%s : p_vaddr : 0x%x, load_addr : 0x%x", __func__, tmp_phdr->p_vaddr, load_addr);
  421. if ((tmp_phdr->p_vaddr == 0) && (*load_base == 0))
  422. {
  423. flags &= ~MAP_FIXED;
  424. }
  425. map_va = elf_map(load_info->lwp, tmp_phdr, fd, load_addr, prot, flags, map_size);
  426. if (!map_va)
  427. {
  428. LOG_E("%s : elf_map failed", __func__);
  429. return -ENOMEM;
  430. }
  431. map_size = 0;
  432. elf_user_dump(load_info->lwp, (void *)load_addr, 64);
  433. if ((tmp_phdr->p_memsz > tmp_phdr->p_filesz) && (tmp_phdr->p_flags & PF_W))
  434. {
  435. bss_start = load_addr + tmp_phdr->p_filesz;
  436. bss_end = load_addr + tmp_phdr->p_memsz;
  437. ret = elf_zero_bss(load_info->lwp, fd, tmp_phdr, bss_start, bss_end);
  438. if (ret)
  439. {
  440. LOG_E("%s : elf_zero_bss error", __func__);
  441. return ret;
  442. }
  443. }
  444. if (*elfload_addr == 0)
  445. {
  446. *elfload_addr = map_va + ELF_PAGEOFFSET(tmp_phdr->p_vaddr);
  447. LOG_D("%s elf_load_addr : %p, vAddr : %p, load_base : %p, map_va : %p", __func__,
  448. *elfload_addr, tmp_phdr->p_vaddr, *load_base, map_va);
  449. }
  450. if ((*load_base == 0) && (ehdr->e_type == ET_DYN))
  451. {
  452. *load_base = map_va;
  453. }
  454. }
  455. return RT_EOK;
  456. }
  457. static int load_elf_interp(elf_load_info_t *load_info, rt_ubase_t *interp_base)
  458. {
  459. int ret;
  460. rt_ubase_t load_base = ELF_INTERP_LOAD_ADDR + elf_random_offset();
  461. ret = total_mapping_size(&load_info->interp_info);
  462. if (ret)
  463. {
  464. LOG_E("%s : total_mapping_size failed", __func__);
  465. return -RT_ERROR;
  466. }
  467. LOG_D("%s : total_mapping_size 0x%x", __func__, load_info->interp_info.map_size);
  468. return elf_file_mmap(load_info, &load_info->interp_info, interp_base,
  469. load_info->interp_info.map_size, &load_base);
  470. }
  471. static int elf_aux_fill(elf_load_info_t *load_info)
  472. {
  473. uint8_t *random;
  474. struct process_aux *aux = load_info->aux;
  475. elf_addr_t *aux_info;
  476. uint32_t random_value = rt_tick_get();
  477. size_t prot = PROT_READ | PROT_WRITE;
  478. size_t flags = MAP_PRIVATE;
  479. void *va;
  480. if (!aux)
  481. {
  482. LOG_E("%s : aux is null", __func__);
  483. return -1;
  484. }
  485. aux_info = (elf_addr_t *)aux->item;
  486. ELF_AUX_ENT(aux_info, AT_PAGESZ, ARCH_PAGE_SIZE);
  487. va = lwp_mmap2(load_info->lwp, (void *)(USER_VADDR_TOP - ARCH_PAGE_SIZE * 2), ARCH_PAGE_SIZE, prot, flags, -1, 0);
  488. if (!va)
  489. {
  490. LOG_E("lwp map user failed!");
  491. return -RT_ERROR;
  492. }
  493. random = (uint8_t *)(USER_VADDR_TOP - ARCH_PAGE_SIZE - sizeof(char[16]));
  494. lwp_data_put(load_info->lwp, random, &random_value, sizeof(random_value));
  495. ELF_AUX_ENT(aux_info, AT_RANDOM, (size_t)random);
  496. ELF_AUX_ENT(aux_info, AT_PHDR, (size_t)load_info->load_addr + load_info->exec_info.ehdr.e_phoff);
  497. ELF_AUX_ENT(aux_info, AT_PHNUM, (size_t)load_info->exec_info.ehdr.e_phnum);
  498. ELF_AUX_ENT(aux_info, AT_PHENT, sizeof(Elf_Phdr));
  499. ELF_AUX_ENT(aux_info, AT_BASE, load_info->interp_base);
  500. ELF_AUX_ENT(aux_info, AT_FLAGS, 0);
  501. ELF_AUX_ENT(aux_info, AT_ENTRY, load_info->exec_info.ehdr.e_entry);
  502. ELF_AUX_ENT(aux_info, AT_UID, 0);
  503. ELF_AUX_ENT(aux_info, AT_EUID, 0);
  504. ELF_AUX_ENT(aux_info, AT_GID, 0);
  505. ELF_AUX_ENT(aux_info, AT_EGID, 0);
  506. ELF_AUX_ENT(aux_info, AT_HWCAP, 0);
  507. ELF_AUX_ENT(aux_info, AT_CLKTCK, 0);
  508. ELF_AUX_ENT(aux_info, AT_SECURE, 0);
  509. #ifdef ARCH_MM_MMU
  510. rt_hw_cpu_dcache_ops(RT_HW_CACHE_FLUSH, aux, sizeof(*aux));
  511. #endif
  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)
  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;
  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