diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2019-02-05 19:39:22 +0000 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2019-02-05 19:39:22 +0000 |
| commit | 3e29da9fd81002a0c03041aaa26dea6d9dd9bd65 (patch) | |
| tree | acd21f31ace26a41b261fe462ae26c782ffb42d2 /include/hw/elf_ops.h | |
| parent | 47994e16b1d66411953623e7c0bf0cdcd50bd507 (diff) | |
| parent | 5ed76a4c63db9295c6c5d67895925810050d4a46 (diff) | |
| download | focaccia-qemu-3e29da9fd81002a0c03041aaa26dea6d9dd9bd65.tar.gz focaccia-qemu-3e29da9fd81002a0c03041aaa26dea6d9dd9bd65.zip | |
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* cpu-exec fixes (Emilio, Laurent) * TCG bugfix in queue.h (Paolo) * high address load for linuxboot (Zhijian) * PVH support (Liam, Stefano) * misc i386 changes (Paolo, Robert, Doug) * configure tweak for openpty (Thomas) * elf2dmp port to Windows (Viktor) * initial improvements to Makefile infrastructure (Yang + GSoC 2013) # gpg: Signature made Tue 05 Feb 2019 17:34:42 GMT # gpg: using RSA key BFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (76 commits) queue: fix QTAILQ_FOREACH_REVERSE_SAFE scsi-generic: Convert from DPRINTF() macro to trace events scsi-disk: Convert from DPRINTF() macro to trace events pc: Use hotplug_handler_(plug|unplug|unplug_request) i386: hvf: Fix smp boot hangs hw/vfio/Makefile.objs: Create new CONFIG_* variables for VFIO core and PCI hw/i2c/Makefile.objs: Create new CONFIG_* variables for EEPROM and ACPI controller hw/tricore/Makefile.objs: Create CONFIG_* for tricore hw/openrisc/Makefile.objs: Create CONFIG_* for openrisc hw/moxie/Makefile.objs: Conditionally build moxie hw/hppa/Makefile.objs: Create CONFIG_* for hppa hw/cris/Makefile.objs: Create CONFIG_* for cris hw/alpha/Makefile.objs: Create CONFIG_* for alpha hw/sparc64/Makefile.objs: Create CONFIG_* for sparc64 hw/riscv/Makefile.objs: Create CONFIG_* for riscv boards hw/nios2/Makefile.objs: Conditionally build nios2 hw/xtensa/Makefile.objs: Build xtensa_sim and xtensa_fpga conditionally hw/lm32/Makefile.objs: Conditionally build lm32 and milkmyst hw/sparc/Makefile.objs: CONFIG_* for sun4m and leon3 created hw/s390/Makefile.objs: Create new CONFIG_* variables for s390x boards and devices ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org> # Conflicts: # qemu-deprecated.texi
Diffstat (limited to 'include/hw/elf_ops.h')
| -rw-r--r-- | include/hw/elf_ops.h | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index e2cb675195..690f9238c8 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -265,7 +265,53 @@ fail: return ret; } +/* + * Given 'nhdr', a pointer to a range of ELF Notes, search through them + * for a note matching type 'elf_note_type' and return a pointer to + * the matching ELF note. + */ +static struct elf_note *glue(get_elf_note_type, SZ)(struct elf_note *nhdr, + elf_word note_size, + elf_word phdr_align, + elf_word elf_note_type) +{ + elf_word nhdr_size = sizeof(struct elf_note); + elf_word elf_note_entry_offset = 0; + elf_word note_type; + elf_word nhdr_namesz; + elf_word nhdr_descsz; + + if (nhdr == NULL) { + return NULL; + } + + note_type = nhdr->n_type; + while (note_type != elf_note_type) { + nhdr_namesz = nhdr->n_namesz; + nhdr_descsz = nhdr->n_descsz; + + elf_note_entry_offset = nhdr_size + + QEMU_ALIGN_UP(nhdr_namesz, phdr_align) + + QEMU_ALIGN_UP(nhdr_descsz, phdr_align); + + /* + * If the offset calculated in this iteration exceeds the + * supplied size, we are done and no matching note was found. + */ + if (elf_note_entry_offset > note_size) { + return NULL; + } + + /* skip to the next ELF Note entry */ + nhdr = (void *)nhdr + elf_note_entry_offset; + note_type = nhdr->n_type; + } + + return nhdr; +} + static int glue(load_elf, SZ)(const char *name, int fd, + uint64_t (*elf_note_fn)(void *, void *, bool), uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, int must_swab, uint64_t *pentry, @@ -496,8 +542,39 @@ static int glue(load_elf, SZ)(const char *name, int fd, high = addr + mem_size; data = NULL; + + } else if (ph->p_type == PT_NOTE && elf_note_fn) { + struct elf_note *nhdr = NULL; + + file_size = ph->p_filesz; /* Size of the range of ELF notes */ + data = g_malloc0(file_size); + if (ph->p_filesz > 0) { + if (lseek(fd, ph->p_offset, SEEK_SET) < 0) { + goto fail; + } + if (read(fd, data, file_size) != file_size) { + goto fail; + } + } + + /* + * Search the ELF notes to find one with a type matching the + * value passed in via 'translate_opaque' + */ + nhdr = (struct elf_note *)data; + assert(translate_opaque != NULL); + nhdr = glue(get_elf_note_type, SZ)(nhdr, file_size, ph->p_align, + *(uint64_t *)translate_opaque); + if (nhdr != NULL) { + bool is64 = + sizeof(struct elf_note) == sizeof(struct elf64_note); + elf_note_fn((void *)nhdr, (void *)&ph->p_align, is64); + } + g_free(data); + data = NULL; } } + g_free(phdr); if (lowaddr) *lowaddr = (uint64_t)(elf_sword)low; |