@@ -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);
@@ -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,
};
@@ -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;