From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=52830 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PCvtv-0003f1-4c for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:02:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PCvtV-0000er-Un for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:02:00 -0400 Received: from cantor.suse.de ([195.135.220.2]:60258 helo=mx1.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PCvtV-0000e2-MO for qemu-devel@nongnu.org; Mon, 01 Nov 2010 11:01:57 -0400 From: Alexander Graf Date: Mon, 1 Nov 2010 16:01:17 +0100 Message-Id: <1288623713-28062-5-git-send-email-agraf@suse.de> In-Reply-To: <1288623713-28062-1-git-send-email-agraf@suse.de> References: <1288623713-28062-1-git-send-email-agraf@suse.de> Subject: [Qemu-devel] [PATCH 04/40] elf: add section analyzer List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel Developers Cc: Gerd Hoffmann --- hw/elf_ops.h | 32 ++++++++++++++++++++++++++++++-- hw/loader.c | 7 +++++++ hw/loader.h | 3 +++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/hw/elf_ops.h b/hw/elf_ops.h index 5bcba7e..6a042c5 100644 --- a/hw/elf_ops.h +++ b/hw/elf_ops.h @@ -100,13 +100,14 @@ 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, ElfHandlers *handlers) { struct elf_shdr *symtab, *strtab, *shdr_table = NULL; struct elf_sym *syms = NULL; struct syminfo *s; int nsyms, i; char *str = NULL; + char *secstr = NULL; shdr_table = load_at(fd, ehdr->e_shoff, sizeof(struct elf_shdr) * ehdr->e_shnum); @@ -172,6 +173,32 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, if (!str) goto fail; + /* Section string table */ + if (ehdr->e_shstrndx >= ehdr->e_shnum) + goto fail; + strtab = &shdr_table[ehdr->e_shstrndx]; + + secstr = load_at(fd, strtab->sh_offset, strtab->sh_size); + if (!secstr) + goto fail; + + /* External section analyzer */ + for (i = 0; i < ehdr->e_shnum; i++) { + struct elf_shdr *cursec = &shdr_table[i]; + uint8_t *section, *name; + + if (!cursec->sh_size) { + continue; + } + + name = (uint8_t*)&secstr[cursec->sh_name]; + section = load_at(fd, cursec->sh_offset, cursec->sh_size); + handlers->section_fn(handlers->section_opaque, name, cursec->sh_size, + section); + qemu_free(section); + } + + /* Commit */ s = qemu_mallocz(sizeof(*s)); s->lookup_symbol = glue(lookup_symbol, SZ); @@ -185,6 +212,7 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab, fail: qemu_free(syms); qemu_free(str); + qemu_free(secstr); qemu_free(shdr_table); return -1; } @@ -273,7 +301,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, handlers); size = ehdr.e_phnum * sizeof(phdr[0]); lseek(fd, ehdr.e_phoff, SEEK_SET); diff --git a/hw/loader.c b/hw/loader.c index 6a43fda..cf3c1ad 100644 --- a/hw/loader.c +++ b/hw/loader.c @@ -234,6 +234,11 @@ static void elf_default_note(void *opaque, uint8_t *name, uint32_t name_len, { } +static void elf_default_section(void *opaque, uint8_t *name, uint32_t len, + uint8_t *data) +{ +} + static uint64_t elf_default_translate(void *opaque, uint64_t addr) { return addr; @@ -251,6 +256,8 @@ ElfHandlers elf_default_handlers = { .note_opaque = NULL, .header_notify_fn = elf_default_header_notify, .header_notify_opaque = NULL, + .section_fn = elf_default_section, + .section_opaque = NULL, }; diff --git a/hw/loader.h b/hw/loader.h index 090b815..6351644 100644 --- a/hw/loader.h +++ b/hw/loader.h @@ -14,6 +14,9 @@ typedef struct ElfHandlers { void *note_opaque; void (*header_notify_fn)(void *opaque, void *ehdr, int bits); void *header_notify_opaque; + void (*section_fn)(void *opaque, uint8_t *name, uint32_t len, + uint8_t *data); + void *section_opaque; } ElfHandlers; extern ElfHandlers elf_default_handlers; -- 1.6.0.2