qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Michael Clark <mjc@sifive.com>
To: qemu-devel@nongnu.org
Cc: Michael Clark <mjc@sifive.com>,
	Palmer Dabbelt <palmer@sifive.com>,
	Sagar Karandikar <sagark@eecs.berkeley.edu>,
	Bastian Koppelmann <kbastian@mail.uni-paderborn.de>,
	RISC-V Patches <patches@groups.riscv.org>
Subject: [Qemu-devel] [PATCH v7 11/23] Add symbol table callback interface to load_elf
Date: Tue, 27 Feb 2018 11:17:48 +1300	[thread overview]
Message-ID: <1519683480-33201-12-git-send-email-mjc@sifive.com> (raw)
In-Reply-To: <1519683480-33201-1-git-send-email-mjc@sifive.com>

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>
---
 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 91669d6..80b69ea 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 = &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) {
diff --git a/include/hw/loader.h b/include/hw/loader.h
index 5edbe02..7b05e8b 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -64,7 +64,7 @@ int load_image_gzipped(const char *filename, hwaddr addr, uint64_t max_sz);
 #define ELF_LOAD_WRONG_ENDIAN -4
 const char *load_elf_strerror(int error);
 
-/** load_elf_ram:
+/** load_elf_ram_sym:
  * @filename: Path of ELF file
  * @translate_fn: optional function to translate load addresses
  * @translate_opaque: opaque data passed to @translate_fn
@@ -81,6 +81,7 @@ const char *load_elf_strerror(int error);
  * @as: The AddressSpace to load the ELF to. The value of address_space_memory
  *      is used if nothing is supplied here.
  * @load_rom : Load ELF binary as ROM
+ * @sym_cb: Callback function for symbol table entries
  *
  * Load an ELF file's contents to the emulated system's address space.
  * Clients may optionally specify a callback to perform address
@@ -93,6 +94,20 @@ const char *load_elf_strerror(int error);
  * If @elf_machine is EM_NONE then the machine type will be read from the
  * ELF header and no checks will be carried out against the machine type.
  */
+typedef void (*symbol_fn_t)(const char *st_name, int st_info,
+                            uint64_t st_value, uint64_t st_size);
+
+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);
+
+/** load_elf_ram:
+ * Same as load_elf_ram_sym(), but doesn't allow the caller to specify a
+ * symbol callback function
+ */
 int load_elf_ram(const char *filename,
                  uint64_t (*translate_fn)(void *, uint64_t),
                  void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
-- 
2.7.0

  parent reply	other threads:[~2018-02-26 22:19 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-26 22:17 [Qemu-devel] [PATCH v7 00/23] RISC-V QEMU Port Submission Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 01/23] RISC-V Maintainers Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 02/23] RISC-V ELF Machine Definition Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 03/23] RISC-V CPU Core Definition Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 04/23] RISC-V Disassembler Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 05/23] RISC-V CPU Helpers Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 06/23] RISC-V FPU Support Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 07/23] RISC-V GDB Stub Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 08/23] RISC-V TCG Code Generation Michael Clark
2018-02-27 14:06   ` Bastian Koppelmann
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 09/23] RISC-V Physical Memory Protection Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 10/23] RISC-V Linux User Emulation Michael Clark
2018-02-26 22:17 ` Michael Clark [this message]
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 12/23] RISC-V HTIF Console Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 13/23] RISC-V HART Array Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 14/23] SiFive RISC-V CLINT Block Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 15/23] SiFive RISC-V PLIC Block Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 16/23] RISC-V Spike Machines Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 17/23] SiFive RISC-V Test Finisher Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 18/23] RISC-V VirtIO Machine Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 19/23] SiFive RISC-V UART Device Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 20/23] SiFive RISC-V PRCI Block Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 21/23] SiFive Freedom E300 RISC-V Machine Michael Clark
2018-02-26 22:17 ` [Qemu-devel] [PATCH v7 22/23] SiFive Freedom U500 " Michael Clark
2018-02-26 22:18 ` [Qemu-devel] [PATCH v7 23/23] RISC-V Build Infrastructure Michael Clark
2018-02-26 23:02   ` Eric Blake
2018-02-26 22:24 ` [Qemu-devel] [PATCH v7 00/23] RISC-V QEMU Port Submission Michael Clark
2018-02-26 23:05   ` Eric Blake
2018-02-26 22:45 ` no-reply
2018-02-26 22:57 ` no-reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1519683480-33201-12-git-send-email-mjc@sifive.com \
    --to=mjc@sifive.com \
    --cc=kbastian@mail.uni-paderborn.de \
    --cc=palmer@sifive.com \
    --cc=patches@groups.riscv.org \
    --cc=qemu-devel@nongnu.org \
    --cc=sagark@eecs.berkeley.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).