diff options
author | Alexey Kardashevskiy <aik@ozlabs.ru> | 2014-02-04 15:04:18 +1100 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2014-03-05 03:06:46 +0100 |
commit | 18674b26788a9e47f1157170234e32ece2044367 (patch) | |
tree | cba0bc536bbd4a924b68997b70b387554831e62c /include | |
parent | 6a2331d12ee7ca9fbcf2a3c22109513ca561a51e (diff) | |
download | qemu-18674b26788a9e47f1157170234e32ece2044367.tar.gz qemu-18674b26788a9e47f1157170234e32ece2044367.tar.bz2 qemu-18674b26788a9e47f1157170234e32ece2044367.zip |
elf-loader: add more return codes
The existing load_elf() just returns -1 if it fails to load ELF. However
it could be smarter than this and tell more about the failure such as
wrong endianness or incompatible platform.
This adds additional return codes for wrong architecture, wrong
endianness and if the image is not ELF at all.
This adds a load_elf_strerror() helper to convert return codes into
string messages.
This fixes handling of what load_elf() returns for s390x, other
callers just check the return value for <0 and this remains unchanged.
Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'include')
-rw-r--r-- | include/hw/elf_ops.h | 19 | ||||
-rw-r--r-- | include/hw/loader.h | 6 |
2 files changed, 20 insertions, 5 deletions
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index acc701e3a4..c6b5129bab 100644 --- a/include/hw/elf_ops.h +++ b/include/hw/elf_ops.h @@ -201,6 +201,7 @@ static int glue(load_elf, SZ)(const char *name, int fd, uint64_t addr, low = (uint64_t)-1, high = 0; uint8_t *data = NULL; char label[128]; + int ret = ELF_LOAD_FAILED; if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr)) goto fail; @@ -211,22 +212,30 @@ static int glue(load_elf, SZ)(const char *name, int fd, switch (elf_machine) { case EM_PPC64: if (EM_PPC64 != ehdr.e_machine) - if (EM_PPC != ehdr.e_machine) + if (EM_PPC != ehdr.e_machine) { + ret = ELF_LOAD_WRONG_ARCH; goto fail; + } break; case EM_X86_64: if (EM_X86_64 != ehdr.e_machine) - if (EM_386 != ehdr.e_machine) + if (EM_386 != ehdr.e_machine) { + ret = ELF_LOAD_WRONG_ARCH; goto fail; + } break; case EM_MICROBLAZE: if (EM_MICROBLAZE != ehdr.e_machine) - if (EM_MICROBLAZE_OLD != ehdr.e_machine) + if (EM_MICROBLAZE_OLD != ehdr.e_machine) { + ret = ELF_LOAD_WRONG_ARCH; goto fail; + } break; default: - if (elf_machine != ehdr.e_machine) + if (elf_machine != ehdr.e_machine) { + ret = ELF_LOAD_WRONG_ARCH; goto fail; + } } if (pentry) @@ -305,5 +314,5 @@ static int glue(load_elf, SZ)(const char *name, int fd, fail: g_free(data); g_free(phdr); - return -1; + return ret; } diff --git a/include/hw/loader.h b/include/hw/loader.h index 91b01224a3..aaf08c377e 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -15,6 +15,12 @@ int get_image_size(const char *filename); int load_image(const char *filename, uint8_t *addr); /* deprecated */ int load_image_targphys(const char *filename, hwaddr, uint64_t max_sz); + +#define ELF_LOAD_FAILED -1 +#define ELF_LOAD_NOT_ELF -2 +#define ELF_LOAD_WRONG_ARCH -3 +#define ELF_LOAD_WRONG_ENDIAN -4 +const char *load_elf_strerror(int error); 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, |