Add an API to load an elf header header from a file. Populates a buffer with the header contents, as well as a boolean for whether the elf is 64b or not. Both arguments are optional.
Signed-off-by: Peter Crosthwaite <crosthwaite.pe...@gmail.com> --- hw/core/loader.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ include/hw/loader.h | 1 + 2 files changed, 49 insertions(+) diff --git a/hw/core/loader.c b/hw/core/loader.c index 6b69852..28da8e2 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -331,6 +331,54 @@ const char *load_elf_strerror(int error) } } +void load_elf_hdr(const char *filename, void *hdr, bool *is64, Error **errp) +{ + int fd; + uint8_t e_ident[EI_NIDENT]; + size_t hdr_size, off = 0; + bool is64l; + + fd = open(filename, O_RDONLY | O_BINARY); + if (fd < 0) { + error_setg_errno(errp, errno, "Fail to open file"); + return; + } + if (read(fd, e_ident, sizeof(e_ident)) != sizeof(e_ident)) { + error_setg_errno(errp, errno, "Fail to read file"); + goto fail; + } + if (e_ident[0] != ELFMAG0 || + e_ident[1] != ELFMAG1 || + e_ident[2] != ELFMAG2 || + e_ident[3] != ELFMAG3) { + error_setg(errp, "Bad ELF magic"); + goto fail; + } + + is64l = e_ident[EI_CLASS] == ELFCLASS64; + hdr_size = is64l ? sizeof(Elf64_Ehdr) : sizeof(Elf32_Ehdr); + if (is64) { + *is64 = is64l; + } + + lseek(fd, 0, SEEK_SET); + while (hdr && off < hdr_size) { + size_t br = read(fd, hdr + off, hdr_size - off); + switch (br) { + case 0: + error_setg(errp, "File too short"); + goto fail; + case -1: + error_setg_errno(errp, errno, "Failed to read file"); + goto fail; + } + off += br; + } + +fail: + close(fd); +} + /* return < 0 if error, otherwise the number of bytes loaded in memory */ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr, diff --git a/include/hw/loader.h b/include/hw/loader.h index f7b43ab..33067f8 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -36,6 +36,7 @@ int load_elf(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); +void load_elf_hdr(const char *filename, void *hdr, bool *is64, Error **errp); int load_aout(const char *filename, hwaddr addr, int max_sz, int bswap_needed, hwaddr target_page_size); int load_uimage(const char *filename, hwaddr *ep, -- 1.9.1