qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Peter Crosthwaite <crosthwaitepeter@gmail.com>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org,
	Peter Crosthwaite <crosthwaite.peter@gmail.com>,
	sw@weilnetz.de, Andrew.Baumann@microsoft.com,
	alistair.francis@xilinx.com, sridhar_kulk@yahoo.com,
	qemu-arm@nongnu.org, pbonzini@redhat.com, piotr.krol@3mdeb.com
Subject: [Qemu-devel] [PATCH v2 15/18] loader: add API to load elf header
Date: Tue,  1 Mar 2016 22:56:19 -0800	[thread overview]
Message-ID: <368ecb8c07deff822a1115b4df3e33e4e4a35524.1456901522.git.crosthwaite.peter@gmail.com> (raw)
In-Reply-To: <cover.1456901522.git.crosthwaite.peter@gmail.com>
In-Reply-To: <cover.1456901522.git.crosthwaite.peter@gmail.com>

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.peter@gmail.com>
---
Changed since v1 (PMM review):
Add filname to error messages
Remove unneeded lseek()
Add doc comment

 hw/core/loader.c    | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/loader.h | 13 +++++++++++++
 2 files changed, 68 insertions(+)

diff --git a/hw/core/loader.c b/hw/core/loader.c
index 3a57415..7d5e3a9 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -332,6 +332,61 @@ 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_local[EI_NIDENT];
+    uint8_t *e_ident;
+    size_t hdr_size, off;
+    bool is64l;
+
+    if (!hdr) {
+        hdr = e_ident_local;
+    }
+    e_ident = hdr;
+
+    fd = open(filename, O_RDONLY | O_BINARY);
+    if (fd < 0) {
+        error_setg_errno(errp, errno, "Failed to open file: %s", filename);
+        return;
+    }
+    if (read(fd, hdr, EI_NIDENT) != EI_NIDENT) {
+        error_setg_errno(errp, errno, "Failed to read file: %s", filename);
+        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;
+    }
+
+    off = EI_NIDENT;
+    while (hdr != e_ident_local && off < hdr_size) {
+        size_t br = read(fd, hdr + off, hdr_size - off);
+        switch (br) {
+        case 0:
+            error_setg(errp, "File too short: %s", filename);
+            goto fail;
+        case -1:
+            error_setg_errno(errp, errno, "Failed to read file: %s",
+                             filename);
+            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..a626c9b 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -36,6 +36,19 @@ 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);
+
+/** load_elf_hdr:
+ * @filename: Path of ELF file
+ * @hdr: Buffer to populate with header data. Header data will not be
+ * filled if set to NULL.
+ * @is64: Set to true if the ELF is 64bit. Ignored if set to NULL
+ * @errp: Populated with an error in failure cases
+ *
+ * Inspect as ELF file's header. Read its full header contents into a
+ * buffer and/or determine if the ELF is 64bit.
+ */
+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

  parent reply	other threads:[~2016-03-02  6:57 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-02  6:56 [Qemu-devel] [PATCH v2 00/18] ARM big-endian and setend support Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 01/18] linux-user: arm: fix coding style for some linux-user signal functions Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 02/18] linux-user: arm: pass env to get_user_code_* Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 03/18] target-arm: implement SCTLR.B, drop bswap_code Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 04/18] target-arm: cpu: Move cpu_is_big_endian to header Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 05/18] arm: cpu: handle BE32 user-mode as BE Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 06/18] linux-user: arm: set CPSR.E/SCTLR.E0E correctly for BE mode Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 07/18] linux-user: arm: handle CPSR.E correctly in strex emulation Peter Crosthwaite
2016-03-03 15:09   ` Peter Maydell
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 08/18] target-arm: implement SCTLR.EE Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 09/18] target-arm: pass DisasContext to gen_aa32_ld*/st* Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 10/18] target-arm: introduce disas flag for endianness Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 11/18] target-arm: a64: Add endianness support Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 12/18] target-arm: introduce tbflag for endianness Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 13/18] target-arm: implement setend Peter Crosthwaite
2016-03-02  6:56 ` Peter Crosthwaite [this message]
2016-03-03 15:24   ` [Qemu-devel] [PATCH v2 15/18] loader: add API to load elf header Peter Maydell
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 16/18] loader: load_elf(): Add doc comment Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 17/18] loader: Add data swap option to load-elf Peter Crosthwaite
2016-03-02  6:56 ` [Qemu-devel] [PATCH v2 18/18] arm: boot: Support big-endian elfs Peter Crosthwaite
2016-03-03 15:23   ` Peter Maydell
2016-03-03 15:25 ` [Qemu-devel] [PATCH v2 00/18] ARM big-endian and setend support Peter Maydell
2016-03-03 15:40   ` Paolo Bonzini
     [not found] ` <130944d3702e4184b48ff43096aabfeb24f0bdf3.1456901522.git.crosthwaite.peter@gmail.com>
2016-03-03 15:27   ` [Qemu-devel] [PATCH v2 14/18] target-arm: implement BE32 mode in system emulation Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=368ecb8c07deff822a1115b4df3e33e4e4a35524.1456901522.git.crosthwaite.peter@gmail.com \
    --to=crosthwaitepeter@gmail.com \
    --cc=Andrew.Baumann@microsoft.com \
    --cc=alistair.francis@xilinx.com \
    --cc=crosthwaite.peter@gmail.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=piotr.krol@3mdeb.com \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=sridhar_kulk@yahoo.com \
    --cc=sw@weilnetz.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).