elf_ops.h.inc 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627
  1. static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
  2. {
  3. bswap16s(&ehdr->e_type); /* Object file type */
  4. bswap16s(&ehdr->e_machine); /* Architecture */
  5. bswap32s(&ehdr->e_version); /* Object file version */
  6. bswapSZs(&ehdr->e_entry); /* Entry point virtual address */
  7. bswapSZs(&ehdr->e_phoff); /* Program header table file offset */
  8. bswapSZs(&ehdr->e_shoff); /* Section header table file offset */
  9. bswap32s(&ehdr->e_flags); /* Processor-specific flags */
  10. bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
  11. bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
  12. bswap16s(&ehdr->e_phnum); /* Program header table entry count */
  13. bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
  14. bswap16s(&ehdr->e_shnum); /* Section header table entry count */
  15. bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
  16. }
  17. static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
  18. {
  19. bswap32s(&phdr->p_type); /* Segment type */
  20. bswapSZs(&phdr->p_offset); /* Segment file offset */
  21. bswapSZs(&phdr->p_vaddr); /* Segment virtual address */
  22. bswapSZs(&phdr->p_paddr); /* Segment physical address */
  23. bswapSZs(&phdr->p_filesz); /* Segment size in file */
  24. bswapSZs(&phdr->p_memsz); /* Segment size in memory */
  25. bswap32s(&phdr->p_flags); /* Segment flags */
  26. bswapSZs(&phdr->p_align); /* Segment alignment */
  27. }
  28. static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
  29. {
  30. bswap32s(&shdr->sh_name);
  31. bswap32s(&shdr->sh_type);
  32. bswapSZs(&shdr->sh_flags);
  33. bswapSZs(&shdr->sh_addr);
  34. bswapSZs(&shdr->sh_offset);
  35. bswapSZs(&shdr->sh_size);
  36. bswap32s(&shdr->sh_link);
  37. bswap32s(&shdr->sh_info);
  38. bswapSZs(&shdr->sh_addralign);
  39. bswapSZs(&shdr->sh_entsize);
  40. }
  41. static void glue(bswap_sym, SZ)(struct elf_sym *sym)
  42. {
  43. bswap32s(&sym->st_name);
  44. bswapSZs(&sym->st_value);
  45. bswapSZs(&sym->st_size);
  46. bswap16s(&sym->st_shndx);
  47. }
  48. static void glue(bswap_rela, SZ)(struct elf_rela *rela)
  49. {
  50. bswapSZs(&rela->r_offset);
  51. bswapSZs(&rela->r_info);
  52. bswapSZs((elf_word *)&rela->r_addend);
  53. }
  54. static struct elf_shdr *glue(find_section, SZ)(struct elf_shdr *shdr_table,
  55. int n, int type)
  56. {
  57. int i;
  58. for(i=0;i<n;i++) {
  59. if (shdr_table[i].sh_type == type)
  60. return shdr_table + i;
  61. }
  62. return NULL;
  63. }
  64. static int glue(symfind, SZ)(const void *s0, const void *s1)
  65. {
  66. hwaddr addr = *(hwaddr *)s0;
  67. struct elf_sym *sym = (struct elf_sym *)s1;
  68. int result = 0;
  69. if (addr < sym->st_value) {
  70. result = -1;
  71. } else if (addr >= sym->st_value + sym->st_size) {
  72. result = 1;
  73. }
  74. return result;
  75. }
  76. static const char *glue(lookup_symbol, SZ)(struct syminfo *s,
  77. hwaddr orig_addr)
  78. {
  79. struct elf_sym *syms = glue(s->disas_symtab.elf, SZ);
  80. struct elf_sym *sym;
  81. sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms),
  82. glue(symfind, SZ));
  83. if (sym != NULL) {
  84. return s->disas_strtab + sym->st_name;
  85. }
  86. return "";
  87. }
  88. static int glue(symcmp, SZ)(const void *s0, const void *s1)
  89. {
  90. struct elf_sym *sym0 = (struct elf_sym *)s0;
  91. struct elf_sym *sym1 = (struct elf_sym *)s1;
  92. return (sym0->st_value < sym1->st_value)
  93. ? -1
  94. : ((sym0->st_value > sym1->st_value) ? 1 : 0);
  95. }
  96. static void glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
  97. int clear_lsb, symbol_fn_t sym_cb)
  98. {
  99. struct elf_shdr *symtab, *strtab;
  100. g_autofree struct elf_shdr *shdr_table = NULL;
  101. g_autofree struct elf_sym *syms = NULL;
  102. g_autofree char *str = NULL;
  103. struct syminfo *s;
  104. int nsyms, i;
  105. shdr_table = load_at(fd, ehdr->e_shoff,
  106. sizeof(struct elf_shdr) * ehdr->e_shnum);
  107. if (!shdr_table) {
  108. return;
  109. }
  110. if (must_swab) {
  111. for (i = 0; i < ehdr->e_shnum; i++) {
  112. glue(bswap_shdr, SZ)(shdr_table + i);
  113. }
  114. }
  115. symtab = glue(find_section, SZ)(shdr_table, ehdr->e_shnum, SHT_SYMTAB);
  116. if (!symtab) {
  117. return;
  118. }
  119. syms = load_at(fd, symtab->sh_offset, symtab->sh_size);
  120. if (!syms) {
  121. return;
  122. }
  123. nsyms = symtab->sh_size / sizeof(struct elf_sym);
  124. /* String table */
  125. if (symtab->sh_link >= ehdr->e_shnum) {
  126. return;
  127. }
  128. strtab = &shdr_table[symtab->sh_link];
  129. str = load_at(fd, strtab->sh_offset, strtab->sh_size);
  130. if (!str) {
  131. return;
  132. }
  133. i = 0;
  134. while (i < nsyms) {
  135. if (must_swab) {
  136. glue(bswap_sym, SZ)(&syms[i]);
  137. }
  138. if (sym_cb) {
  139. sym_cb(str + syms[i].st_name, syms[i].st_info,
  140. syms[i].st_value, syms[i].st_size);
  141. }
  142. /* We are only interested in function symbols.
  143. Throw everything else away. */
  144. if (syms[i].st_shndx == SHN_UNDEF ||
  145. syms[i].st_shndx >= SHN_LORESERVE ||
  146. ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
  147. nsyms--;
  148. if (i < nsyms) {
  149. syms[i] = syms[nsyms];
  150. }
  151. continue;
  152. }
  153. if (clear_lsb) {
  154. /* The bottom address bit marks a Thumb or MIPS16 symbol. */
  155. syms[i].st_value &= ~(glue(glue(Elf, SZ), _Addr))1;
  156. }
  157. i++;
  158. }
  159. /* check we have symbols left */
  160. if (nsyms == 0) {
  161. return;
  162. }
  163. syms = g_realloc(syms, nsyms * sizeof(*syms));
  164. qsort(syms, nsyms, sizeof(*syms), glue(symcmp, SZ));
  165. for (i = 0; i < nsyms - 1; i++) {
  166. if (syms[i].st_size == 0) {
  167. syms[i].st_size = syms[i + 1].st_value - syms[i].st_value;
  168. }
  169. }
  170. /* Commit */
  171. s = g_malloc0(sizeof(*s));
  172. s->lookup_symbol = glue(lookup_symbol, SZ);
  173. glue(s->disas_symtab.elf, SZ) = g_steal_pointer(&syms);
  174. s->disas_num_syms = nsyms;
  175. s->disas_strtab = g_steal_pointer(&str);
  176. s->next = syminfos;
  177. syminfos = s;
  178. }
  179. static int glue(elf_reloc, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
  180. uint64_t (*translate_fn)(void *, uint64_t),
  181. void *translate_opaque, uint8_t *data,
  182. struct elf_phdr *ph, int elf_machine)
  183. {
  184. struct elf_shdr *reltab, *shdr_table = NULL;
  185. struct elf_rela *rels = NULL;
  186. int nrels, i, ret = -1;
  187. elf_word wordval;
  188. void *addr;
  189. shdr_table = load_at(fd, ehdr->e_shoff,
  190. sizeof(struct elf_shdr) * ehdr->e_shnum);
  191. if (!shdr_table) {
  192. return -1;
  193. }
  194. if (must_swab) {
  195. for (i = 0; i < ehdr->e_shnum; i++) {
  196. glue(bswap_shdr, SZ)(&shdr_table[i]);
  197. }
  198. }
  199. reltab = glue(find_section, SZ)(shdr_table, ehdr->e_shnum, SHT_RELA);
  200. if (!reltab) {
  201. goto fail;
  202. }
  203. rels = load_at(fd, reltab->sh_offset, reltab->sh_size);
  204. if (!rels) {
  205. goto fail;
  206. }
  207. nrels = reltab->sh_size / sizeof(struct elf_rela);
  208. for (i = 0; i < nrels; i++) {
  209. if (must_swab) {
  210. glue(bswap_rela, SZ)(&rels[i]);
  211. }
  212. if (rels[i].r_offset < ph->p_vaddr ||
  213. rels[i].r_offset >= ph->p_vaddr + ph->p_filesz) {
  214. continue;
  215. }
  216. addr = &data[rels[i].r_offset - ph->p_vaddr];
  217. switch (elf_machine) {
  218. case EM_S390:
  219. switch (rels[i].r_info) {
  220. case R_390_RELATIVE:
  221. wordval = *(elf_word *)addr;
  222. if (must_swab) {
  223. bswapSZs(&wordval);
  224. }
  225. wordval = translate_fn(translate_opaque, wordval);
  226. if (must_swab) {
  227. bswapSZs(&wordval);
  228. }
  229. *(elf_word *)addr = wordval;
  230. break;
  231. default:
  232. fprintf(stderr, "Unsupported relocation type %i!\n",
  233. (int)rels[i].r_info);
  234. }
  235. }
  236. }
  237. ret = 0;
  238. fail:
  239. g_free(rels);
  240. g_free(shdr_table);
  241. return ret;
  242. }
  243. /*
  244. * Given 'nhdr', a pointer to a range of ELF Notes, search through them
  245. * for a note matching type 'elf_note_type' and return a pointer to
  246. * the matching ELF note.
  247. */
  248. static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr,
  249. elf_word note_size,
  250. elf_word phdr_align,
  251. elf_word elf_note_type)
  252. {
  253. elf_word nhdr_size = sizeof(struct elf_note);
  254. elf_word elf_note_entry_offset = 0;
  255. elf_word note_type;
  256. elf_word nhdr_namesz;
  257. elf_word nhdr_descsz;
  258. if (nhdr == NULL) {
  259. return NULL;
  260. }
  261. note_type = nhdr->n_type;
  262. while (note_type != elf_note_type) {
  263. nhdr_namesz = nhdr->n_namesz;
  264. nhdr_descsz = nhdr->n_descsz;
  265. elf_note_entry_offset = nhdr_size +
  266. QEMU_ALIGN_UP(nhdr_namesz, phdr_align) +
  267. QEMU_ALIGN_UP(nhdr_descsz, phdr_align);
  268. /*
  269. * If the offset calculated in this iteration exceeds the
  270. * supplied size, we are done and no matching note was found.
  271. */
  272. if (elf_note_entry_offset > note_size) {
  273. return NULL;
  274. }
  275. /* skip to the next ELF Note entry */
  276. nhdr = (void *)nhdr + elf_note_entry_offset;
  277. note_type = nhdr->n_type;
  278. }
  279. return nhdr;
  280. }
  281. static ssize_t glue(load_elf, SZ)(const char *name, int fd,
  282. uint64_t (*elf_note_fn)(void *, void *, bool),
  283. uint64_t (*translate_fn)(void *, uint64_t),
  284. void *translate_opaque,
  285. int must_swab, uint64_t *pentry,
  286. uint64_t *lowaddr, uint64_t *highaddr,
  287. uint32_t *pflags, int elf_machine,
  288. int clear_lsb, int data_swab,
  289. AddressSpace *as, bool load_rom,
  290. symbol_fn_t sym_cb)
  291. {
  292. struct elfhdr ehdr;
  293. struct elf_phdr *phdr = NULL, *ph;
  294. int size, i;
  295. ssize_t total_size;
  296. elf_word mem_size, file_size, data_offset;
  297. uint64_t addr, low = (uint64_t)-1, high = 0;
  298. GMappedFile *mapped_file = NULL;
  299. uint8_t *data = NULL;
  300. ssize_t ret = ELF_LOAD_FAILED;
  301. if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
  302. goto fail;
  303. if (must_swab) {
  304. glue(bswap_ehdr, SZ)(&ehdr);
  305. }
  306. if (elf_machine <= EM_NONE) {
  307. /* The caller didn't specify an ARCH, we can figure it out */
  308. elf_machine = ehdr.e_machine;
  309. }
  310. switch (elf_machine) {
  311. case EM_PPC64:
  312. if (ehdr.e_machine != EM_PPC64) {
  313. if (ehdr.e_machine != EM_PPC) {
  314. ret = ELF_LOAD_WRONG_ARCH;
  315. goto fail;
  316. }
  317. }
  318. break;
  319. case EM_X86_64:
  320. if (ehdr.e_machine != EM_X86_64) {
  321. if (ehdr.e_machine != EM_386) {
  322. ret = ELF_LOAD_WRONG_ARCH;
  323. goto fail;
  324. }
  325. }
  326. break;
  327. case EM_MICROBLAZE:
  328. if (ehdr.e_machine != EM_MICROBLAZE) {
  329. if (ehdr.e_machine != EM_MICROBLAZE_OLD) {
  330. ret = ELF_LOAD_WRONG_ARCH;
  331. goto fail;
  332. }
  333. }
  334. break;
  335. case EM_MIPS:
  336. case EM_NANOMIPS:
  337. if ((ehdr.e_machine != EM_MIPS) &&
  338. (ehdr.e_machine != EM_NANOMIPS)) {
  339. ret = ELF_LOAD_WRONG_ARCH;
  340. goto fail;
  341. }
  342. break;
  343. default:
  344. if (elf_machine != ehdr.e_machine) {
  345. ret = ELF_LOAD_WRONG_ARCH;
  346. goto fail;
  347. }
  348. }
  349. if (pflags) {
  350. *pflags = ehdr.e_flags;
  351. }
  352. if (pentry) {
  353. *pentry = ehdr.e_entry;
  354. }
  355. glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb, sym_cb);
  356. size = ehdr.e_phnum * sizeof(phdr[0]);
  357. if (lseek(fd, ehdr.e_phoff, SEEK_SET) != ehdr.e_phoff) {
  358. goto fail;
  359. }
  360. phdr = g_malloc0(size);
  361. if (!phdr)
  362. goto fail;
  363. if (read(fd, phdr, size) != size)
  364. goto fail;
  365. if (must_swab) {
  366. for(i = 0; i < ehdr.e_phnum; i++) {
  367. ph = &phdr[i];
  368. glue(bswap_phdr, SZ)(ph);
  369. }
  370. }
  371. /*
  372. * Since we want to be able to modify the mapped buffer, we set the
  373. * 'writable' parameter to 'true'. Modifications to the buffer are not
  374. * written back to the file.
  375. */
  376. mapped_file = g_mapped_file_new_from_fd(fd, true, NULL);
  377. if (!mapped_file) {
  378. goto fail;
  379. }
  380. total_size = 0;
  381. for(i = 0; i < ehdr.e_phnum; i++) {
  382. ph = &phdr[i];
  383. if (ph->p_type == PT_LOAD) {
  384. mem_size = ph->p_memsz; /* Size of the ROM */
  385. file_size = ph->p_filesz; /* Size of the allocated data */
  386. data_offset = ph->p_offset; /* Offset where the data is located */
  387. if (file_size > 0) {
  388. if (g_mapped_file_get_length(mapped_file) <
  389. file_size + data_offset) {
  390. goto fail;
  391. }
  392. data = (uint8_t *)g_mapped_file_get_contents(mapped_file);
  393. data += data_offset;
  394. }
  395. /* The ELF spec is somewhat vague about the purpose of the
  396. * physical address field. One common use in the embedded world
  397. * is that physical address field specifies the load address
  398. * and the virtual address field specifies the execution address.
  399. * Segments are packed into ROM or flash, and the relocation
  400. * and zero-initialization of data is done at runtime. This
  401. * means that the memsz header represents the runtime size of the
  402. * segment, but the filesz represents the loadtime size. If
  403. * we try to honour the memsz value for an ELF file like this
  404. * we will end up with overlapping segments (which the
  405. * loader.c code will later reject).
  406. * We support ELF files using this scheme by by checking whether
  407. * paddr + memsz for this segment would overlap with any other
  408. * segment. If so, then we assume it's using this scheme and
  409. * truncate the loaded segment to the filesz size.
  410. * If the segment considered as being memsz size doesn't overlap
  411. * then we use memsz for the segment length, to handle ELF files
  412. * which assume that the loader will do the zero-initialization.
  413. */
  414. if (mem_size > file_size) {
  415. /* If this segment's zero-init portion overlaps another
  416. * segment's data or zero-init portion, then truncate this one.
  417. * Invalid ELF files where the segments overlap even when
  418. * only file_size bytes are loaded will be rejected by
  419. * the ROM overlap check in loader.c, so we don't try to
  420. * explicitly detect those here.
  421. */
  422. int j;
  423. elf_word zero_start = ph->p_paddr + file_size;
  424. elf_word zero_end = ph->p_paddr + mem_size;
  425. for (j = 0; j < ehdr.e_phnum; j++) {
  426. struct elf_phdr *jph = &phdr[j];
  427. if (i != j && jph->p_type == PT_LOAD) {
  428. elf_word other_start = jph->p_paddr;
  429. elf_word other_end = jph->p_paddr + jph->p_memsz;
  430. if (!(other_start >= zero_end ||
  431. zero_start >= other_end)) {
  432. mem_size = file_size;
  433. break;
  434. }
  435. }
  436. }
  437. }
  438. if (mem_size > SSIZE_MAX - total_size) {
  439. ret = ELF_LOAD_TOO_BIG;
  440. goto fail;
  441. }
  442. /* address_offset is hack for kernel images that are
  443. linked at the wrong physical address. */
  444. if (translate_fn) {
  445. addr = translate_fn(translate_opaque, ph->p_paddr);
  446. glue(elf_reloc, SZ)(&ehdr, fd, must_swab, translate_fn,
  447. translate_opaque, data, ph, elf_machine);
  448. } else {
  449. addr = ph->p_paddr;
  450. }
  451. if (data_swab) {
  452. elf_word j;
  453. for (j = 0; j < file_size; j += (1 << data_swab)) {
  454. uint8_t *dp = data + j;
  455. switch (data_swab) {
  456. case (1):
  457. *(uint16_t *)dp = bswap16(*(uint16_t *)dp);
  458. break;
  459. case (2):
  460. *(uint32_t *)dp = bswap32(*(uint32_t *)dp);
  461. break;
  462. case (3):
  463. *(uint64_t *)dp = bswap64(*(uint64_t *)dp);
  464. break;
  465. default:
  466. g_assert_not_reached();
  467. }
  468. }
  469. }
  470. /* the entry pointer in the ELF header is a virtual
  471. * address, if the text segments paddr and vaddr differ
  472. * we need to adjust the entry */
  473. if (pentry && !translate_fn &&
  474. ph->p_vaddr != ph->p_paddr &&
  475. ehdr.e_entry >= ph->p_vaddr &&
  476. ehdr.e_entry < ph->p_vaddr + ph->p_filesz &&
  477. ph->p_flags & PF_X) {
  478. *pentry = ehdr.e_entry - ph->p_vaddr + ph->p_paddr;
  479. }
  480. /* Some ELF files really do have segments of zero size;
  481. * just ignore them rather than trying to create empty
  482. * ROM blobs, because the zero-length blob can falsely
  483. * trigger the overlapping-ROM-blobs check.
  484. */
  485. if (mem_size != 0) {
  486. if (load_rom) {
  487. g_autofree char *label =
  488. g_strdup_printf("%s ELF program header segment %d",
  489. name, i);
  490. /*
  491. * rom_add_elf_program() takes its own reference to
  492. * 'mapped_file'.
  493. */
  494. rom_add_elf_program(label, mapped_file, data, file_size,
  495. mem_size, addr, as);
  496. } else {
  497. MemTxResult res;
  498. res = address_space_write(as ? as : &address_space_memory,
  499. addr, MEMTXATTRS_UNSPECIFIED,
  500. data, file_size);
  501. if (res != MEMTX_OK) {
  502. goto fail;
  503. }
  504. /*
  505. * We need to zero'ify the space that is not copied
  506. * from file
  507. */
  508. if (file_size < mem_size) {
  509. res = address_space_set(as ? as : &address_space_memory,
  510. addr + file_size, 0,
  511. mem_size - file_size,
  512. MEMTXATTRS_UNSPECIFIED);
  513. if (res != MEMTX_OK) {
  514. goto fail;
  515. }
  516. }
  517. }
  518. }
  519. total_size += mem_size;
  520. if (addr < low)
  521. low = addr;
  522. if ((addr + mem_size) > high)
  523. high = addr + mem_size;
  524. data = NULL;
  525. } else if (ph->p_type == PT_NOTE && elf_note_fn) {
  526. struct elf_note *nhdr = NULL;
  527. file_size = ph->p_filesz; /* Size of the range of ELF notes */
  528. data_offset = ph->p_offset; /* Offset where the notes are located */
  529. if (file_size > 0) {
  530. if (g_mapped_file_get_length(mapped_file) <
  531. file_size + data_offset) {
  532. goto fail;
  533. }
  534. data = (uint8_t *)g_mapped_file_get_contents(mapped_file);
  535. data += data_offset;
  536. }
  537. /*
  538. * Search the ELF notes to find one with a type matching the
  539. * value passed in via 'translate_opaque'
  540. */
  541. nhdr = (struct elf_note *)data;
  542. assert(translate_opaque != NULL);
  543. nhdr = glue(get_elf_note_type, SZ)(nhdr, file_size, ph->p_align,
  544. *(uint64_t *)translate_opaque);
  545. if (nhdr != NULL) {
  546. elf_note_fn((void *)nhdr, (void *)&ph->p_align, SZ == 64);
  547. }
  548. data = NULL;
  549. }
  550. }
  551. if (lowaddr) {
  552. *lowaddr = low;
  553. }
  554. if (highaddr) {
  555. *highaddr = high;
  556. }
  557. ret = total_size;
  558. fail:
  559. if (mapped_file) {
  560. g_mapped_file_unref(mapped_file);
  561. }
  562. g_free(phdr);
  563. return ret;
  564. }