From patchwork Mon Feb 26 22:17:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Clark X-Patchwork-Id: 10243875 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id AB547602A0 for ; Mon, 26 Feb 2018 22:28:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8D4022A43C for ; Mon, 26 Feb 2018 22:28:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7F05C2A445; Mon, 26 Feb 2018 22:28:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id BAE6E2A43C for ; Mon, 26 Feb 2018 22:28:34 +0000 (UTC) Received: from localhost ([::1]:33529 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eqRG6-0005Qf-12 for patchwork-qemu-devel@patchwork.kernel.org; Mon, 26 Feb 2018 17:28:34 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49399) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eqR7j-0006Qh-T9 for qemu-devel@nongnu.org; Mon, 26 Feb 2018 17:19:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eqR7h-00057f-7m for qemu-devel@nongnu.org; Mon, 26 Feb 2018 17:19:55 -0500 Received: from mail-pl0-x244.google.com ([2607:f8b0:400e:c01::244]:34032) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1eqR7g-00057X-Vi for qemu-devel@nongnu.org; Mon, 26 Feb 2018 17:19:53 -0500 Received: by mail-pl0-x244.google.com with SMTP id u13so10139987plq.1 for ; Mon, 26 Feb 2018 14:19:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sifive.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=DaifeSz61loz53EG/nzQ0Tdn+FB+6b43jipBJXtKtMY=; b=CYNyD3ieDZUU+j0B6t+pFFoAl1e+ogcWVyEk/zVuH/yK6IZvoZyKMAsaRJLi+DT7vN 1+9sMCe8qS3+DQK02BoRHli6ev2LVoJQ/eXAiu5wzoufjX08rWlbFKQFCk/K/qpYsNYT z1jXcqXjpNmgOe5Haxb26xVjZvpmoZ1rk120CocXBhtAveCP5l1N1FAozGyP0tZxO/kr cNXYQJRsIpHsmpLP5sMaoebBEtkqwxb/Hl2lgRAxjIXpKdUKB7lsdFDA+Smyl7lQWX09 E1/v6grvsssK/Cz+gdxkSjB8nlWIcqFXJXkCg2GDDOXcuUUw/aDDwus/O1amhZaRuoRU TPuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=DaifeSz61loz53EG/nzQ0Tdn+FB+6b43jipBJXtKtMY=; b=H3vWDxVXkEW7ul666R8b/tYVdQf0T8xT6fFPAvZnxIxGrUokXUeHwZjws2GaookNkB 81rsX78K/3iDHPMQDCHsGN+IvHcT8aZ68xVx8McdXSSAcoCAmzEWisHqnRRn06b4q0XV SFdl84KATWoW5BXiKwH4HObCzKy9M0sXGIVR4dtcbZNF3g5XKS3C/5wneuXbPeObL539 n94ghpHJWRVXGaDJTXD4istSK2/BJaEEWy3s86C1aVWclCec3AKRUU/oF8ApYK5Ttg87 LxNIjiuWM1soO6ENdzWtUtDCvK6VjwrZa/S1Sp+m3l29erVD/UEsrFYW43PT+uyWSUfk vQfQ== X-Gm-Message-State: APf1xPDusoldI79/wlVi2VgzP6MG1CXADk+fB7CPyTSJa9QLbeNaRNyj E7FFJp78vTuRSsSH0C+NusgTs+eTdGc= X-Google-Smtp-Source: AH8x224Vabpc0zCx1JpxYHuWon0swX1u26fft/HaOYOss7m6ogTdbbPkT6w0nGzApU+0nbV5Pgkdvg== X-Received: by 2002:a17:902:461:: with SMTP id 88-v6mr12002707ple.88.1519683592020; Mon, 26 Feb 2018 14:19:52 -0800 (PST) Received: from localhost.localdomain (125-237-39-90.jetstream.xtra.co.nz. [125.237.39.90]) by smtp.gmail.com with ESMTPSA id n14sm13592702pfj.154.2018.02.26.14.19.48 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 26 Feb 2018 14:19:51 -0800 (PST) From: Michael Clark To: qemu-devel@nongnu.org Date: Tue, 27 Feb 2018 11:17:48 +1300 Message-Id: <1519683480-33201-12-git-send-email-mjc@sifive.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1519683480-33201-1-git-send-email-mjc@sifive.com> References: <1519683480-33201-1-git-send-email-mjc@sifive.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:400e:c01::244 Subject: [Qemu-devel] [PATCH v7 11/23] Add symbol table callback interface to load_elf X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Bastian Koppelmann , Michael Clark , Palmer Dabbelt , Sagar Karandikar , RISC-V Patches Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 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 --- 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,