Commit 9042c0e20de166542b603621fd30dc8be95dfd4d
1 parent
70ead434
Check ELF binaries for machine type and endianness.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2274 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
10 changed files
with
44 additions
and
15 deletions
elf_ops.h
| @@ -153,6 +153,9 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, | @@ -153,6 +153,9 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, | ||
| 153 | glue(bswap_ehdr, SZ)(&ehdr); | 153 | glue(bswap_ehdr, SZ)(&ehdr); |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | + if (ELF_MACHINE != ehdr.e_machine) | ||
| 157 | + goto fail; | ||
| 158 | + | ||
| 156 | if (pentry) | 159 | if (pentry) |
| 157 | *pentry = (uint64_t)ehdr.e_entry; | 160 | *pentry = (uint64_t)ehdr.e_entry; |
| 158 | 161 | ||
| @@ -164,7 +167,7 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, | @@ -164,7 +167,7 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, | ||
| 164 | if (!phdr) | 167 | if (!phdr) |
| 165 | goto fail; | 168 | goto fail; |
| 166 | if (read(fd, phdr, size) != size) | 169 | if (read(fd, phdr, size) != size) |
| 167 | - goto fail; | 170 | + goto fail1; |
| 168 | if (must_swab) { | 171 | if (must_swab) { |
| 169 | for(i = 0; i < ehdr.e_phnum; i++) { | 172 | for(i = 0; i < ehdr.e_phnum; i++) { |
| 170 | ph = &phdr[i]; | 173 | ph = &phdr[i]; |
| @@ -181,9 +184,9 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, | @@ -181,9 +184,9 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, | ||
| 181 | data = qemu_mallocz(mem_size); | 184 | data = qemu_mallocz(mem_size); |
| 182 | if (ph->p_filesz > 0) { | 185 | if (ph->p_filesz > 0) { |
| 183 | if (lseek(fd, ph->p_offset, SEEK_SET) < 0) | 186 | if (lseek(fd, ph->p_offset, SEEK_SET) < 0) |
| 184 | - goto fail; | 187 | + goto fail2; |
| 185 | if (read(fd, data, ph->p_filesz) != ph->p_filesz) | 188 | if (read(fd, data, ph->p_filesz) != ph->p_filesz) |
| 186 | - goto fail; | 189 | + goto fail2; |
| 187 | } | 190 | } |
| 188 | addr = ph->p_vaddr + virt_to_phys_addend; | 191 | addr = ph->p_vaddr + virt_to_phys_addend; |
| 189 | 192 | ||
| @@ -197,9 +200,11 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, | @@ -197,9 +200,11 @@ int glue(load_elf, SZ)(int fd, int64_t virt_to_phys_addend, | ||
| 197 | } | 200 | } |
| 198 | qemu_free(phdr); | 201 | qemu_free(phdr); |
| 199 | return total_size; | 202 | return total_size; |
| 200 | - fail: | 203 | +fail2: |
| 201 | qemu_free(data); | 204 | qemu_free(data); |
| 205 | +fail1: | ||
| 202 | qemu_free(phdr); | 206 | qemu_free(phdr); |
| 207 | +fail: | ||
| 203 | return -1; | 208 | return -1; |
| 204 | } | 209 | } |
| 205 | 210 |
hw/mips_r4k.c
| @@ -11,7 +11,6 @@ | @@ -11,7 +11,6 @@ | ||
| 11 | 11 | ||
| 12 | #define BIOS_FILENAME "mips_bios.bin" | 12 | #define BIOS_FILENAME "mips_bios.bin" |
| 13 | //#define BIOS_FILENAME "system.bin" | 13 | //#define BIOS_FILENAME "system.bin" |
| 14 | -#define KERNEL_LOAD_ADDR (int32_t)0x80010000 | ||
| 15 | #ifdef MIPS_HAS_MIPS64 | 14 | #ifdef MIPS_HAS_MIPS64 |
| 16 | #define INITRD_LOAD_ADDR (int64_t)0x80800000 | 15 | #define INITRD_LOAD_ADDR (int64_t)0x80800000 |
| 17 | #else | 16 | #else |
| @@ -86,14 +85,9 @@ void load_kernel (CPUState *env, int ram_size, const char *kernel_filename, | @@ -86,14 +85,9 @@ void load_kernel (CPUState *env, int ram_size, const char *kernel_filename, | ||
| 86 | entry = (int32_t)entry; | 85 | entry = (int32_t)entry; |
| 87 | env->PC = entry; | 86 | env->PC = entry; |
| 88 | } else { | 87 | } else { |
| 89 | - kernel_size = load_image(kernel_filename, | ||
| 90 | - phys_ram_base + KERNEL_LOAD_ADDR + VIRT_TO_PHYS_ADDEND); | ||
| 91 | - if (kernel_size < 0) { | ||
| 92 | - fprintf(stderr, "qemu: could not load kernel '%s'\n", | ||
| 93 | - kernel_filename); | ||
| 94 | - exit(1); | ||
| 95 | - } | ||
| 96 | - env->PC = KERNEL_LOAD_ADDR; | 88 | + fprintf(stderr, "qemu: could not load kernel '%s'\n", |
| 89 | + kernel_filename); | ||
| 90 | + exit(1); | ||
| 97 | } | 91 | } |
| 98 | 92 | ||
| 99 | /* load initrd */ | 93 | /* load initrd */ |
loader.c
| @@ -197,7 +197,7 @@ static void *load_at(int fd, int offset, int size) | @@ -197,7 +197,7 @@ static void *load_at(int fd, int offset, int size) | ||
| 197 | int load_elf(const char *filename, int64_t virt_to_phys_addend, | 197 | int load_elf(const char *filename, int64_t virt_to_phys_addend, |
| 198 | uint64_t *pentry) | 198 | uint64_t *pentry) |
| 199 | { | 199 | { |
| 200 | - int fd, data_order, must_swab, ret; | 200 | + int fd, data_order, host_data_order, must_swab, ret; |
| 201 | uint8_t e_ident[EI_NIDENT]; | 201 | uint8_t e_ident[EI_NIDENT]; |
| 202 | 202 | ||
| 203 | fd = open(filename, O_RDONLY | O_BINARY); | 203 | fd = open(filename, O_RDONLY | O_BINARY); |
| @@ -218,7 +218,15 @@ int load_elf(const char *filename, int64_t virt_to_phys_addend, | @@ -218,7 +218,15 @@ int load_elf(const char *filename, int64_t virt_to_phys_addend, | ||
| 218 | data_order = ELFDATA2LSB; | 218 | data_order = ELFDATA2LSB; |
| 219 | #endif | 219 | #endif |
| 220 | must_swab = data_order != e_ident[EI_DATA]; | 220 | must_swab = data_order != e_ident[EI_DATA]; |
| 221 | - | 221 | + |
| 222 | +#ifdef TARGET_WORDS_BIGENDIAN | ||
| 223 | + host_data_order = ELFDATA2MSB; | ||
| 224 | +#else | ||
| 225 | + host_data_order = ELFDATA2LSB; | ||
| 226 | +#endif | ||
| 227 | + if (host_data_order != e_ident[EI_DATA]) | ||
| 228 | + return -1; | ||
| 229 | + | ||
| 222 | lseek(fd, 0, SEEK_SET); | 230 | lseek(fd, 0, SEEK_SET); |
| 223 | if (e_ident[EI_CLASS] == ELFCLASS64) { | 231 | if (e_ident[EI_CLASS] == ELFCLASS64) { |
| 224 | ret = load_elf64(fd, virt_to_phys_addend, must_swab, pentry); | 232 | ret = load_elf64(fd, virt_to_phys_addend, must_swab, pentry); |
target-arm/cpu.h
target-i386/cpu.h
| @@ -36,6 +36,12 @@ | @@ -36,6 +36,12 @@ | ||
| 36 | 36 | ||
| 37 | #define TARGET_HAS_ICE 1 | 37 | #define TARGET_HAS_ICE 1 |
| 38 | 38 | ||
| 39 | +#ifdef TARGET_X86_64 | ||
| 40 | +#define ELF_MACHINE EM_X86_64 | ||
| 41 | +#else | ||
| 42 | +#define ELF_MACHINE EM_386 | ||
| 43 | +#endif | ||
| 44 | + | ||
| 39 | #include "cpu-defs.h" | 45 | #include "cpu-defs.h" |
| 40 | 46 | ||
| 41 | #include "softfloat.h" | 47 | #include "softfloat.h" |
target-m68k/cpu.h
| @@ -31,6 +31,8 @@ | @@ -31,6 +31,8 @@ | ||
| 31 | 31 | ||
| 32 | #define TARGET_HAS_ICE 1 | 32 | #define TARGET_HAS_ICE 1 |
| 33 | 33 | ||
| 34 | +#define ELF_MACHINE EM_68K | ||
| 35 | + | ||
| 34 | #define EXCP_ACCESS 2 /* Access (MMU) error. */ | 36 | #define EXCP_ACCESS 2 /* Access (MMU) error. */ |
| 35 | #define EXCP_ADDRESS 3 /* Address error. */ | 37 | #define EXCP_ADDRESS 3 /* Address error. */ |
| 36 | #define EXCP_ILLEGAL 4 /* Illegal instruction. */ | 38 | #define EXCP_ILLEGAL 4 /* Illegal instruction. */ |
target-mips/cpu.h
target-ppc/cpu.h
| @@ -32,6 +32,8 @@ | @@ -32,6 +32,8 @@ | ||
| 32 | 32 | ||
| 33 | #define TARGET_HAS_ICE 1 | 33 | #define TARGET_HAS_ICE 1 |
| 34 | 34 | ||
| 35 | +#define ELF_MACHINE EM_PPC | ||
| 36 | + | ||
| 35 | /* XXX: this should be tunable: PowerPC 601 & 64 bits PowerPC | 37 | /* XXX: this should be tunable: PowerPC 601 & 64 bits PowerPC |
| 36 | * have different cache line sizes | 38 | * have different cache line sizes |
| 37 | */ | 39 | */ |
target-sh4/cpu.h
| @@ -25,6 +25,8 @@ | @@ -25,6 +25,8 @@ | ||
| 25 | #define TARGET_LONG_BITS 32 | 25 | #define TARGET_LONG_BITS 32 |
| 26 | #define TARGET_HAS_ICE 1 | 26 | #define TARGET_HAS_ICE 1 |
| 27 | 27 | ||
| 28 | +#define ELF_MACHINE EM_SH | ||
| 29 | + | ||
| 28 | #include "cpu-defs.h" | 30 | #include "cpu-defs.h" |
| 29 | 31 | ||
| 30 | #include "softfloat.h" | 32 | #include "softfloat.h" |
target-sparc/cpu.h
| @@ -19,6 +19,12 @@ | @@ -19,6 +19,12 @@ | ||
| 19 | 19 | ||
| 20 | #define TARGET_HAS_ICE 1 | 20 | #define TARGET_HAS_ICE 1 |
| 21 | 21 | ||
| 22 | +#if !defined(TARGET_SPARC64) | ||
| 23 | +#define ELF_MACHINE EM_SPARC | ||
| 24 | +#else | ||
| 25 | +#define ELF_MACHINE EM_SPARCV9 | ||
| 26 | +#endif | ||
| 27 | + | ||
| 22 | /*#define EXCP_INTERRUPT 0x100*/ | 28 | /*#define EXCP_INTERRUPT 0x100*/ |
| 23 | 29 | ||
| 24 | /* trap definitions */ | 30 | /* trap definitions */ |