From patchwork Wed Jan 22 05:20:40 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Kardashevskiy X-Patchwork-Id: 313126 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id BDAFA2C008F for ; Wed, 22 Jan 2014 16:21:39 +1100 (EST) Received: from localhost ([::1]:33653 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W5qFs-0007al-05 for incoming@patchwork.ozlabs.org; Wed, 22 Jan 2014 00:21:36 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37622) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W5qFK-0006ui-9r for qemu-devel@nongnu.org; Wed, 22 Jan 2014 00:21:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1W5qFB-0007UK-V2 for qemu-devel@nongnu.org; Wed, 22 Jan 2014 00:21:02 -0500 Received: from e23smtp09.au.ibm.com ([202.81.31.142]:60522) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1W5qFB-0007O3-8o for qemu-devel@nongnu.org; Wed, 22 Jan 2014 00:20:53 -0500 Received: from /spool/local by e23smtp09.au.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 22 Jan 2014 15:20:47 +1000 Received: from d23dlp03.au.ibm.com (202.81.31.214) by e23smtp09.au.ibm.com (202.81.31.206) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 22 Jan 2014 15:20:46 +1000 Received: from d23relay04.au.ibm.com (d23relay04.au.ibm.com [9.190.234.120]) by d23dlp03.au.ibm.com (Postfix) with ESMTP id C267E3578053; Wed, 22 Jan 2014 16:20:45 +1100 (EST) Received: from d23av02.au.ibm.com (d23av02.au.ibm.com [9.190.235.138]) by d23relay04.au.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id s0M51gtJ50856102; Wed, 22 Jan 2014 16:01:43 +1100 Received: from d23av02.au.ibm.com (localhost [127.0.0.1]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id s0M5Kinx021879; Wed, 22 Jan 2014 16:20:45 +1100 Received: from ozlabs.au.ibm.com (ozlabs.au.ibm.com [9.190.163.12]) by d23av02.au.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id s0M5Kir4021876; Wed, 22 Jan 2014 16:20:44 +1100 Received: from bran.ozlabs.ibm.com (haven.au.ibm.com [9.190.164.82]) by ozlabs.au.ibm.com (Postfix) with ESMTP id A7C06A03B1; Wed, 22 Jan 2014 16:20:44 +1100 (EST) Received: from ka1.ozlabs.ibm.com (ka1.ozlabs.ibm.com [10.61.145.11]) by bran.ozlabs.ibm.com (Postfix) with ESMTP id 5268616AB3D; Wed, 22 Jan 2014 16:20:44 +1100 (EST) From: Alexey Kardashevskiy To: qemu-devel@nongnu.org Date: Wed, 22 Jan 2014 16:20:40 +1100 Message-Id: <1390368041-2184-4-git-send-email-aik@ozlabs.ru> X-Mailer: git-send-email 1.8.4.rc4 In-Reply-To: <1390368041-2184-1-git-send-email-aik@ozlabs.ru> References: <1390368041-2184-1-git-send-email-aik@ozlabs.ru> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14012205-3568-0000-0000-000004D4EC7E X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] X-Received-From: 202.81.31.142 Cc: Alexey Kardashevskiy , Peter Maydell , qemu-ppc@nongnu.org, Alexander Graf Subject: [Qemu-devel] [PATCH 3/4] elf-loader: add more return codes X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 fixes handling of what load_elf() returns for s390x and moxie architectures, other callers just check the return value for <0 and this remains unchanged. Signed-off-by: Alexey Kardashevskiy --- hw/core/loader.c | 12 ++++++------ hw/s390x/ipl.c | 4 ++-- include/hw/elf_ops.h | 19 ++++++++++++++----- include/hw/loader.h | 5 +++++ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/hw/core/loader.c b/hw/core/loader.c index 0634bee..f510260 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -289,7 +289,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) { - int fd, data_order, target_data_order, must_swab, ret; + int fd, data_order, target_data_order, must_swab, ret = ELF_LOAD_FAILED; uint8_t e_ident[EI_NIDENT]; fd = open(filename, O_RDONLY | O_BINARY); @@ -302,8 +302,10 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), if (e_ident[0] != ELFMAG0 || e_ident[1] != ELFMAG1 || e_ident[2] != ELFMAG2 || - e_ident[3] != ELFMAG3) + e_ident[3] != ELFMAG3) { + ret = ELF_LOAD_NOT_ELF; goto fail; + } #ifdef HOST_WORDS_BIGENDIAN data_order = ELFDATA2MSB; #else @@ -317,6 +319,7 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), } if (target_data_order != e_ident[EI_DATA]) { + ret = ELF_LOAD_WRONG_ENDIAN; goto fail; } @@ -329,12 +332,9 @@ int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t), pentry, lowaddr, highaddr, elf_machine, clear_lsb); } - close(fd); - return ret; - fail: close(fd); - return -1; + return ret; } static void bswap_uboot_header(uboot_image_header_t *hdr) diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index 1a6397b..cff77ad 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -97,10 +97,10 @@ static int s390_ipl_init(SysBusDevice *dev) } else { kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0); - if (kernel_size == -1) { + if (kernel_size < 0) { kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); } - if (kernel_size == -1) { + if (kernel_size < 0) { fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel); return -1; } diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h index acc701e..b7e7b36 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; @@ -210,23 +211,31 @@ 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_PPC64 != 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 7a23d6b..6c9d762 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -8,6 +8,11 @@ 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 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,