elf_file.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835
  1. #include <elf.h>
  2. #include "elf_file.h"
  3. #include "elf_file_i.h"
  4. #include "elf_api_interface.h"
  5. #define TAG "elf"
  6. #define ELF_NAME_BUFFER_LEN 32
  7. #define SECTION_OFFSET(e, n) (e->section_table + n * sizeof(Elf32_Shdr))
  8. #define IS_FLAGS_SET(v, m) ((v & m) == m)
  9. #define RESOLVER_THREAD_YIELD_STEP 30
  10. // #define ELF_DEBUG_LOG 1
  11. #ifndef ELF_DEBUG_LOG
  12. #undef FURI_LOG_D
  13. #define FURI_LOG_D(...)
  14. #endif
  15. #define TRAMPOLINE_CODE_SIZE 6
  16. /**
  17. ldr r12, [pc, #2]
  18. bx r12
  19. */
  20. const uint8_t trampoline_code_little_endian[TRAMPOLINE_CODE_SIZE] =
  21. {0xdf, 0xf8, 0x02, 0xc0, 0x60, 0x47};
  22. typedef struct {
  23. uint8_t code[TRAMPOLINE_CODE_SIZE];
  24. uint32_t addr;
  25. } __attribute__((packed)) JMPTrampoline;
  26. /**************************************************************************************************/
  27. /********************************************* Caches *********************************************/
  28. /**************************************************************************************************/
  29. static bool address_cache_get(AddressCache_t cache, int symEntry, Elf32_Addr* symAddr) {
  30. Elf32_Addr* addr = AddressCache_get(cache, symEntry);
  31. if(addr) {
  32. *symAddr = *addr;
  33. return true;
  34. } else {
  35. return false;
  36. }
  37. }
  38. static void address_cache_put(AddressCache_t cache, int symEntry, Elf32_Addr symAddr) {
  39. AddressCache_set_at(cache, symEntry, symAddr);
  40. }
  41. /**************************************************************************************************/
  42. /********************************************** ELF ***********************************************/
  43. /**************************************************************************************************/
  44. static ELFSection* elf_file_get_section(ELFFile* elf, const char* name) {
  45. return ELFSectionDict_get(elf->sections, name);
  46. }
  47. static void elf_file_put_section(ELFFile* elf, const char* name, ELFSection* section) {
  48. ELFSectionDict_set_at(elf->sections, strdup(name), *section);
  49. }
  50. static bool elf_read_string_from_offset(ELFFile* elf, off_t offset, string_t name) {
  51. bool result = false;
  52. off_t old = storage_file_tell(elf->fd);
  53. do {
  54. if(!storage_file_seek(elf->fd, offset, true)) break;
  55. char buffer[ELF_NAME_BUFFER_LEN + 1];
  56. buffer[ELF_NAME_BUFFER_LEN] = 0;
  57. while(true) {
  58. uint16_t read = storage_file_read(elf->fd, buffer, ELF_NAME_BUFFER_LEN);
  59. string_cat_str(name, buffer);
  60. if(strlen(buffer) < ELF_NAME_BUFFER_LEN) {
  61. result = true;
  62. break;
  63. }
  64. if(storage_file_get_error(elf->fd) != FSE_OK || read == 0) break;
  65. }
  66. } while(false);
  67. storage_file_seek(elf->fd, old, true);
  68. return result;
  69. }
  70. static bool elf_read_section_name(ELFFile* elf, off_t offset, string_t name) {
  71. return elf_read_string_from_offset(elf, elf->section_table_strings + offset, name);
  72. }
  73. static bool elf_read_symbol_name(ELFFile* elf, off_t offset, string_t name) {
  74. return elf_read_string_from_offset(elf, elf->symbol_table_strings + offset, name);
  75. }
  76. static bool elf_read_section_header(ELFFile* elf, size_t section_idx, Elf32_Shdr* section_header) {
  77. off_t offset = SECTION_OFFSET(elf, section_idx);
  78. return storage_file_seek(elf->fd, offset, true) &&
  79. storage_file_read(elf->fd, section_header, sizeof(Elf32_Shdr)) == sizeof(Elf32_Shdr);
  80. }
  81. static bool
  82. elf_read_section(ELFFile* elf, size_t section_idx, Elf32_Shdr* section_header, string_t name) {
  83. if(!elf_read_section_header(elf, section_idx, section_header)) {
  84. return false;
  85. }
  86. if(section_header->sh_name && !elf_read_section_name(elf, section_header->sh_name, name)) {
  87. return false;
  88. }
  89. return true;
  90. }
  91. static bool elf_read_symbol(ELFFile* elf, int n, Elf32_Sym* sym, string_t name) {
  92. bool success = false;
  93. off_t old = storage_file_tell(elf->fd);
  94. off_t pos = elf->symbol_table + n * sizeof(Elf32_Sym);
  95. if(storage_file_seek(elf->fd, pos, true) &&
  96. storage_file_read(elf->fd, sym, sizeof(Elf32_Sym)) == sizeof(Elf32_Sym)) {
  97. if(sym->st_name)
  98. success = elf_read_symbol_name(elf, sym->st_name, name);
  99. else {
  100. Elf32_Shdr shdr;
  101. success = elf_read_section(elf, sym->st_shndx, &shdr, name);
  102. }
  103. }
  104. storage_file_seek(elf->fd, old, true);
  105. return success;
  106. }
  107. static ELFSection* elf_section_of(ELFFile* elf, int index) {
  108. ELFSectionDict_it_t it;
  109. for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it); ELFSectionDict_next(it)) {
  110. ELFSectionDict_itref_t* itref = ELFSectionDict_ref(it);
  111. if(itref->value.sec_idx == index) {
  112. return &itref->value;
  113. }
  114. }
  115. return NULL;
  116. }
  117. static Elf32_Addr elf_address_of(ELFFile* elf, Elf32_Sym* sym, const char* sName) {
  118. if(sym->st_shndx == SHN_UNDEF) {
  119. Elf32_Addr addr = 0;
  120. if(elf->api_interface->resolver_callback(sName, &addr)) {
  121. return addr;
  122. }
  123. } else {
  124. ELFSection* symSec = elf_section_of(elf, sym->st_shndx);
  125. if(symSec) {
  126. return ((Elf32_Addr)symSec->data) + sym->st_value;
  127. }
  128. }
  129. FURI_LOG_D(TAG, " Can not find address for symbol %s", sName);
  130. return ELF_INVALID_ADDRESS;
  131. }
  132. __attribute__((unused)) static const char* elf_reloc_type_to_str(int symt) {
  133. #define STRCASE(name) \
  134. case name: \
  135. return #name;
  136. switch(symt) {
  137. STRCASE(R_ARM_NONE)
  138. STRCASE(R_ARM_TARGET1)
  139. STRCASE(R_ARM_ABS32)
  140. STRCASE(R_ARM_THM_PC22)
  141. STRCASE(R_ARM_THM_JUMP24)
  142. default:
  143. return "R_<unknow>";
  144. }
  145. #undef STRCASE
  146. }
  147. static JMPTrampoline* elf_create_trampoline(Elf32_Addr addr) {
  148. JMPTrampoline* trampoline = malloc(sizeof(JMPTrampoline));
  149. memcpy(trampoline->code, trampoline_code_little_endian, TRAMPOLINE_CODE_SIZE);
  150. trampoline->addr = addr;
  151. return trampoline;
  152. }
  153. static void elf_relocate_jmp_call(ELFFile* elf, Elf32_Addr relAddr, int type, Elf32_Addr symAddr) {
  154. int offset, hi, lo, s, j1, j2, i1, i2, imm10, imm11;
  155. int to_thumb, is_call, blx_bit = 1 << 12;
  156. /* Get initial offset */
  157. hi = ((uint16_t*)relAddr)[0];
  158. lo = ((uint16_t*)relAddr)[1];
  159. s = (hi >> 10) & 1;
  160. j1 = (lo >> 13) & 1;
  161. j2 = (lo >> 11) & 1;
  162. i1 = (j1 ^ s) ^ 1;
  163. i2 = (j2 ^ s) ^ 1;
  164. imm10 = hi & 0x3ff;
  165. imm11 = lo & 0x7ff;
  166. offset = (s << 24) | (i1 << 23) | (i2 << 22) | (imm10 << 12) | (imm11 << 1);
  167. if(offset & 0x01000000) offset -= 0x02000000;
  168. to_thumb = symAddr & 1;
  169. is_call = (type == R_ARM_THM_PC22);
  170. /* Store offset */
  171. int offset_copy = offset;
  172. /* Compute final offset */
  173. offset += symAddr - relAddr;
  174. if(!to_thumb && is_call) {
  175. blx_bit = 0; /* bl -> blx */
  176. offset = (offset + 3) & -4; /* Compute offset from aligned PC */
  177. }
  178. /* Check that relocation is possible
  179. * offset must not be out of range
  180. * if target is to be entered in arm mode:
  181. - bit 1 must not set
  182. - instruction must be a call (bl) or a jump to PLT */
  183. if(!to_thumb || offset >= 0x1000000 || offset < -0x1000000) {
  184. if(to_thumb || (symAddr & 2) || (!is_call)) {
  185. FURI_LOG_D(
  186. TAG,
  187. "can't relocate value at %x, %s, doing trampoline",
  188. relAddr,
  189. elf_reloc_type_to_str(type));
  190. Elf32_Addr addr;
  191. if(!address_cache_get(elf->trampoline_cache, symAddr, &addr)) {
  192. addr = (Elf32_Addr)elf_create_trampoline(symAddr);
  193. address_cache_put(elf->trampoline_cache, symAddr, addr);
  194. }
  195. offset = offset_copy;
  196. offset += (int)addr - relAddr;
  197. if(!to_thumb && is_call) {
  198. blx_bit = 0; /* bl -> blx */
  199. offset = (offset + 3) & -4; /* Compute offset from aligned PC */
  200. }
  201. }
  202. }
  203. /* Compute and store final offset */
  204. s = (offset >> 24) & 1;
  205. i1 = (offset >> 23) & 1;
  206. i2 = (offset >> 22) & 1;
  207. j1 = s ^ (i1 ^ 1);
  208. j2 = s ^ (i2 ^ 1);
  209. imm10 = (offset >> 12) & 0x3ff;
  210. imm11 = (offset >> 1) & 0x7ff;
  211. (*(uint16_t*)relAddr) = (uint16_t)((hi & 0xf800) | (s << 10) | imm10);
  212. (*(uint16_t*)(relAddr + 2)) =
  213. (uint16_t)((lo & 0xc000) | (j1 << 13) | blx_bit | (j2 << 11) | imm11);
  214. }
  215. static void elf_relocate_mov(Elf32_Addr relAddr, int type, Elf32_Addr symAddr) {
  216. uint16_t upper_insn = ((uint16_t*)relAddr)[0];
  217. uint16_t lower_insn = ((uint16_t*)relAddr)[1];
  218. /* MOV*<C> <Rd>,#<imm16>
  219. *
  220. * i = upper[10]
  221. * imm4 = upper[3:0]
  222. * imm3 = lower[14:12]
  223. * imm8 = lower[7:0]
  224. *
  225. * imm16 = imm4:i:imm3:imm8
  226. */
  227. uint32_t i = (upper_insn >> 10) & 1; /* upper[10] */
  228. uint32_t imm4 = upper_insn & 0x000F; /* upper[3:0] */
  229. uint32_t imm3 = (lower_insn >> 12) & 0x7; /* lower[14:12] */
  230. uint32_t imm8 = lower_insn & 0x00FF; /* lower[7:0] */
  231. int32_t addend = (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8; /* imm16 */
  232. uint32_t addr = (symAddr + addend);
  233. if (type == R_ARM_THM_MOVT_ABS) {
  234. addr >>= 16; /* upper 16 bits */
  235. } else {
  236. addr &= 0x0000FFFF; /* lower 16 bits */
  237. }
  238. /* Re-encode */
  239. ((uint16_t*)relAddr)[0] = (upper_insn & 0xFBF0)
  240. | (((addr >> 11) & 1) << 10) /* i */
  241. | ((addr >> 12) & 0x000F); /* imm4 */
  242. ((uint16_t*)relAddr)[1] = (lower_insn & 0x8F00)
  243. | (((addr >> 8) & 0x7) << 12) /* imm3 */
  244. | (addr & 0x00FF); /* imm8 */
  245. }
  246. static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf32_Addr symAddr) {
  247. switch(type) {
  248. case R_ARM_TARGET1:
  249. case R_ARM_ABS32:
  250. *((uint32_t*)relAddr) += symAddr;
  251. FURI_LOG_D(TAG, " R_ARM_ABS32 relocated is 0x%08X", (unsigned int)*((uint32_t*)relAddr));
  252. break;
  253. case R_ARM_THM_PC22:
  254. case R_ARM_THM_JUMP24:
  255. elf_relocate_jmp_call(elf, relAddr, type, symAddr);
  256. FURI_LOG_D(
  257. TAG, " R_ARM_THM_CALL/JMP relocated is 0x%08X", (unsigned int)*((uint32_t*)relAddr));
  258. break;
  259. case R_ARM_THM_MOVW_ABS_NC:
  260. case R_ARM_THM_MOVT_ABS:
  261. elf_relocate_mov(relAddr, type, symAddr);
  262. FURI_LOG_D(TAG, " R_ARM_THM_MOVW_ABS_NC/MOVT_ABS relocated is 0x%08X", (unsigned int)*((uint32_t*)relAddr));
  263. break;
  264. default:
  265. FURI_LOG_E(TAG, " Undefined relocation %d", type);
  266. return false;
  267. }
  268. return true;
  269. }
  270. static bool elf_relocate(ELFFile* elf, Elf32_Shdr* h, ELFSection* s) {
  271. if(s->data) {
  272. Elf32_Rel rel;
  273. size_t relEntries = h->sh_size / sizeof(rel);
  274. size_t relCount;
  275. (void)storage_file_seek(elf->fd, h->sh_offset, true);
  276. FURI_LOG_D(TAG, " Offset Info Type Name");
  277. int relocate_result = true;
  278. string_t symbol_name;
  279. string_init(symbol_name);
  280. for(relCount = 0; relCount < relEntries; relCount++) {
  281. if(relCount % RESOLVER_THREAD_YIELD_STEP == 0) {
  282. FURI_LOG_D(TAG, " reloc YIELD");
  283. furi_delay_tick(1);
  284. }
  285. if(storage_file_read(elf->fd, &rel, sizeof(Elf32_Rel)) != sizeof(Elf32_Rel)) {
  286. FURI_LOG_E(TAG, " reloc read fail");
  287. string_clear(symbol_name);
  288. return false;
  289. }
  290. Elf32_Addr symAddr;
  291. int symEntry = ELF32_R_SYM(rel.r_info);
  292. int relType = ELF32_R_TYPE(rel.r_info);
  293. Elf32_Addr relAddr = ((Elf32_Addr)s->data) + rel.r_offset;
  294. if(!address_cache_get(elf->relocation_cache, symEntry, &symAddr)) {
  295. Elf32_Sym sym;
  296. string_reset(symbol_name);
  297. if(!elf_read_symbol(elf, symEntry, &sym, symbol_name)) {
  298. FURI_LOG_E(TAG, " symbol read fail");
  299. string_clear(symbol_name);
  300. return false;
  301. }
  302. FURI_LOG_D(
  303. TAG,
  304. " %08X %08X %-16s %s",
  305. (unsigned int)rel.r_offset,
  306. (unsigned int)rel.r_info,
  307. elf_reloc_type_to_str(relType),
  308. string_get_cstr(symbol_name));
  309. symAddr = elf_address_of(elf, &sym, string_get_cstr(symbol_name));
  310. address_cache_put(elf->relocation_cache, symEntry, symAddr);
  311. }
  312. if(symAddr != ELF_INVALID_ADDRESS) {
  313. FURI_LOG_D(
  314. TAG,
  315. " symAddr=%08X relAddr=%08X",
  316. (unsigned int)symAddr,
  317. (unsigned int)relAddr);
  318. if(!elf_relocate_symbol(elf, relAddr, relType, symAddr)) {
  319. relocate_result = false;
  320. }
  321. } else {
  322. FURI_LOG_E(TAG, " No symbol address of %s", string_get_cstr(symbol_name));
  323. relocate_result = false;
  324. }
  325. }
  326. string_clear(symbol_name);
  327. return relocate_result;
  328. } else {
  329. FURI_LOG_D(TAG, "Section not loaded");
  330. }
  331. return false;
  332. }
  333. /**************************************************************************************************/
  334. /********************************************* MISC ***********************************************/
  335. /**************************************************************************************************/
  336. static bool cstr_prefix(const char* prefix, const char* string) {
  337. return strncmp(prefix, string, strlen(prefix)) == 0;
  338. }
  339. /**************************************************************************************************/
  340. /************************************ Internal FAP interfaces *************************************/
  341. /**************************************************************************************************/
  342. typedef enum {
  343. SectionTypeERROR = 0,
  344. SectionTypeUnused = 1 << 0,
  345. SectionTypeData = 1 << 1,
  346. SectionTypeRelData = 1 << 2,
  347. SectionTypeSymTab = 1 << 3,
  348. SectionTypeStrTab = 1 << 4,
  349. SectionTypeManifest = 1 << 5,
  350. SectionTypeDebugLink = 1 << 6,
  351. SectionTypeValid = SectionTypeSymTab | SectionTypeStrTab | SectionTypeManifest,
  352. } SectionType;
  353. static bool elf_load_metadata(
  354. ELFFile* elf,
  355. Elf32_Shdr* section_header,
  356. FlipperApplicationManifest* manifest) {
  357. if(section_header->sh_size < sizeof(FlipperApplicationManifest)) {
  358. return false;
  359. }
  360. if(manifest == NULL) {
  361. return true;
  362. }
  363. return storage_file_seek(elf->fd, section_header->sh_offset, true) &&
  364. storage_file_read(elf->fd, manifest, section_header->sh_size) ==
  365. section_header->sh_size;
  366. }
  367. static bool elf_load_debug_link(ELFFile* elf, Elf32_Shdr* section_header) {
  368. elf->debug_link_info.debug_link_size = section_header->sh_size;
  369. elf->debug_link_info.debug_link = malloc(section_header->sh_size);
  370. return storage_file_seek(elf->fd, section_header->sh_offset, true) &&
  371. storage_file_read(elf->fd, elf->debug_link_info.debug_link, section_header->sh_size) ==
  372. section_header->sh_size;
  373. }
  374. static SectionType elf_preload_section(
  375. ELFFile* elf,
  376. size_t section_idx,
  377. Elf32_Shdr* section_header,
  378. string_t name_string,
  379. FlipperApplicationManifest* manifest) {
  380. const char* name = string_get_cstr(name_string);
  381. const struct {
  382. const char* prefix;
  383. SectionType type;
  384. } lookup_sections[] = {
  385. {".text", SectionTypeData},
  386. {".rodata", SectionTypeData},
  387. {".data", SectionTypeData},
  388. {".bss", SectionTypeData},
  389. {".preinit_array", SectionTypeData},
  390. {".init_array", SectionTypeData},
  391. {".fini_array", SectionTypeData},
  392. {".rel.text", SectionTypeRelData},
  393. {".rel.rodata", SectionTypeRelData},
  394. {".rel.data", SectionTypeRelData},
  395. {".rel.preinit_array", SectionTypeRelData},
  396. {".rel.init_array", SectionTypeRelData},
  397. {".rel.fini_array", SectionTypeRelData},
  398. };
  399. for(size_t i = 0; i < COUNT_OF(lookup_sections); i++) {
  400. if(cstr_prefix(lookup_sections[i].prefix, name)) {
  401. FURI_LOG_D(TAG, "Found section %s", lookup_sections[i].prefix);
  402. if(lookup_sections[i].type == SectionTypeRelData) {
  403. name = name + strlen(".rel");
  404. }
  405. ELFSection* section_p = elf_file_get_section(elf, name);
  406. if(!section_p) {
  407. ELFSection section = {
  408. .data = NULL,
  409. .sec_idx = 0,
  410. .rel_sec_idx = 0,
  411. .size = 0,
  412. };
  413. elf_file_put_section(elf, name, &section);
  414. section_p = elf_file_get_section(elf, name);
  415. }
  416. if(lookup_sections[i].type == SectionTypeRelData) {
  417. section_p->rel_sec_idx = section_idx;
  418. } else {
  419. section_p->sec_idx = section_idx;
  420. }
  421. return lookup_sections[i].type;
  422. }
  423. }
  424. if(strcmp(name, ".symtab") == 0) {
  425. FURI_LOG_D(TAG, "Found .symtab section");
  426. elf->symbol_table = section_header->sh_offset;
  427. elf->symbol_count = section_header->sh_size / sizeof(Elf32_Sym);
  428. return SectionTypeSymTab;
  429. } else if(strcmp(name, ".strtab") == 0) {
  430. FURI_LOG_D(TAG, "Found .strtab section");
  431. elf->symbol_table_strings = section_header->sh_offset;
  432. return SectionTypeStrTab;
  433. } else if(strcmp(name, ".fapmeta") == 0) {
  434. FURI_LOG_D(TAG, "Found .fapmeta section");
  435. if(elf_load_metadata(elf, section_header, manifest)) {
  436. return SectionTypeManifest;
  437. } else {
  438. return SectionTypeERROR;
  439. }
  440. } else if(strcmp(name, ".gnu_debuglink") == 0) {
  441. FURI_LOG_D(TAG, "Found .gnu_debuglink section");
  442. if(elf_load_debug_link(elf, section_header)) {
  443. return SectionTypeDebugLink;
  444. } else {
  445. return SectionTypeERROR;
  446. }
  447. }
  448. return SectionTypeUnused;
  449. }
  450. static bool elf_load_section_data(ELFFile* elf, ELFSection* section) {
  451. Elf32_Shdr section_header;
  452. if(section->sec_idx == 0) {
  453. FURI_LOG_D(TAG, "Section is not present");
  454. return true;
  455. }
  456. if(!elf_read_section_header(elf, section->sec_idx, &section_header)) {
  457. return false;
  458. }
  459. if(section_header.sh_size == 0) {
  460. FURI_LOG_D(TAG, "No data for section");
  461. return true;
  462. }
  463. section->data = aligned_malloc(section_header.sh_size, section_header.sh_addralign);
  464. section->size = section_header.sh_size;
  465. if(section_header.sh_type == SHT_NOBITS) {
  466. /* section is empty (.bss?) */
  467. /* no need to memset - allocator already did that */
  468. return true;
  469. }
  470. if((!storage_file_seek(elf->fd, section_header.sh_offset, true)) ||
  471. (storage_file_read(elf->fd, section->data, section_header.sh_size) !=
  472. section_header.sh_size)) {
  473. FURI_LOG_E(TAG, " seek/read fail");
  474. return false;
  475. }
  476. FURI_LOG_D(TAG, "0x%X", section->data);
  477. return true;
  478. }
  479. static bool elf_relocate_section(ELFFile* elf, ELFSection* section) {
  480. Elf32_Shdr section_header;
  481. if(section->rel_sec_idx) {
  482. FURI_LOG_D(TAG, "Relocating section");
  483. if(elf_read_section_header(elf, section->rel_sec_idx, &section_header))
  484. return elf_relocate(elf, &section_header, section);
  485. else {
  486. FURI_LOG_E(TAG, "Error reading section header");
  487. return false;
  488. }
  489. } else {
  490. FURI_LOG_D(TAG, "No relocation index"); /* Not an error */
  491. }
  492. return true;
  493. }
  494. static void elf_file_call_section_list(ELFFile* elf, const char* name, bool reverse_order) {
  495. ELFSection* section = elf_file_get_section(elf, name);
  496. if(section && section->size) {
  497. const uint32_t* start = section->data;
  498. const uint32_t* end = section->data + section->size;
  499. if(reverse_order) {
  500. while(end > start) {
  501. end--;
  502. ((void (*)(void))(*end))();
  503. }
  504. } else {
  505. while(start < end) {
  506. ((void (*)(void))(*start))();
  507. start++;
  508. }
  509. }
  510. }
  511. }
  512. /**************************************************************************************************/
  513. /********************************************* Public *********************************************/
  514. /**************************************************************************************************/
  515. ELFFile* elf_file_alloc(Storage* storage, const ElfApiInterface* api_interface) {
  516. ELFFile* elf = malloc(sizeof(ELFFile));
  517. elf->fd = storage_file_alloc(storage);
  518. elf->api_interface = api_interface;
  519. ELFSectionDict_init(elf->sections);
  520. AddressCache_init(elf->trampoline_cache);
  521. return elf;
  522. }
  523. void elf_file_free(ELFFile* elf) {
  524. // free sections data
  525. {
  526. ELFSectionDict_it_t it;
  527. for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it);
  528. ELFSectionDict_next(it)) {
  529. const ELFSectionDict_itref_t* itref = ELFSectionDict_cref(it);
  530. if(itref->value.data) {
  531. aligned_free(itref->value.data);
  532. }
  533. free((void*)itref->key);
  534. }
  535. ELFSectionDict_clear(elf->sections);
  536. }
  537. // free trampoline data
  538. {
  539. AddressCache_it_t it;
  540. for(AddressCache_it(it, elf->trampoline_cache); !AddressCache_end_p(it);
  541. AddressCache_next(it)) {
  542. const AddressCache_itref_t* itref = AddressCache_cref(it);
  543. free((void*)itref->value);
  544. }
  545. AddressCache_clear(elf->trampoline_cache);
  546. }
  547. if(elf->debug_link_info.debug_link) {
  548. free(elf->debug_link_info.debug_link);
  549. }
  550. storage_file_free(elf->fd);
  551. free(elf);
  552. }
  553. bool elf_file_open(ELFFile* elf, const char* path) {
  554. Elf32_Ehdr h;
  555. Elf32_Shdr sH;
  556. if(!storage_file_open(elf->fd, path, FSAM_READ, FSOM_OPEN_EXISTING) ||
  557. !storage_file_seek(elf->fd, 0, true) ||
  558. storage_file_read(elf->fd, &h, sizeof(h)) != sizeof(h) ||
  559. !storage_file_seek(elf->fd, h.e_shoff + h.e_shstrndx * sizeof(sH), true) ||
  560. storage_file_read(elf->fd, &sH, sizeof(Elf32_Shdr)) != sizeof(Elf32_Shdr)) {
  561. return false;
  562. }
  563. elf->entry = h.e_entry;
  564. elf->sections_count = h.e_shnum;
  565. elf->section_table = h.e_shoff;
  566. elf->section_table_strings = sH.sh_offset;
  567. return true;
  568. }
  569. bool elf_file_load_manifest(ELFFile* elf, FlipperApplicationManifest* manifest) {
  570. bool result = false;
  571. string_t name;
  572. string_init(name);
  573. FURI_LOG_D(TAG, "Looking for manifest section");
  574. for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) {
  575. Elf32_Shdr section_header;
  576. string_reset(name);
  577. if(!elf_read_section(elf, section_idx, &section_header, name)) {
  578. break;
  579. }
  580. if(string_cmp(name, ".fapmeta") == 0) {
  581. if(elf_load_metadata(elf, &section_header, manifest)) {
  582. FURI_LOG_D(TAG, "Load manifest done");
  583. result = true;
  584. break;
  585. } else {
  586. break;
  587. }
  588. }
  589. }
  590. string_clear(name);
  591. return result;
  592. }
  593. bool elf_file_load_section_table(ELFFile* elf, FlipperApplicationManifest* manifest) {
  594. SectionType loaded_sections = SectionTypeERROR;
  595. string_t name;
  596. string_init(name);
  597. FURI_LOG_D(TAG, "Scan ELF indexs...");
  598. for(size_t section_idx = 1; section_idx < elf->sections_count; section_idx++) {
  599. Elf32_Shdr section_header;
  600. string_reset(name);
  601. if(!elf_read_section(elf, section_idx, &section_header, name)) {
  602. loaded_sections = SectionTypeERROR;
  603. break;
  604. }
  605. FURI_LOG_D(TAG, "Preloading data for section #%d %s", section_idx, string_get_cstr(name));
  606. SectionType section_type =
  607. elf_preload_section(elf, section_idx, &section_header, name, manifest);
  608. loaded_sections |= section_type;
  609. if(section_type == SectionTypeERROR) {
  610. loaded_sections = SectionTypeERROR;
  611. break;
  612. }
  613. }
  614. string_clear(name);
  615. FURI_LOG_D(TAG, "Load symbols done");
  616. return IS_FLAGS_SET(loaded_sections, SectionTypeValid);
  617. }
  618. ELFFileLoadStatus elf_file_load_sections(ELFFile* elf) {
  619. ELFFileLoadStatus status = ELFFileLoadStatusSuccess;
  620. ELFSectionDict_it_t it;
  621. AddressCache_init(elf->relocation_cache);
  622. size_t start = furi_get_tick();
  623. for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it); ELFSectionDict_next(it)) {
  624. ELFSectionDict_itref_t* itref = ELFSectionDict_ref(it);
  625. FURI_LOG_D(TAG, "Loading section '%s'", itref->key);
  626. if(!elf_load_section_data(elf, &itref->value)) {
  627. FURI_LOG_E(TAG, "Error loading section '%s'", itref->key);
  628. status = ELFFileLoadStatusUnspecifiedError;
  629. }
  630. }
  631. if(status == ELFFileLoadStatusSuccess) {
  632. for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it);
  633. ELFSectionDict_next(it)) {
  634. ELFSectionDict_itref_t* itref = ELFSectionDict_ref(it);
  635. FURI_LOG_D(TAG, "Relocating section '%s'", itref->key);
  636. if(!elf_relocate_section(elf, &itref->value)) {
  637. FURI_LOG_E(TAG, "Error relocating section '%s'", itref->key);
  638. status = ELFFileLoadStatusMissingImports;
  639. }
  640. }
  641. }
  642. /* Fixing up entry point */
  643. if(status == ELFFileLoadStatusSuccess) {
  644. ELFSection* text_section = elf_file_get_section(elf, ".text");
  645. if(text_section == NULL) {
  646. FURI_LOG_E(TAG, "No .text section found");
  647. status = ELFFileLoadStatusUnspecifiedError;
  648. } else {
  649. elf->entry += (uint32_t)text_section->data;
  650. }
  651. }
  652. FURI_LOG_D(TAG, "Relocation cache size: %u", AddressCache_size(elf->relocation_cache));
  653. FURI_LOG_D(TAG, "Trampoline cache size: %u", AddressCache_size(elf->trampoline_cache));
  654. AddressCache_clear(elf->relocation_cache);
  655. FURI_LOG_I(TAG, "Loaded in %ums", (size_t)(furi_get_tick() - start));
  656. return status;
  657. }
  658. void elf_file_pre_run(ELFFile* elf) {
  659. elf_file_call_section_list(elf, ".preinit_array", false);
  660. elf_file_call_section_list(elf, ".init_array", false);
  661. }
  662. int32_t elf_file_run(ELFFile* elf, void* args) {
  663. int32_t result;
  664. result = ((int32_t(*)(void*))elf->entry)(args);
  665. return result;
  666. }
  667. void elf_file_post_run(ELFFile* elf) {
  668. elf_file_call_section_list(elf, ".fini_array", true);
  669. }
  670. const ElfApiInterface* elf_file_get_api_interface(ELFFile* elf_file) {
  671. return elf_file->api_interface;
  672. }
  673. void elf_file_init_debug_info(ELFFile* elf, ELFDebugInfo* debug_info) {
  674. // set entry
  675. debug_info->entry = elf->entry;
  676. // copy debug info
  677. memcpy(&debug_info->debug_link_info, &elf->debug_link_info, sizeof(ELFDebugLinkInfo));
  678. // init mmap
  679. debug_info->mmap_entry_count = ELFSectionDict_size(elf->sections);
  680. debug_info->mmap_entries = malloc(sizeof(ELFMemoryMapEntry) * debug_info->mmap_entry_count);
  681. uint32_t mmap_entry_idx = 0;
  682. ELFSectionDict_it_t it;
  683. for(ELFSectionDict_it(it, elf->sections); !ELFSectionDict_end_p(it); ELFSectionDict_next(it)) {
  684. const ELFSectionDict_itref_t* itref = ELFSectionDict_cref(it);
  685. const void* data_ptr = itref->value.data;
  686. if(data_ptr) {
  687. debug_info->mmap_entries[mmap_entry_idx].address = (uint32_t)data_ptr;
  688. debug_info->mmap_entries[mmap_entry_idx].name = itref->key;
  689. mmap_entry_idx++;
  690. }
  691. }
  692. }
  693. void elf_file_clear_debug_info(ELFDebugInfo* debug_info) {
  694. // clear debug info
  695. memset(&debug_info->debug_link_info, 0, sizeof(ELFDebugLinkInfo));
  696. // clear mmap
  697. if(debug_info->mmap_entries) {
  698. free(debug_info->mmap_entries);
  699. debug_info->mmap_entries = NULL;
  700. }
  701. debug_info->mmap_entry_count = 0;
  702. }