aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2006-12-23 14:18:40 +0000
committerths <ths@c046a42c-6fe2-441c-8c8c-71466251a162>2006-12-23 14:18:40 +0000
commit9042c0e20de166542b603621fd30dc8be95dfd4d (patch)
tree84ea028032cb2c70fff393af4d94854eea585f3f
parent70ead4341212ecb3181d5c780284cef0fc7b51fc (diff)
downloadqemu-9042c0e20de166542b603621fd30dc8be95dfd4d.zip
qemu-9042c0e20de166542b603621fd30dc8be95dfd4d.tar.gz
qemu-9042c0e20de166542b603621fd30dc8be95dfd4d.tar.bz2
Check ELF binaries for machine type and endianness.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2274 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--elf_ops.h13
-rw-r--r--hw/mips_r4k.c12
-rw-r--r--loader.c12
-rw-r--r--target-arm/cpu.h2
-rw-r--r--target-i386/cpu.h6
-rw-r--r--target-m68k/cpu.h2
-rw-r--r--target-mips/cpu.h2
-rw-r--r--target-ppc/cpu.h2
-rw-r--r--target-sh4/cpu.h2
-rw-r--r--target-sparc/cpu.h6
10 files changed, 44 insertions, 15 deletions
diff --git a/elf_ops.h b/elf_ops.h
index 122bf10..1cd4f2b 100644
--- a/elf_ops.h
+++ b/elf_ops.h
@@ -153,6 +153,9 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend,
glue(bswap_ehdr, SZ)(&ehdr);
}
+ if (ELF_MACHINE != ehdr.e_machine)
+ goto fail;
+
if (pentry)
*pentry = (uint64_t)ehdr.e_entry;
@@ -164,7 +167,7 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend,
if (!phdr)
goto fail;
if (read(fd, phdr, size) != size)
- goto fail;
+ goto fail1;
if (must_swab) {
for(i = 0; i < ehdr.e_phnum; i++) {
ph = &phdr[i];
@@ -181,9 +184,9 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend,
data = qemu_mallocz(mem_size);
if (ph->p_filesz > 0) {
if (lseek(fd, ph->p_offset, SEEK_SET) < 0)
- goto fail;
+ goto fail2;
if (read(fd, data, ph->p_filesz) != ph->p_filesz)
- goto fail;
+ goto fail2;
}
addr = ph->p_vaddr + virt_to_phys_addend;
@@ -197,9 +200,11 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend,
}
qemu_free(phdr);
return total_size;
- fail:
+fail2:
qemu_free(data);
+fail1:
qemu_free(phdr);
+fail:
return -1;
}
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index cf52a03..d72d768 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -11,7 +11,6 @@
#define BIOS_FILENAME "mips_bios.bin"
//#define BIOS_FILENAME "system.bin"
-#define KERNEL_LOAD_ADDR (int32_t)0x80010000
#ifdef MIPS_HAS_MIPS64
#define INITRD_LOAD_ADDR (int64_t)0x80800000
#else
@@ -86,14 +85,9 @@ void load_kernel (CPUState *env, int ram_size, const char *kernel_filename,
entry = (int32_t)entry;
env->PC = entry;
} else {
- kernel_size = load_image(kernel_filename,
- phys_ram_base + KERNEL_LOAD_ADDR + VIRT_TO_PHYS_ADDEND);
- if (kernel_size < 0) {
- fprintf(stderr, "qemu: could not load kernel '%s'\n",
- kernel_filename);
- exit(1);
- }
- env->PC = KERNEL_LOAD_ADDR;
+ fprintf(stderr, "qemu: could not load kernel '%s'\n",
+ kernel_filename);
+ exit(1);
}
/* load initrd */
diff --git a/loader.c b/loader.c
index 3fa681d..7823add 100644
--- a/loader.c
+++ b/loader.c
@@ -197,7 +197,7 @@ static void *load_at(int fd, int offset, int size)
int load_elf(const char *filename, int64_t virt_to_phys_addend,
uint64_t *pentry)
{
- int fd, data_order, must_swab, ret;
+ int fd, data_order, host_data_order, must_swab, ret;
uint8_t e_ident[EI_NIDENT];
fd = open(filename, O_RDONLY | O_BINARY);
@@ -218,7 +218,15 @@ int load_elf(const char *filename, int64_t virt_to_phys_addend,
data_order = ELFDATA2LSB;
#endif
must_swab = data_order != e_ident[EI_DATA];
-
+
+#ifdef TARGET_WORDS_BIGENDIAN
+ host_data_order = ELFDATA2MSB;
+#else
+ host_data_order = ELFDATA2LSB;
+#endif
+ if (host_data_order != e_ident[EI_DATA])
+ return -1;
+
lseek(fd, 0, SEEK_SET);
if (e_ident[EI_CLASS] == ELFCLASS64) {
ret = load_elf64(fd, virt_to_phys_addend, must_swab, pentry);
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index b994bdd..359d5cb 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -22,6 +22,8 @@
#define TARGET_LONG_BITS 32
+#define ELF_MACHINE EM_ARM
+
#include "cpu-defs.h"
#include "softfloat.h"
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 3050740..4296093 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -36,6 +36,12 @@
#define TARGET_HAS_ICE 1
+#ifdef TARGET_X86_64
+#define ELF_MACHINE EM_X86_64
+#else
+#define ELF_MACHINE EM_386
+#endif
+
#include "cpu-defs.h"
#include "softfloat.h"
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 29e02e8..a30bf96 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -31,6 +31,8 @@
#define TARGET_HAS_ICE 1
+#define ELF_MACHINE EM_68K
+
#define EXCP_ACCESS 2 /* Access (MMU) error. */
#define EXCP_ADDRESS 3 /* Address error. */
#define EXCP_ILLEGAL 4 /* Illegal instruction. */
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 8f0f598..c1b13d9 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -3,6 +3,8 @@
#define TARGET_HAS_ICE 1
+#define ELF_MACHINE EM_MIPS
+
#include "config.h"
#include "mips-defs.h"
#include "cpu-defs.h"
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 88d9135..f05fb28 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -32,6 +32,8 @@
#define TARGET_HAS_ICE 1
+#define ELF_MACHINE EM_PPC
+
/* XXX: this should be tunable: PowerPC 601 & 64 bits PowerPC
* have different cache line sizes
*/
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index ef818fd..7296d9e 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -25,6 +25,8 @@
#define TARGET_LONG_BITS 32
#define TARGET_HAS_ICE 1
+#define ELF_MACHINE EM_SH
+
#include "cpu-defs.h"
#include "softfloat.h"
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index 8cbf0b2..86c23200 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -19,6 +19,12 @@
#define TARGET_HAS_ICE 1
+#if !defined(TARGET_SPARC64)
+#define ELF_MACHINE EM_SPARC
+#else
+#define ELF_MACHINE EM_SPARCV9
+#endif
+
/*#define EXCP_INTERRUPT 0x100*/
/* trap definitions */