]> www.infradead.org Git - users/dwmw2/qemu.git/commitdiff
Compile loader only once
authorBlue Swirl <blauwirbel@gmail.com>
Sun, 20 Sep 2009 14:58:02 +0000 (14:58 +0000)
committerBlue Swirl <blauwirbel@gmail.com>
Sun, 20 Sep 2009 14:58:02 +0000 (14:58 +0000)
Callers must pass ELF machine, byte swapping and symbol LSB clearing
information to ELF loader. A.out loader needs page size information, pass
that too as a parameter.

Extract prototypes to a separate file. Move loader.[ch] and elf_ops.h under hw.

Adjust callers. Also use target_phys_addr_t instead of target_ulong for
addresses: loader addresses aren't virtual.

Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
36 files changed:
Makefile.hw
Makefile.target
disas.h
hw/an5206.c
hw/arm_boot.c
hw/armv7m.c
hw/axis_dev88.c
hw/dummy_m68k.c
hw/elf_ops.h [moved from elf_ops.h with 93% similarity]
hw/etraxfs.c
hw/loader.c [moved from loader.c with 90% similarity]
hw/loader.h [new file with mode: 0644]
hw/mcf5208.c
hw/mips_jazz.c
hw/mips_malta.c
hw/mips_mipssim.c
hw/mips_r4k.c
hw/nseries.c
hw/palm.c
hw/pc.c
hw/petalogix_s3adsp1800_mmu.c
hw/ppc.c
hw/ppc405_boards.c
hw/ppc440_bamboo.c
hw/ppc_newworld.c
hw/ppc_oldworld.c
hw/ppc_prep.c
hw/ppce500_mpc8544ds.c
hw/r2d.c
hw/shix.c
hw/smbios.c
hw/sun4m.c
hw/sun4u.c
hw/tc58128.c
linux-user/elfload.c
sysemu.h

index 11227bf873cd0ca99a40187e100cfc64060df37a..cb9c9a4a8502a1c7fef943267dcb277fdb89858b 100644 (file)
@@ -11,6 +11,7 @@ VPATH=$(SRC_PATH):$(SRC_PATH)/hw
 QEMU_CFLAGS+=-I.. -I$(SRC_PATH)/fpu
 
 obj-y =
+obj-y += loader.o
 obj-y += virtio.o
 obj-y += fw_cfg.o
 obj-y += watchdog.o
index d9e98fe3c5891c07c6e0a1c93ee60039ef924efb..bc3998a1de14ccfa438ddcd712cd03066798938a 100644 (file)
@@ -155,7 +155,7 @@ endif
 # System emulator target
 ifdef CONFIG_SOFTMMU
 
-obj-y = vl.o monitor.o pci.o loader.o isa_mmio.o machine.o \
+obj-y = vl.o monitor.o pci.o isa_mmio.o machine.o \
         gdbstub.o gdbstub-xml.o msix.o ioport.o
 # virtio has to be here due to weird dependency between PCI and virtio-net.
 # need to fix this properly
diff --git a/disas.h b/disas.h
index 0789b57218600a64d6ec16d099d7ca79bdfa81e2..06abab21ebc6032763747b1d06c62aa24fde7cd2 100644 (file)
--- a/disas.h
+++ b/disas.h
@@ -3,6 +3,7 @@
 
 #include "qemu-common.h"
 
+#ifdef NEED_CPU_H
 /* Disassemble this for me please... (debugging). */
 void disas(FILE *out, void *code, unsigned long size);
 void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
@@ -15,12 +16,13 @@ void monitor_disas(Monitor *mon, CPUState *env,
 
 /* Look up symbol for debugging purpose.  Returns "" if unknown. */
 const char *lookup_symbol(target_ulong orig_addr);
+#endif
 
 struct syminfo;
 struct elf32_sym;
 struct elf64_sym;
 
-typedef const char *(*lookup_symbol_t)(struct syminfo *s, target_ulong orig_addr);
+typedef const char *(*lookup_symbol_t)(struct syminfo *s, target_phys_addr_t orig_addr);
 
 struct syminfo {
     lookup_symbol_t lookup_symbol;
index d417d923b95d420df83e45029493376b22e8efa3..a4b83b0f44571cdd4287d6e21916e91c78dbead7 100644 (file)
@@ -11,6 +11,8 @@
 #include "mcf.h"
 #include "sysemu.h"
 #include "boards.h"
+#include "loader.h"
+#include "elf.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 #define AN5206_MBAR_ADDR 0x10000000
@@ -35,7 +37,7 @@ static void an5206_init(ram_addr_t ram_size,
     CPUState *env;
     int kernel_size;
     uint64_t elf_entry;
-    target_ulong entry;
+    target_phys_addr_t entry;
 
     if (!cpu_model)
         cpu_model = "m5206";
@@ -66,7 +68,8 @@ static void an5206_init(ram_addr_t ram_size,
         exit(1);
     }
 
-    kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
+    kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
+                           1, ELF_MACHINE, 0);
     entry = elf_entry;
     if (kernel_size < 0) {
         kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
index 35f0130db111504ddc65d3fb3c5acc91fdb5f17a..a8a38c5a369350fd8ba49bf8ceadb0ea86be0741 100644 (file)
@@ -10,6 +10,8 @@
 #include "hw.h"
 #include "arm-misc.h"
 #include "sysemu.h"
+#include "loader.h"
+#include "elf.h"
 
 #define KERNEL_ARGS_ADDR 0x100
 #define KERNEL_LOAD_ADDR 0x00010000
@@ -191,7 +193,8 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
     int n;
     int is_linux = 0;
     uint64_t elf_entry;
-    target_ulong entry;
+    target_phys_addr_t entry;
+    int big_endian;
 
     /* Load the kernel.  */
     if (!info->kernel_filename) {
@@ -206,8 +209,15 @@ void arm_load_kernel(CPUState *env, struct arm_boot_info *info)
         qemu_register_reset(main_cpu_reset, env);
     }
 
+#ifdef TARGET_WORDS_BIGENDIAN
+    big_endian = 1;
+#else
+    big_endian = 0;
+#endif
+
     /* Assume that raw images are linux kernels, and ELF images are not.  */
-    kernel_size = load_elf(info->kernel_filename, 0, &elf_entry, NULL, NULL);
+    kernel_size = load_elf(info->kernel_filename, 0, &elf_entry, NULL, NULL,
+                           big_endian, ELF_MACHINE, 1);
     entry = elf_entry;
     if (kernel_size < 0) {
         kernel_size = load_uimage(info->kernel_filename, &entry, NULL,
index 059a356e216553c8853e0394c13f3aeac8a90f16..a96288d0ddf08f27334f746f6e799d9813aff22c 100644 (file)
@@ -10,6 +10,8 @@
 #include "sysbus.h"
 #include "arm-misc.h"
 #include "sysemu.h"
+#include "loader.h"
+#include "elf.h"
 
 /* Bitbanded IO.  Each word corresponds to a single bit.  */
 
@@ -166,6 +168,7 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
     uint64_t entry;
     uint64_t lowaddr;
     int i;
+    int big_endian;
 
     flash_size *= 1024;
     sram_size *= 1024;
@@ -206,7 +209,14 @@ qemu_irq *armv7m_init(int flash_size, int sram_size,
         pic[i] = qdev_get_gpio_in(nvic, i);
     }
 
-    image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL);
+#ifdef TARGET_WORDS_BIGENDIAN
+    big_endian = 1;
+#else
+    big_endian = 0;
+#endif
+
+    image_size = load_elf(kernel_filename, 0, &entry, &lowaddr, NULL,
+                          big_endian, ELF_MACHINE, 1);
     if (image_size < 0) {
         image_size = load_image_targphys(kernel_filename, 0, flash_size);
        lowaddr = 0;
index b5163b655fb92a4ba13a4eba85196ddfea527bcb..81a41c94461d0f6dc5f3bc715bb0a82d86d27b44 100644 (file)
@@ -28,6 +28,8 @@
 #include "boards.h"
 #include "sysemu.h"
 #include "etraxfs.h"
+#include "loader.h"
+#include "elf.h"
 
 #define D(x)
 #define DNAND(x)
@@ -344,7 +346,7 @@ void axisdev88_init (ram_addr_t ram_size,
         /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis 
            devboard SDK.  */
         kernel_size = load_elf(kernel_filename, -0x80000000LL,
-                               &entry, NULL, &high);
+                               &entry, NULL, &high, 0, ELF_MACHINE, 0);
         bootstrap_pc = entry;
         if (kernel_size < 0) {
             /* Takes a kimage from the axis devboard SDK.  */
index 5718ab64e1f16043c8ca6e5c471a9763c4eba775..ce45a597db38243d8dffbe334d679de5dddda88b 100644 (file)
@@ -9,6 +9,8 @@
 #include "hw.h"
 #include "sysemu.h"
 #include "boards.h"
+#include "loader.h"
+#include "elf.h"
 
 #define KERNEL_LOAD_ADDR 0x10000
 
@@ -22,7 +24,7 @@ static void dummy_m68k_init(ram_addr_t ram_size,
     CPUState *env;
     int kernel_size;
     uint64_t elf_entry;
-    target_ulong entry;
+    target_phys_addr_t entry;
 
     if (!cpu_model)
         cpu_model = "cfv4e";
@@ -41,7 +43,8 @@ static void dummy_m68k_init(ram_addr_t ram_size,
 
     /* Load kernel.  */
     if (kernel_filename) {
-        kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
+        kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
+                               1, ELF_MACHINE, 0);
         entry = elf_entry;
         if (kernel_size < 0) {
             kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
similarity index 93%
rename from elf_ops.h
rename to hw/elf_ops.h
index 15928cbb5b2b98e60382ec6e63c5ed432b6c9783..8376465a1095b3257fcca4d81ee516653b62d160 100644 (file)
--- a/elf_ops.h
@@ -73,7 +73,8 @@ static int glue(symfind, SZ)(const void *s0, const void *s1)
     return result;
 }
 
-static const char *glue(lookup_symbol, SZ)(struct syminfo *s, target_ulong orig_addr)
+static const char *glue(lookup_symbol, SZ)(struct syminfo *s,
+                                           target_phys_addr_t orig_addr)
 {
     struct elf_sym *syms = glue(s->disas_symtab.elf, SZ);
     struct elf_sym key;
@@ -98,7 +99,8 @@ static int glue(symcmp, SZ)(const void *s0, const void *s1)
         : ((sym0->st_value > sym1->st_value) ? 1 : 0);
 }
 
-static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
+static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
+                                  int clear_lsb)
 {
     struct elf_shdr *symtab, *strtab, *shdr_table = NULL;
     struct elf_sym *syms = NULL;
@@ -141,10 +143,10 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
             }
             continue;
         }
-#if defined(TARGET_ARM) || defined (TARGET_MIPS)
-        /* The bottom address bit marks a Thumb or MIPS16 symbol.  */
-        syms[i].st_value &= ~(target_ulong)1;
-#endif
+        if (clear_lsb) {
+            /* The bottom address bit marks a Thumb or MIPS16 symbol.  */
+            syms[i].st_value &= ~(glue(glue(Elf, SZ), _Addr))1;
+        }
         i++;
     }
     syms = qemu_realloc(syms, nsyms * sizeof(*syms));
@@ -179,7 +181,8 @@ static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab)
 
 static int glue(load_elf, SZ)(int fd, int64_t address_offset,
                               int must_swab, uint64_t *pentry,
-                              uint64_t *lowaddr, uint64_t *highaddr)
+                              uint64_t *lowaddr, uint64_t *highaddr,
+                              int elf_machine, int clear_lsb)
 {
     struct elfhdr ehdr;
     struct elf_phdr *phdr = NULL, *ph;
@@ -194,7 +197,7 @@ static int glue(load_elf, SZ)(int fd, int64_t address_offset,
         glue(bswap_ehdr, SZ)(&ehdr);
     }
 
-    switch (ELF_MACHINE) {
+    switch (elf_machine) {
         case EM_PPC64:
             if (EM_PPC64 != ehdr.e_machine)
                 if (EM_PPC != ehdr.e_machine)
@@ -206,14 +209,14 @@ static int glue(load_elf, SZ)(int fd, int64_t address_offset,
                     goto fail;
             break;
         default:
-            if (ELF_MACHINE != ehdr.e_machine)
+            if (elf_machine != ehdr.e_machine)
                 goto fail;
     }
 
     if (pentry)
        *pentry = (uint64_t)(elf_sword)ehdr.e_entry;
 
-    glue(load_symbols, SZ)(&ehdr, fd, must_swab);
+    glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb);
 
     size = ehdr.e_phnum * sizeof(phdr[0]);
     lseek(fd, ehdr.e_phoff, SEEK_SET);
index ab6a3a302ffd47754e6a5b41b1557f7f80b3d1f6..4f451c54c926f15a8545a1bb6a212fe4c1606d7e 100644 (file)
@@ -28,6 +28,8 @@
 #include "net.h"
 #include "flash.h"
 #include "etraxfs.h"
+#include "loader.h"
+#include "elf.h"
 
 #define FLASH_SIZE 0x2000000
 #define INTMEM_SIZE (128 * 1024)
@@ -136,7 +138,7 @@ void bareetraxfs_init (ram_addr_t ram_size,
         /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis 
            devboard SDK.  */
         kernel_size = load_elf(kernel_filename, -0x80000000LL,
-                               &entry, NULL, &high);
+                               &entry, NULL, &high, 0, ELF_MACHINE, 0);
         bootstrap_pc = entry;
         if (kernel_size < 0) {
             /* Takes a kimage from the axis devboard SDK.  */
similarity index 90%
rename from loader.c
rename to hw/loader.c
index 0cbcf9c6a3e71756bb8bfe005d28f32cf758a58b..5d83a66041ef047ab8d37bb9872c19e0925ee892 100644 (file)
--- a/loader.c
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "qemu-common.h"
+#include "hw.h"
 #include "disas.h"
 #include "sysemu.h"
 #include "uboot_image.h"
+#include "loader.h"
 
 #include <zlib.h>
 
@@ -172,7 +173,6 @@ struct exec
   uint32_t a_drsize; /* length of relocation info for data, in bytes */
 };
 
-#ifdef BSWAP_NEEDED
 static void bswap_ahdr(struct exec *e)
 {
     bswap32s(&e->a_info);
@@ -184,9 +184,6 @@ static void bswap_ahdr(struct exec *e)
     bswap32s(&e->a_trsize);
     bswap32s(&e->a_drsize);
 }
-#else
-#define bswap_ahdr(x) do { } while (0)
-#endif
 
 #define N_MAGIC(exec) ((exec).a_info & 0xffff)
 #define OMAGIC 0407
@@ -197,17 +194,18 @@ static void bswap_ahdr(struct exec *e)
 #define N_TXTOFF(x)                                                    \
     (N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) :    \
      (N_MAGIC(x) == QMAGIC ? 0 : sizeof (struct exec)))
-#define N_TXTADDR(x) (N_MAGIC(x) == QMAGIC ? TARGET_PAGE_SIZE : 0)
-#define _N_SEGMENT_ROUND(x) (((x) + TARGET_PAGE_SIZE - 1) & ~(TARGET_PAGE_SIZE - 1))
+#define N_TXTADDR(x, target_page_size) (N_MAGIC(x) == QMAGIC ? target_page_size : 0)
+#define _N_SEGMENT_ROUND(x, target_page_size) (((x) + target_page_size - 1) & ~(target_page_size - 1))
 
-#define _N_TXTENDADDR(x) (N_TXTADDR(x)+(x).a_text)
+#define _N_TXTENDADDR(x, target_page_size) (N_TXTADDR(x, target_page_size)+(x).a_text)
 
-#define N_DATADDR(x) \
-    (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x)) \
-     : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x))))
+#define N_DATADDR(x, target_page_size) \
+    (N_MAGIC(x)==OMAGIC? (_N_TXTENDADDR(x, target_page_size)) \
+     : (_N_SEGMENT_ROUND (_N_TXTENDADDR(x, target_page_size), target_page_size)))
 
 
-int load_aout(const char *filename, target_phys_addr_t addr, int max_sz)
+int load_aout(const char *filename, target_phys_addr_t addr, int max_sz,
+              int bswap_needed, target_phys_addr_t target_page_size)
 {
     int fd, size, ret;
     struct exec e;
@@ -221,7 +219,9 @@ int load_aout(const char *filename, target_phys_addr_t addr, int max_sz)
     if (size < 0)
         goto fail;
 
-    bswap_ahdr(&e);
+    if (bswap_needed) {
+        bswap_ahdr(&e);
+    }
 
     magic = N_MAGIC(e);
     switch (magic) {
@@ -236,13 +236,14 @@ int load_aout(const char *filename, target_phys_addr_t addr, int max_sz)
            goto fail;
        break;
     case NMAGIC:
-        if (N_DATADDR(e) + e.a_data > max_sz)
+        if (N_DATADDR(e, target_page_size) + e.a_data > max_sz)
             goto fail;
        lseek(fd, N_TXTOFF(e), SEEK_SET);
        size = read_targphys(fd, addr, e.a_text);
        if (size < 0)
            goto fail;
-       ret = read_targphys(fd, addr + N_DATADDR(e), e.a_data);
+        ret = read_targphys(fd, addr + N_DATADDR(e, target_page_size),
+                            e.a_data);
        if (ret < 0)
            goto fail;
        size += ret;
@@ -307,9 +308,10 @@ static void *load_at(int fd, int offset, int size)
 
 /* return < 0 if error, otherwise the number of bytes loaded in memory */
 int load_elf(const char *filename, int64_t address_offset,
-             uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr)
+             uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr,
+             int big_endian, int elf_machine, int clear_lsb)
 {
-    int fd, data_order, host_data_order, must_swab, ret;
+    int fd, data_order, target_data_order, must_swab, ret;
     uint8_t e_ident[EI_NIDENT];
 
     fd = open(filename, O_RDONLY | O_BINARY);
@@ -330,22 +332,22 @@ int load_elf(const char *filename, int64_t address_offset,
     data_order = ELFDATA2LSB;
 #endif
     must_swab = data_order != e_ident[EI_DATA];
+    if (big_endian) {
+        target_data_order = ELFDATA2MSB;
+    } else {
+        target_data_order = ELFDATA2LSB;
+    }
 
-#ifdef TARGET_WORDS_BIGENDIAN
-    host_data_order = ELFDATA2MSB;
-#else
-    host_data_order = ELFDATA2LSB;
-#endif
-    if (host_data_order != e_ident[EI_DATA])
+    if (target_data_order != e_ident[EI_DATA])
         return -1;
 
     lseek(fd, 0, SEEK_SET);
     if (e_ident[EI_CLASS] == ELFCLASS64) {
         ret = load_elf64(fd, address_offset, must_swab, pentry,
-                         lowaddr, highaddr);
+                         lowaddr, highaddr, elf_machine, clear_lsb);
     } else {
         ret = load_elf32(fd, address_offset, must_swab, pentry,
-                         lowaddr, highaddr);
+                         lowaddr, highaddr, elf_machine, clear_lsb);
     }
 
     close(fd);
@@ -455,8 +457,8 @@ static ssize_t gunzip(void *dst, size_t dstlen, uint8_t *src,
 }
 
 /* Load a U-Boot image.  */
-int load_uimage(const char *filename, target_ulong *ep, target_ulong *loadaddr,
-                int *is_linux)
+int load_uimage(const char *filename, target_phys_addr_t *ep,
+                target_phys_addr_t *loadaddr, int *is_linux)
 {
     int fd;
     int size;
diff --git a/hw/loader.h b/hw/loader.h
new file mode 100644 (file)
index 0000000..3632008
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef LOADER_H
+#define LOADER_H
+
+/* loader.c */
+int get_image_size(const char *filename);
+int load_image(const char *filename, uint8_t *addr); /* deprecated */
+int load_image_targphys(const char *filename, target_phys_addr_t, int max_sz);
+int load_elf(const char *filename, int64_t address_offset,
+             uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr,
+             int big_endian, int elf_machine, int clear_lsb);
+int load_aout(const char *filename, target_phys_addr_t addr, int max_sz,
+              int bswap_needed, target_phys_addr_t target_page_size);
+int load_uimage(const char *filename, target_phys_addr_t *ep,
+                target_phys_addr_t *loadaddr, int *is_linux);
+
+int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f);
+int fread_targphys_ok(target_phys_addr_t dst_addr, size_t nbytes, FILE *f);
+int read_targphys(int fd, target_phys_addr_t dst_addr, size_t nbytes);
+void pstrcpy_targphys(target_phys_addr_t dest, int buf_size,
+                      const char *source);
+#endif
index 95a03fc0e6ea616c6f72fc0625bacf74c9746555..559861146272e21669502434748f2eddbd398fb3 100644 (file)
@@ -11,6 +11,8 @@
 #include "sysemu.h"
 #include "net.h"
 #include "boards.h"
+#include "loader.h"
+#include "elf.h"
 
 #define SYS_FREQ 66000000
 
@@ -201,7 +203,7 @@ static void mcf5208evb_init(ram_addr_t ram_size,
     CPUState *env;
     int kernel_size;
     uint64_t elf_entry;
-    target_ulong entry;
+    target_phys_addr_t entry;
     qemu_irq *pic;
 
     if (!cpu_model)
@@ -268,7 +270,8 @@ static void mcf5208evb_init(ram_addr_t ram_size,
         exit(1);
     }
 
-    kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
+    kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
+                           1, ELF_MACHINE, 0);
     entry = elf_entry;
     if (kernel_size < 0) {
         kernel_size = load_uimage(kernel_filename, &entry, NULL, NULL);
index d62a584a9a67dbe749dea8cab6c1a7bd117b9bd0..1a499fa3970454eb4b000afc006d652d04d53408 100644 (file)
@@ -33,6 +33,7 @@
 #include "net.h"
 #include "scsi.h"
 #include "mips-bios.h"
+#include "loader.h"
 
 enum jazz_model_e
 {
index 0a6eaa479ac748b90eb26ff0b651de677d1ec683..4d72da87164b7d0403527f9057cc35d98f487090 100644 (file)
@@ -39,6 +39,8 @@
 #include "qemu-log.h"
 #include "mips-bios.h"
 #include "ide.h"
+#include "loader.h"
+#include "elf.h"
 
 //#define DEBUG_BOARD_INIT
 
@@ -687,10 +689,17 @@ static int64_t load_kernel (CPUState *env)
     int index = 0;
     long initrd_size;
     ram_addr_t initrd_offset;
+    int big_endian;
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    big_endian = 1;
+#else
+    big_endian = 0;
+#endif
 
     if (load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
                  (uint64_t *)&kernel_entry, (uint64_t *)&kernel_low,
-                 (uint64_t *)&kernel_high) < 0) {
+                 (uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1) < 0) {
         fprintf(stderr, "qemu: could not load kernel '%s'\n",
                 loaderparams.kernel_filename);
         exit(1);
index 6080dc825e1839c9445952b493513957c66bd6bf..9aed40e1bd6af10ae49f76d41519766107f2b04f 100644 (file)
@@ -32,6 +32,8 @@
 #include "sysemu.h"
 #include "boards.h"
 #include "mips-bios.h"
+#include "loader.h"
+#include "elf.h"
 
 #ifdef TARGET_MIPS64
 #define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
@@ -54,10 +56,17 @@ static void load_kernel (CPUState *env)
     long kernel_size;
     long initrd_size;
     ram_addr_t initrd_offset;
+    int big_endian;
+
+#ifdef TARGET_WORDS_BIGENDIAN
+    big_endian = 1;
+#else
+    big_endian = 0;
+#endif
 
     kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
                            (uint64_t *)&entry, (uint64_t *)&kernel_low,
-                           (uint64_t *)&kernel_high);
+                           (uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1);
     if (kernel_size >= 0) {
         if ((entry & ~0x7fffffffULL) == 0x80000000)
             entry = (int32_t)entry;
index fcc7fed5f15bd27b7512e35305654e3530119e3a..b3abc61551f2edfd730d331a0d68e36cc848b5f3 100644 (file)
@@ -18,6 +18,8 @@
 #include "qemu-log.h"
 #include "mips-bios.h"
 #include "ide.h"
+#include "loader.h"
+#include "elf.h"
 
 #define PHYS_TO_VIRT(x) ((x) | ~(target_ulong)0x7fffffff)
 
@@ -77,10 +79,16 @@ static void load_kernel (CPUState *env)
     long kernel_size, initrd_size;
     ram_addr_t initrd_offset;
     int ret;
+    int big_endian;
 
+#ifdef TARGET_WORDS_BIGENDIAN
+    big_endian = 1;
+#else
+    big_endian = 0;
+#endif
     kernel_size = load_elf(loaderparams.kernel_filename, VIRT_TO_PHYS_ADDEND,
                            (uint64_t *)&entry, (uint64_t *)&kernel_low,
-                           (uint64_t *)&kernel_high);
+                           (uint64_t *)&kernel_high, big_endian, ELF_MACHINE, 1);
     if (kernel_size >= 0) {
         if ((entry & ~0x7fffffffULL) == 0x80000000)
             entry = (int32_t)entry;
index e9b68a7f105774e89c770ed499cb7b4d3037ebcd..066a0f980fe5344c2053fe3313232be6fe4ce625 100644 (file)
@@ -30,6 +30,7 @@
 #include "flash.h"
 #include "hw.h"
 #include "bt.h"
+#include "loader.h"
 
 /* Nokia N8x0 support */
 struct n800_s {
index bba972276ebc66592f8d04326647717b2527e645..6d19167512f5f022c1630433c25cb716f97deda5 100644 (file)
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -24,6 +24,7 @@
 #include "boards.h"
 #include "arm-misc.h"
 #include "devices.h"
+#include "loader.h"
 
 static uint32_t static_readb(void *opaque, target_phys_addr_t offset)
 {
diff --git a/hw/pc.c b/hw/pc.c
index 58de372da671f62085397ac7b717a4605a280482..bc2875e36dea80c66ece2a1e15c715c800e3fcc3 100644 (file)
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -37,6 +37,8 @@
 #include "watchdog.h"
 #include "smbios.h"
 #include "ide.h"
+#include "loader.h"
+#include "elf.h"
 
 /* output Bochs bios info messages */
 //#define DEBUG_BIOS
@@ -657,7 +659,8 @@ static int load_multiboot(void *fw_cfg,
         uint64_t elf_entry;
         int kernel_size;
         fclose(f);
-        kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL);
+        kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,
+                               0, ELF_MACHINE, 0);
         if (kernel_size < 0) {
             fprintf(stderr, "Error while loading elf kernel\n");
             exit(1);
index a04794d7f347003eab9ce5989a2996bedc366545..f343dbf7b8e495e42cd7bca8e61cdcb65be911a0 100644 (file)
@@ -32,6 +32,8 @@
 #include "boards.h"
 #include "device_tree.h"
 #include "xilinx.h"
+#include "loader.h"
+#include "elf.h"
 
 #define LMB_BRAM_SIZE  (128 * 1024)
 #define FLASH_SIZE     (16 * 1024 * 1024)
@@ -155,11 +157,13 @@ petalogix_s3adsp1800_init(ram_addr_t ram_size,
 
         /* Boots a kernel elf binary.  */
         kernel_size = load_elf(kernel_filename, 0,
-                               &entry, &low, &high);
+                               &entry, &low, &high,
+                               1, ELF_MACHINE, 0);
         base32 = entry;
         if (base32 == 0xc0000000) {
             kernel_size = load_elf(kernel_filename, -0x30000000LL,
-                                   &entry, NULL, NULL);
+                                   &entry, NULL, NULL,
+                                   1, ELF_MACHINE, 0);
         }
         /* Always boot into physical ram.  */
         bootstrap_pc = ddr_base + (entry & 0x0fffffff);
index 2d66b9dc597011694b7ece07a2466813b3ac1613..09ee2e46dd4d465886e1a4d2a8e26ea1cb053162 100644 (file)
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -27,6 +27,7 @@
 #include "sysemu.h"
 #include "nvram.h"
 #include "qemu-log.h"
+#include "loader.h"
 
 //#define PPC_DEBUG_IRQ
 //#define PPC_DEBUG_TB
index 0d7860edd655f4e2ed51663a75b24f4d1d218d47..9aa99c17812f1d3997b8f06bbc2ebb2aa02a0f67 100644 (file)
@@ -30,6 +30,7 @@
 #include "block.h"
 #include "boards.h"
 #include "qemu-log.h"
+#include "loader.h"
 
 #define BIOS_FILENAME "ppc405_rom.bin"
 #define BIOS_SIZE (2048 * 1024)
index 3c59f3309920b76d97c7b88230bf68e45c78aeb5..8a6b7ced9200eed290579c600485be506083bf09 100644 (file)
@@ -22,6 +22,8 @@
 #include "kvm.h"
 #include "kvm_ppc.h"
 #include "device_tree.h"
+#include "loader.h"
+#include "elf.h"
 
 #define BINARY_DEVICE_TREE_FILE "bamboo.dtb"
 
@@ -93,8 +95,8 @@ static void bamboo_init(ram_addr_t ram_size,
     CPUState *env;
     uint64_t elf_entry;
     uint64_t elf_lowaddr;
-    target_ulong entry = 0;
-    target_ulong loadaddr = 0;
+    target_phys_addr_t entry = 0;
+    target_phys_addr_t loadaddr = 0;
     target_long kernel_size = 0;
     target_ulong initrd_base = 0;
     target_long initrd_size = 0;
@@ -126,7 +128,7 @@ static void bamboo_init(ram_addr_t ram_size,
         kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
         if (kernel_size < 0) {
             kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
-                                   NULL);
+                                   NULL, 1, ELF_MACHINE, 0);
             entry = elf_entry;
             loadaddr = elf_lowaddr;
         }
index 9a491eb7c6733b6a9ef3cb15717f919794fec9ce..6bd5234d8f247d7be37f8b4d2da89cdaf347a796 100644 (file)
@@ -36,6 +36,8 @@
 #include "escc.h"
 #include "openpic.h"
 #include "ide.h"
+#include "loader.h"
+#include "elf.h"
 
 #define MAX_IDE_BUS 2
 #define VGA_BIOS_SIZE 65536
@@ -145,7 +147,8 @@ static void ppc_core99_init (ram_addr_t ram_size,
 
     /* Load OpenBIOS (ELF) */
     if (filename) {
-        bios_size = load_elf(filename, 0, NULL, NULL, NULL);
+        bios_size = load_elf(filename, 0, NULL, NULL, NULL, 1, ELF_MACHINE, 0);
+
         qemu_free(filename);
     } else {
         bios_size = -1;
@@ -187,19 +190,28 @@ static void ppc_core99_init (ram_addr_t ram_size,
 
     if (linux_boot) {
         uint64_t lowaddr = 0;
+        int bswap_needed;
+
+#ifdef BSWAP_NEEDED
+        bswap_needed = 1;
+#else
+        bswap_needed = 0;
+#endif
         kernel_base = KERNEL_LOAD_ADDR;
 
         /* Now we can load the kernel. The first step tries to load the kernel
            supposing PhysAddr = 0x00000000. If that was wrong the kernel is
            loaded again, the new PhysAddr being computed from lowaddr. */
-        kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL);
+        kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL,
+                               1, ELF_MACHINE, 0);
         if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) {
             kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
-                                   NULL, NULL, NULL);
+                                   NULL, NULL, NULL, 1, ELF_MACHINE, 0);
         }
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, kernel_base,
-                                    ram_size - kernel_base);
+                                    ram_size - kernel_base, bswap_needed,
+                                    TARGET_PAGE_SIZE);
         if (kernel_size < 0)
             kernel_size = load_image_targphys(kernel_filename,
                                               kernel_base,
index 693365071161b8687389c65ec4ac0832c347886a..bb8c969ca2e716c91ec8d323bcef1d2940f280bf 100644 (file)
@@ -36,6 +36,8 @@
 #include "fw_cfg.h"
 #include "escc.h"
 #include "ide.h"
+#include "loader.h"
+#include "elf.h"
 
 #define MAX_IDE_BUS 2
 #define VGA_BIOS_SIZE 65536
@@ -180,7 +182,8 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
 
     /* Load OpenBIOS (ELF) */
     if (filename) {
-        bios_size = load_elf(filename, 0, NULL, NULL, NULL);
+        bios_size = load_elf(filename, 0, NULL, NULL, NULL,
+                               1, ELF_MACHINE, 0);
         qemu_free(filename);
     } else {
         bios_size = -1;
@@ -222,18 +225,27 @@ static void ppc_heathrow_init (ram_addr_t ram_size,
 
     if (linux_boot) {
         uint64_t lowaddr = 0;
+        int bswap_needed;
+
+#ifdef BSWAP_NEEDED
+        bswap_needed = 1;
+#else
+        bswap_needed = 0;
+#endif
         kernel_base = KERNEL_LOAD_ADDR;
         /* Now we can load the kernel. The first step tries to load the kernel
            supposing PhysAddr = 0x00000000. If that was wrong the kernel is
            loaded again, the new PhysAddr being computed from lowaddr. */
-        kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL);
+        kernel_size = load_elf(kernel_filename, kernel_base, NULL, &lowaddr, NULL,
+                               1, ELF_MACHINE, 0);
         if (kernel_size > 0 && lowaddr != KERNEL_LOAD_ADDR) {
             kernel_size = load_elf(kernel_filename, (2 * kernel_base) - lowaddr,
-                                   NULL, NULL, NULL);
+                                   NULL, NULL, NULL, 1, ELF_MACHINE, 0);
         }
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, kernel_base,
-                                    ram_size - kernel_base);
+                                    ram_size - kernel_base, bswap_needed,
+                                    TARGET_PAGE_SIZE);
         if (kernel_size < 0)
             kernel_size = load_image_targphys(kernel_filename,
                                               kernel_base,
index 5392072982731c7e0559f1fcfab0506ee8e90400..eb281f85f758952385921370fd95f2953cf4049c 100644 (file)
@@ -33,6 +33,7 @@
 #include "boards.h"
 #include "qemu-log.h"
 #include "ide.h"
+#include "loader.h"
 
 //#define HARD_DEBUG_PPC_IO
 //#define DEBUG_PPC_IO
index 51208215f10606d6fe370afb251a3702bb321d85..504419458b3762bdadf0dcef8a7b433617b26851 100644 (file)
@@ -29,6 +29,8 @@
 #include "device_tree.h"
 #include "openpic.h"
 #include "ppce500.h"
+#include "loader.h"
+#include "elf.h"
 
 #define BINARY_DEVICE_TREE_FILE    "mpc8544ds.dtb"
 #define UIMAGE_LOAD_BASE           0
@@ -160,8 +162,8 @@ static void mpc8544ds_init(ram_addr_t ram_size,
     CPUState *env;
     uint64_t elf_entry;
     uint64_t elf_lowaddr;
-    target_ulong entry=0;
-    target_ulong loadaddr=UIMAGE_LOAD_BASE;
+    target_phys_addr_t entry=0;
+    target_phys_addr_t loadaddr=UIMAGE_LOAD_BASE;
     target_long kernel_size=0;
     target_ulong dt_base=DTB_LOAD_BASE;
     target_ulong initrd_base=INITRD_LOAD_BASE;
@@ -226,7 +228,7 @@ static void mpc8544ds_init(ram_addr_t ram_size,
         kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);
         if (kernel_size < 0) {
             kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,
-                                   NULL);
+                                   NULL, 1, ELF_MACHINE, 0);
             entry = elf_entry;
             loadaddr = elf_lowaddr;
         }
index ff514a482f4d46adda7ea32ed45961ba19336836..ea19ff623da5aa4dad63f9d8bae6f4f1e811ddeb 100644 (file)
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -32,6 +32,7 @@
 #include "net.h"
 #include "sh7750_regs.h"
 #include "ide.h"
+#include "loader.h"
 
 #define SDRAM_BASE 0x0c000000 /* Physical location of SDRAM: Area 3 */
 #define SDRAM_SIZE 0x04000000
index 19b0155a49a86c49a270f49fe888011076aff98e..638bf16e349ff4b1d8866d860480e08909dbc4fb 100644 (file)
--- a/hw/shix.c
+++ b/hw/shix.c
@@ -32,6 +32,7 @@
 #include "sh.h"
 #include "sysemu.h"
 #include "boards.h"
+#include "loader.h"
 
 #define BIOS_FILENAME "shix_bios.bin"
 #define BIOS_ADDRESS 0xA0000000
index e28beba2c8881a4f6d30a9a34a0347c72297469e..a3ae1de824db2d69c1f770c37cac41553b4b831e 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "sysemu.h"
 #include "smbios.h"
+#include "loader.h"
 
 /*
  * Structures shared with the BIOS
index d97072393b50168c962d90ec6d0333cdf356455d..a869d15a811991e62cf791c9d0d9fd003978c875 100644 (file)
@@ -37,6 +37,8 @@
 #include "fw_cfg.h"
 #include "escc.h"
 #include "qdev-addr.h"
+#include "loader.h"
+#include "elf.h"
 
 //#define DEBUG_IRQ
 
@@ -302,11 +304,19 @@ static unsigned long sun4m_load_kernel(const char *kernel_filename,
 
     kernel_size = 0;
     if (linux_boot) {
+        int bswap_needed;
+
+#ifdef BSWAP_NEEDED
+        bswap_needed = 1;
+#else
+        bswap_needed = 0;
+#endif
         kernel_size = load_elf(kernel_filename, -0xf0000000ULL, NULL, NULL,
-                               NULL);
+                               NULL, 1, ELF_MACHINE, 0);
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
-                                    RAM_size - KERNEL_LOAD_ADDR);
+                                    RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
+                                    TARGET_PAGE_SIZE);
         if (kernel_size < 0)
             kernel_size = load_image_targphys(kernel_filename,
                                               KERNEL_LOAD_ADDR,
@@ -608,7 +618,8 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name)
     }
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     if (filename) {
-        ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL);
+        ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL,
+                       1, ELF_MACHINE, 0);
         if (ret < 0 || ret > PROM_SIZE_MAX) {
             ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
         }
index 427ee764ceaea1b8a77e148f3a979b99f62aa92c..2c97d9d7026e4a4c7ccf6a735f4f181e1c11aab8 100644 (file)
@@ -34,6 +34,8 @@
 #include "fw_cfg.h"
 #include "sysbus.h"
 #include "ide.h"
+#include "loader.h"
+#include "elf.h"
 
 //#define DEBUG_IRQ
 
@@ -164,10 +166,19 @@ static unsigned long sun4u_load_kernel(const char *kernel_filename,
 
     kernel_size = 0;
     if (linux_boot) {
-        kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL);
+        int bswap_needed;
+
+#ifdef BSWAP_NEEDED
+        bswap_needed = 1;
+#else
+        bswap_needed = 0;
+#endif
+        kernel_size = load_elf(kernel_filename, 0, NULL, NULL, NULL,
+                               1, ELF_MACHINE, 0);
         if (kernel_size < 0)
             kernel_size = load_aout(kernel_filename, KERNEL_LOAD_ADDR,
-                                    RAM_size - KERNEL_LOAD_ADDR);
+                                    RAM_size - KERNEL_LOAD_ADDR, bswap_needed,
+                                    TARGET_PAGE_SIZE);
         if (kernel_size < 0)
             kernel_size = load_image_targphys(kernel_filename,
                                               KERNEL_LOAD_ADDR,
@@ -418,7 +429,8 @@ static void prom_init(target_phys_addr_t addr, const char *bios_name)
     }
     filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
     if (filename) {
-        ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL);
+        ret = load_elf(filename, addr - PROM_VADDR, NULL, NULL, NULL,
+                       1, ELF_MACHINE, 0);
         if (ret < 0 || ret > PROM_SIZE_MAX) {
             ret = load_image_targphys(filename, addr, PROM_SIZE_MAX);
         }
index 21e808547e54ac3a48c35d31a224dd3a9f177ca0..264aa028da8c084fac73d47f7cb35c0defc8ea0b 100644 (file)
@@ -1,6 +1,7 @@
 #include "hw.h"
 #include "sh.h"
 #include "sysemu.h"
+#include "loader.h"
 
 #define CE1  0x0100
 #define CE2  0x0200
index 10d4781da8ec567a2a9ecbd595397be64270021e..7c8e771df13039037bb08feb52db9c7b0c3f2265 100644 (file)
@@ -1315,10 +1315,10 @@ static void load_symbols(struct elfhdr *hdr, int fd)
     s->disas_num_syms = nsyms;
 #if ELF_CLASS == ELFCLASS32
     s->disas_symtab.elf32 = syms;
-    s->lookup_symbol = lookup_symbolxx;
+    s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx;
 #else
     s->disas_symtab.elf64 = syms;
-    s->lookup_symbol = lookup_symbolxx;
+    s->lookup_symbol = (lookup_symbol_t)lookup_symbolxx;
 #endif
     s->next = syminfos;
     syminfos = s;
index 644a97d62453bb5bd2a6e3b406177040218795a0..8bf90ee357a541fe687f5e1e04f3d09bc9b8fd9e 100644 (file)
--- a/sysemu.h
+++ b/sysemu.h
@@ -237,24 +237,6 @@ extern CharDriverState *virtcon_hds[MAX_VIRTIO_CONSOLES];
 
 #define TFR(expr) do { if ((expr) != -1) break; } while (errno == EINTR)
 
-#ifdef NEED_CPU_H
-/* loader.c */
-int get_image_size(const char *filename);
-int load_image(const char *filename, uint8_t *addr); /* deprecated */
-int load_image_targphys(const char *filename, target_phys_addr_t, int max_sz);
-int load_elf(const char *filename, int64_t address_offset,
-             uint64_t *pentry, uint64_t *lowaddr, uint64_t *highaddr);
-int load_aout(const char *filename, target_phys_addr_t addr, int max_sz);
-int load_uimage(const char *filename, target_ulong *ep, target_ulong *loadaddr,
-                int *is_linux);
-
-int fread_targphys(target_phys_addr_t dst_addr, size_t nbytes, FILE *f);
-int fread_targphys_ok(target_phys_addr_t dst_addr, size_t nbytes, FILE *f);
-int read_targphys(int fd, target_phys_addr_t dst_addr, size_t nbytes);
-void pstrcpy_targphys(target_phys_addr_t dest, int buf_size,
-                      const char *source);
-#endif
-
 #ifdef HAS_AUDIO
 struct soundhw {
     const char *name;