diff options
author | Michael Clark <mjc@sifive.com> | 2018-03-03 01:31:12 +1300 |
---|---|---|
committer | Michael Clark <mjc@sifive.com> | 2018-03-07 08:30:28 +1300 |
commit | a2480ffa88a247acbddcf6bb8c4cf69b1af0f48c (patch) | |
tree | adb1e9aabe450c454e057a76ed359e76d5d020c6 /include/hw/elf_ops.h | |
parent | 47ae93cdfedc683c56e19113d516d7ce4971c8e6 (diff) | |
download | qemu-a2480ffa88a247acbddcf6bb8c4cf69b1af0f48c.zip qemu-a2480ffa88a247acbddcf6bb8c4cf69b1af0f48c.tar.gz qemu-a2480ffa88a247acbddcf6bb8c4cf69b1af0f48c.tar.bz2 |
Add symbol table callback interface to load_elf
The RISC-V HTIF (Host Target Interface) console device requires access
to the symbol table to locate the 'tohost' and 'fromhost' symbols.
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Michael Clark <mjc@sifive.com>
Diffstat (limited to 'include/hw/elf_ops.h')
-rw-r--r-- | include/hw/elf_ops.h | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index d192e7e..b6e19e3 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -105,7 +105,7 @@ static int glue(symcmp, SZ)(const void *s0, const void *s1) } static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, - int clear_lsb) + int clear_lsb, symbol_fn_t sym_cb) { struct elf_shdr *symtab, *strtab, *shdr_table = NULL; struct elf_sym *syms = NULL; @@ -133,10 +133,26 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, nsyms = symtab->sh_size / sizeof(struct elf_sym); + /* String table */ + if (symtab->sh_link >= ehdr->e_shnum) { + goto fail; + } + strtab = &shdr_table[symtab->sh_link]; + + str = load_at(fd, strtab->sh_offset, strtab->sh_size); + if (!str) { + goto fail; + } + i = 0; while (i < nsyms) { - if (must_swab) + if (must_swab) { glue(bswap_sym, SZ)(&syms[i]); + } + if (sym_cb) { + sym_cb(str + syms[i].st_name, syms[i].st_info, + syms[i].st_value, syms[i].st_size); + } /* We are only interested in function symbols. Throw everything else away. */ if (syms[i].st_shndx == SHN_UNDEF || @@ -163,15 +179,6 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, } } - /* String table */ - if (symtab->sh_link >= ehdr->e_shnum) - goto fail; - strtab = &shdr_table[symtab->sh_link]; - - str = load_at(fd, strtab->sh_offset, strtab->sh_size); - if (!str) - goto fail; - /* Commit */ s = g_malloc0(sizeof(*s)); s->lookup_symbol = glue(lookup_symbol, SZ); @@ -264,7 +271,8 @@ static int glue(load_elf, SZ)(const char *name, int fd, int must_swab, uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr, int elf_machine, int clear_lsb, int data_swab, - AddressSpace *as, bool load_rom) + AddressSpace *as, bool load_rom, + symbol_fn_t sym_cb) { struct elfhdr ehdr; struct elf_phdr *phdr = NULL, *ph; @@ -329,7 +337,7 @@ static int glue(load_elf, SZ)(const char *name, int fd, if (pentry) *pentry = (uint64_t)(elf_sword)ehdr.e_entry; - glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb); + glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb, sym_cb); size = ehdr.e_phnum * sizeof(phdr[0]); if (lseek(fd, ehdr.e_phoff, SEEK_SET) != ehdr.e_phoff) { |