Re: [Qemu-devel] [PATCH v8 11/23] Add symbol table callback interface to load_elf
On 03/02/2018 02:51 PM, Michael Clark wrote: > 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> Signed-off-by: Michael Clark Reviewed-by: Philippe Mathieu-Daudé > --- > hw/core/loader.c | 18 -- > include/hw/elf_ops.h | 34 +- > include/hw/loader.h | 17 - > 3 files changed, 53 insertions(+), 16 deletions(-) > > diff --git a/hw/core/loader.c b/hw/core/loader.c > index c08f130..1d26c6e 100644 > --- a/hw/core/loader.c > +++ b/hw/core/loader.c > @@ -450,6 +450,20 @@ int load_elf_ram(const char *filename, > int clear_lsb, int data_swab, AddressSpace *as, > bool load_rom) > { > +return load_elf_ram_sym(filename, translate_fn, translate_opaque, > +pentry, lowaddr, highaddr, big_endian, > +elf_machine, clear_lsb, data_swab, as, > +load_rom, NULL); > +} > + > +/* return < 0 if error, otherwise the number of bytes loaded in memory */ > +int load_elf_ram_sym(const char *filename, > + uint64_t (*translate_fn)(void *, uint64_t), > + void *translate_opaque, uint64_t *pentry, > + uint64_t *lowaddr, uint64_t *highaddr, int big_endian, > + int elf_machine, int clear_lsb, int data_swab, > + AddressSpace *as, bool load_rom, symbol_fn_t sym_cb) > +{ > int fd, data_order, target_data_order, must_swab, ret = ELF_LOAD_FAILED; > uint8_t e_ident[EI_NIDENT]; > > @@ -488,11 +502,11 @@ int load_elf_ram(const char *filename, > if (e_ident[EI_CLASS] == ELFCLASS64) { > ret = load_elf64(filename, fd, translate_fn, translate_opaque, > must_swab, > pentry, lowaddr, highaddr, elf_machine, clear_lsb, > - data_swab, as, load_rom); > + data_swab, as, load_rom, sym_cb); > } else { > ret = load_elf32(filename, fd, translate_fn, translate_opaque, > must_swab, > pentry, lowaddr, highaddr, elf_machine, clear_lsb, > - data_swab, as, load_rom); > + data_swab, as, load_rom, sym_cb); > } > > fail: > 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 = _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)([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 = _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
[Qemu-devel] [PATCH v8 11/23] 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 HendersonSigned-off-by: Michael Clark --- hw/core/loader.c | 18 -- include/hw/elf_ops.h | 34 +- include/hw/loader.h | 17 - 3 files changed, 53 insertions(+), 16 deletions(-) diff --git a/hw/core/loader.c b/hw/core/loader.c index c08f130..1d26c6e 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -450,6 +450,20 @@ int load_elf_ram(const char *filename, int clear_lsb, int data_swab, AddressSpace *as, bool load_rom) { +return load_elf_ram_sym(filename, translate_fn, translate_opaque, +pentry, lowaddr, highaddr, big_endian, +elf_machine, clear_lsb, data_swab, as, +load_rom, NULL); +} + +/* return < 0 if error, otherwise the number of bytes loaded in memory */ +int load_elf_ram_sym(const char *filename, + uint64_t (*translate_fn)(void *, uint64_t), + void *translate_opaque, uint64_t *pentry, + uint64_t *lowaddr, uint64_t *highaddr, int big_endian, + int elf_machine, int clear_lsb, int data_swab, + AddressSpace *as, bool load_rom, symbol_fn_t sym_cb) +{ int fd, data_order, target_data_order, must_swab, ret = ELF_LOAD_FAILED; uint8_t e_ident[EI_NIDENT]; @@ -488,11 +502,11 @@ int load_elf_ram(const char *filename, if (e_ident[EI_CLASS] == ELFCLASS64) { ret = load_elf64(filename, fd, translate_fn, translate_opaque, must_swab, pentry, lowaddr, highaddr, elf_machine, clear_lsb, - data_swab, as, load_rom); + data_swab, as, load_rom, sym_cb); } else { ret = load_elf32(filename, fd, translate_fn, translate_opaque, must_swab, pentry, lowaddr, highaddr, elf_machine, clear_lsb, - data_swab, as, load_rom); + data_swab, as, load_rom, sym_cb); } fail: 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 = _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)([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 = _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)(, fd, must_swab, clear_lsb); +glue(load_symbols, SZ)(, 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) { diff --git