From: Nathan Froyd <froydnj@codesourcery.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 1/6] sysemu: add section_callback argument to ELF loader
Date: Mon, 3 Aug 2009 07:45:06 -0700 [thread overview]
Message-ID: <1249310711-8873-2-git-send-email-froydnj@codesourcery.com> (raw)
In-Reply-To: <1249310711-8873-1-git-send-email-froydnj@codesourcery.com>
Some targets indicate properties of the program with special sections in
the ELF file--MIPS in particular. This infrastructure is useful for
grovelling through those sections.
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com>
---
elf_ops.h | 34 +++++++++++++++++++++++++++++++---
loader.c | 19 ++++++++++++++-----
sysemu.h | 5 +++++
3 files changed, 50 insertions(+), 8 deletions(-)
diff --git a/elf_ops.h b/elf_ops.h
index 699651c..0acbcc7 100644
--- a/elf_ops.h
+++ b/elf_ops.h
@@ -98,7 +98,13 @@ static int glue(symcmp, SZ)(const void *s0, const void *s1)
: ((sym0->st_value > sym1->st_value) ? 1 : 0);
}
-static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
+/* Load function symbols for later groveling. If SECTION_CALLBACK is
+ non-NULL, it will be called with information about each section in
+ the binary. This interface enables to the caller to mine the binary
+ for useful information about the ABI, such as whether the CPU chosen is
+ compatible with the binary. */
+static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
+ section_callback_t section_callback)
{
struct elf_shdr *symtab, *strtab, *shdr_table = NULL;
struct elf_sym *syms = NULL;
@@ -117,6 +123,27 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
}
}
+ /* Permit machines to grovel through the ELF file looking for
+ interesting bits of information. */
+ if (section_callback && ehdr->e_shstrndx != SHN_UNDEF) {
+ char *shstr = NULL;
+ struct elf_shdr *shstrtab = &shdr_table[ehdr->e_shstrndx];
+
+ shstr = load_at(fd, shstrtab->sh_offset, shstrtab->sh_size);
+ if (!shstr)
+ goto fail_callback;
+
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ struct elf_shdr *sh = shdr_table + i;
+
+ section_callback(fd, must_swab, sh->sh_size, sh->sh_offset,
+ &shstr[sh->sh_name]);
+ }
+
+ fail_callback:
+ free (shstr);
+ }
+
symtab = glue(find_section, SZ)(shdr_table, ehdr->e_shnum, SHT_SYMTAB);
if (!symtab)
goto fail;
@@ -179,7 +206,8 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
static int glue(load_elf, SZ)(int fd, int64_t address_offset,
int must_swab, uint64_t *pentry,
- uint64_t *lowaddr, uint64_t *highaddr)
+ uint64_t *lowaddr, uint64_t *highaddr,
+ section_callback_t section_callback)
{
struct elfhdr ehdr;
struct elf_phdr *phdr = NULL, *ph;
@@ -213,7 +241,7 @@ static int glue(load_elf, SZ)(int fd, int64_t address_offset,
if (pentry)
*pentry = (uint64_t)(elf_sword)ehdr.e_entry;
- glue(load_symbols, SZ)(&ehdr, fd, must_swab);
+ glue(load_symbols, SZ)(&ehdr, fd, must_swab, section_callback);
size = ehdr.e_phnum * sizeof(phdr[0]);
lseek(fd, ehdr.e_phoff, SEEK_SET);
diff --git a/loader.c b/loader.c
index 0cbcf9c..6f025a9 100644
--- a/loader.c
+++ b/loader.c
@@ -305,9 +305,10 @@ static void *load_at(int fd, int offset, int size)
#define SZ 64
#include "elf_ops.h"
-/* return < 0 if error, otherwise the number of bytes loaded in memory */
-int load_elf(const char *filename, int64_t address_offset,
- uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr)
+int load_elf_introspect(const char *filename, int64_t address_offset,
+ uint64_t *pentry, uint64_t *lowaddr,
+ uint64_t *highaddr,
+ section_callback_t section_callback)
{
int fd, data_order, host_data_order, must_swab, ret;
uint8_t e_ident[EI_NIDENT];
@@ -342,10 +343,10 @@ int load_elf(const char *filename, int64_t address_offset,
lseek(fd, 0, SEEK_SET);
if (e_ident[EI_CLASS] == ELFCLASS64) {
ret = load_elf64(fd, address_offset, must_swab, pentry,
- lowaddr, highaddr);
+ lowaddr, highaddr, section_callback);
} else {
ret = load_elf32(fd, address_offset, must_swab, pentry,
- lowaddr, highaddr);
+ lowaddr, highaddr, section_callback);
}
close(fd);
@@ -356,6 +357,14 @@ int load_elf(const char *filename, int64_t address_offset,
return -1;
}
+/* return < 0 if error, otherwise the number of bytes loaded in memory */
+int load_elf(const char *filename, int64_t address_offset,
+ uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr)
+{
+ return load_elf_introspect (filename, address_offset, pentry, lowaddr,
+ highaddr, NULL);
+}
+
static void bswap_uboot_header(uboot_image_header_t *hdr)
{
#ifndef HOST_WORDS_BIGENDIAN
diff --git a/sysemu.h b/sysemu.h
index 6af88d8..b26cf40 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -241,6 +241,11 @@ int load_image(const char *filename, uint8_t *addr); /* deprecated */
int load_image_targphys(const char *filename, target_phys_addr_t, int max_sz);
int load_elf(const char *filename, int64_t address_offset,
uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr);
+typedef void (*section_callback_t)(int fd, int must_swab,
+ uint64_t size, uint64_t offset, char *name);
+int load_elf_introspect(const char *filename, int64_t address_offset,
+ uint64_t *pentry, uint64_t *lowaddr,
+ uint64_t *highaddr, section_callback_t callback);
int load_aout(const char *filename, target_phys_addr_t addr, int max_sz);
int load_uimage(const char *filename, target_ulong *ep, target_ulong *loadaddr,
int *is_linux);
--
1.6.3.2
next prev parent reply other threads:[~2009-08-03 14:52 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-03 14:45 [Qemu-devel] [PATCH 0/6] target-mips: add MDI semihosting, v2 Nathan Froyd
2009-08-03 14:45 ` Nathan Froyd [this message]
2009-08-03 14:45 ` [Qemu-devel] [PATCH 2/6] add softmmu_target_strlen Nathan Froyd
2009-08-03 14:45 ` [Qemu-devel] [PATCH 3/6] add implementation of MIPS semihosting Nathan Froyd
2009-08-03 14:45 ` [Qemu-devel] [PATCH 4/6] target-mips: add MDI semihosting support to mipssim machine Nathan Froyd
2009-08-03 14:45 ` [Qemu-devel] [PATCH 5/6] enable --semihosting option for TARGET_MIPS Nathan Froyd
2009-08-03 14:45 ` [Qemu-devel] [PATCH 6/6] gdbstub: add qSymbol handling " Nathan Froyd
-- strict thread matches above, loose matches on Subject: below --
2009-07-17 20:33 [Qemu-devel] [PATCH 0/6] target-mips: add MDI semihosting Nathan Froyd
2009-07-17 20:33 ` [Qemu-devel] [PATCH 1/6] sysemu: add section_callback argument to ELF loader Nathan Froyd
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=1249310711-8873-2-git-send-email-froydnj@codesourcery.com \
--to=froydnj@codesourcery.com \
--cc=qemu-devel@nongnu.org \
/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).