diff options
-rw-r--r-- | fesvr/elfloader.cc | 93 |
1 files changed, 50 insertions, 43 deletions
diff --git a/fesvr/elfloader.cc b/fesvr/elfloader.cc index 7d39cce..b31e2be 100644 --- a/fesvr/elfloader.cc +++ b/fesvr/elfloader.cc @@ -40,49 +40,56 @@ std::map<std::string, uint64_t> load_elf(const char* fn, memif_t* memif, reg_t* std::vector<uint8_t> zeros; std::map<std::string, uint64_t> symbols; - #define LOAD_ELF(ehdr_t, phdr_t, shdr_t, sym_t, bswap) do { \ - ehdr_t* eh = (ehdr_t*)buf; \ - phdr_t* ph = (phdr_t*)(buf + bswap(eh->e_phoff)); \ - *entry = bswap(eh->e_entry); \ - assert(size >= bswap(eh->e_phoff) + bswap(eh->e_phnum)*sizeof(*ph)); \ - for (unsigned i = 0; i < bswap(eh->e_phnum); i++) { \ - if(bswap(ph[i].p_type) == PT_LOAD && bswap(ph[i].p_memsz)) { \ - if (bswap(ph[i].p_filesz)) { \ - assert(size >= bswap(ph[i].p_offset) + bswap(ph[i].p_filesz)); \ - memif->write(bswap(ph[i].p_paddr), bswap(ph[i].p_filesz), (uint8_t*)buf + bswap(ph[i].p_offset)); \ - } \ - zeros.resize(bswap(ph[i].p_memsz) - bswap(ph[i].p_filesz)); \ - memif->write(bswap(ph[i].p_paddr) + bswap(ph[i].p_filesz), bswap(ph[i].p_memsz) - bswap(ph[i].p_filesz), &zeros[0]); \ - } \ - } \ - shdr_t* sh = (shdr_t*)(buf + bswap(eh->e_shoff)); \ - assert(size >= bswap(eh->e_shoff) + bswap(eh->e_shnum)*sizeof(*sh)); \ - assert(bswap(eh->e_shstrndx) < bswap(eh->e_shnum)); \ - assert(size >= bswap(sh[bswap(eh->e_shstrndx)].sh_offset) + bswap(sh[bswap(eh->e_shstrndx)].sh_size)); \ - char *shstrtab = buf + bswap(sh[bswap(eh->e_shstrndx)].sh_offset); \ - unsigned strtabidx = 0, symtabidx = 0; \ - for (unsigned i = 0; i < bswap(eh->e_shnum); i++) { \ - unsigned max_len = bswap(sh[bswap(eh->e_shstrndx)].sh_size) - bswap(sh[i].sh_name); \ - assert(bswap(sh[i].sh_name) < bswap(sh[bswap(eh->e_shstrndx)].sh_size)); \ - assert(strnlen(shstrtab + bswap(sh[i].sh_name), max_len) < max_len); \ - if (bswap(sh[i].sh_type) & SHT_NOBITS) continue; \ - assert(size >= bswap(sh[i].sh_offset) + bswap(sh[i].sh_size)); \ - if (strcmp(shstrtab + bswap(sh[i].sh_name), ".strtab") == 0) \ - strtabidx = i; \ - if (strcmp(shstrtab + bswap(sh[i].sh_name), ".symtab") == 0) \ - symtabidx = i; \ - } \ - if (strtabidx && symtabidx) { \ - char* strtab = buf + bswap(sh[strtabidx].sh_offset); \ - sym_t* sym = (sym_t*)(buf + bswap(sh[symtabidx].sh_offset)); \ - for (unsigned i = 0; i < bswap(sh[symtabidx].sh_size)/sizeof(sym_t); i++) { \ - unsigned max_len = bswap(sh[strtabidx].sh_size) - bswap(sym[i].st_name); \ - assert(bswap(sym[i].st_name) < bswap(sh[strtabidx].sh_size)); \ - assert(strnlen(strtab + bswap(sym[i].st_name), max_len) < max_len); \ - symbols[strtab + bswap(sym[i].st_name)] = bswap(sym[i].st_value); \ - } \ - } \ - } while(0) +#define LOAD_ELF(ehdr_t, phdr_t, shdr_t, sym_t, bswap) \ + do { \ + ehdr_t* eh = (ehdr_t*)buf; \ + phdr_t* ph = (phdr_t*)(buf + bswap(eh->e_phoff)); \ + *entry = bswap(eh->e_entry); \ + assert(size >= bswap(eh->e_phoff) + bswap(eh->e_phnum) * sizeof(*ph)); \ + for (unsigned i = 0; i < bswap(eh->e_phnum); i++) { \ + if (bswap(ph[i].p_type) == PT_LOAD && bswap(ph[i].p_memsz)) { \ + if (bswap(ph[i].p_filesz)) { \ + assert(size >= bswap(ph[i].p_offset) + bswap(ph[i].p_filesz)); \ + memif->write(bswap(ph[i].p_paddr), bswap(ph[i].p_filesz), \ + (uint8_t*)buf + bswap(ph[i].p_offset)); \ + } \ + zeros.resize(bswap(ph[i].p_memsz) - bswap(ph[i].p_filesz)); \ + memif->write(bswap(ph[i].p_paddr) + bswap(ph[i].p_filesz), \ + bswap(ph[i].p_memsz) - bswap(ph[i].p_filesz), &zeros[0]); \ + } \ + } \ + shdr_t* sh = (shdr_t*)(buf + bswap(eh->e_shoff)); \ + assert(size >= bswap(eh->e_shoff) + bswap(eh->e_shnum) * sizeof(*sh)); \ + assert(bswap(eh->e_shstrndx) < bswap(eh->e_shnum)); \ + assert(size >= bswap(sh[bswap(eh->e_shstrndx)].sh_offset) + \ + bswap(sh[bswap(eh->e_shstrndx)].sh_size)); \ + char* shstrtab = buf + bswap(sh[bswap(eh->e_shstrndx)].sh_offset); \ + unsigned strtabidx = 0, symtabidx = 0; \ + for (unsigned i = 0; i < bswap(eh->e_shnum); i++) { \ + unsigned max_len = \ + bswap(sh[bswap(eh->e_shstrndx)].sh_size) - bswap(sh[i].sh_name); \ + assert(bswap(sh[i].sh_name) < bswap(sh[bswap(eh->e_shstrndx)].sh_size)); \ + assert(strnlen(shstrtab + bswap(sh[i].sh_name), max_len) < max_len); \ + if (bswap(sh[i].sh_type) & SHT_NOBITS) continue; \ + assert(size >= bswap(sh[i].sh_offset) + bswap(sh[i].sh_size)); \ + if (strcmp(shstrtab + bswap(sh[i].sh_name), ".strtab") == 0) \ + strtabidx = i; \ + if (strcmp(shstrtab + bswap(sh[i].sh_name), ".symtab") == 0) \ + symtabidx = i; \ + } \ + if (strtabidx && symtabidx) { \ + char* strtab = buf + bswap(sh[strtabidx].sh_offset); \ + sym_t* sym = (sym_t*)(buf + bswap(sh[symtabidx].sh_offset)); \ + for (unsigned i = 0; i < bswap(sh[symtabidx].sh_size) / sizeof(sym_t); \ + i++) { \ + unsigned max_len = \ + bswap(sh[strtabidx].sh_size) - bswap(sym[i].st_name); \ + assert(bswap(sym[i].st_name) < bswap(sh[strtabidx].sh_size)); \ + assert(strnlen(strtab + bswap(sym[i].st_name), max_len) < max_len); \ + symbols[strtab + bswap(sym[i].st_name)] = bswap(sym[i].st_value); \ + } \ + } \ + } while (0) if (IS_ELFLE(*eh64)) { memif->set_target_endianness(memif_endianness_little); |