Commit ce11fedc6ecb6c6bedcff28e2a5ab3a864267245
1 parent
43d4145a
64 bit support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@76 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
124 additions
and
145 deletions
dyngen.c
| ... | ... | @@ -22,25 +22,62 @@ |
| 22 | 22 | #include <string.h> |
| 23 | 23 | #include <stdarg.h> |
| 24 | 24 | #include <inttypes.h> |
| 25 | -#include <elf.h> | |
| 26 | 25 | #include <unistd.h> |
| 27 | 26 | #include <fcntl.h> |
| 28 | 27 | |
| 29 | -#include "thunk.h" | |
| 28 | +#include "config.h" | |
| 29 | + | |
| 30 | +/* elf format definitions. We use these macros to test the CPU to | |
| 31 | + allow cross compilation (this tool must be ran on the build | |
| 32 | + platform) */ | |
| 33 | +#if defined(HOST_I386) | |
| 34 | + | |
| 35 | +#define ELF_CLASS ELFCLASS32 | |
| 36 | +#define ELF_ARCH EM_386 | |
| 37 | +#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) ) | |
| 38 | +#undef ELF_USES_RELOCA | |
| 39 | + | |
| 40 | +#elif defined(HOST_PPC) | |
| 41 | + | |
| 42 | +#define ELF_CLASS ELFCLASS32 | |
| 43 | +#define ELF_ARCH EM_PPC | |
| 44 | +#define elf_check_arch(x) ((x) == EM_PPC) | |
| 45 | +#define ELF_USES_RELOCA | |
| 46 | + | |
| 47 | +#elif defined(HOST_S390) | |
| 48 | + | |
| 49 | +#define ELF_CLASS ELFCLASS32 | |
| 50 | +#define ELF_ARCH EM_S390 | |
| 51 | +#define elf_check_arch(x) ((x) == EM_S390) | |
| 52 | +#define ELF_USES_RELOCA | |
| 30 | 53 | |
| 31 | -/* temporary fix to make it compile with old elf headers (XXX: use | |
| 32 | - included elf.h in all cases) */ | |
| 33 | -#ifndef EM_390 | |
| 34 | -#define EM_S390 22 /* IBM S390 */ | |
| 35 | -#define R_390_8 1 /* Direct 8 bit. */ | |
| 36 | -#define R_390_16 3 /* Direct 16 bit. */ | |
| 37 | -#define R_390_32 4 /* Direct 32 bit. */ | |
| 54 | +#elif defined(HOST_ALPHA) | |
| 55 | + | |
| 56 | +#define ELF_CLASS ELFCLASS64 | |
| 57 | +#define ELF_ARCH EM_ALPHA | |
| 58 | +#define elf_check_arch(x) ((x) == EM_ALPHA) | |
| 59 | +#define ELF_USES_RELOCA | |
| 60 | + | |
| 61 | +#else | |
| 62 | +#error unsupported CPU - please update the code | |
| 63 | +#endif | |
| 64 | + | |
| 65 | +#if ELF_CLASS == ELFCLASS32 | |
| 66 | +typedef int32_t host_long; | |
| 67 | +typedef uint32_t host_ulong; | |
| 68 | +#else | |
| 69 | +typedef int64_t host_long; | |
| 70 | +typedef uint64_t host_ulong; | |
| 38 | 71 | #endif |
| 39 | 72 | |
| 73 | +#include "elf.h" | |
| 74 | + | |
| 75 | +#include "thunk.h" | |
| 76 | + | |
| 40 | 77 | /* all dynamically generated functions begin with this code */ |
| 41 | 78 | #define OP_PREFIX "op_" |
| 42 | 79 | |
| 43 | -int elf_must_swap(Elf32_Ehdr *h) | |
| 80 | +int elf_must_swap(struct elfhdr *h) | |
| 44 | 81 | { |
| 45 | 82 | union { |
| 46 | 83 | uint32_t i; |
| ... | ... | @@ -62,19 +99,25 @@ void swab32s(uint32_t *p) |
| 62 | 99 | *p = bswap32(*p); |
| 63 | 100 | } |
| 64 | 101 | |
| 65 | -void swab64s(uint32_t *p) | |
| 102 | +void swab64s(uint64_t *p) | |
| 66 | 103 | { |
| 67 | 104 | *p = bswap64(*p); |
| 68 | 105 | } |
| 69 | 106 | |
| 70 | -void elf_swap_ehdr(Elf32_Ehdr *h) | |
| 107 | +#if ELF_CLASS == ELFCLASS32 | |
| 108 | +#define swabls(x) swab32s(x) | |
| 109 | +#else | |
| 110 | +#define swabls(x) swab64s(x) | |
| 111 | +#endif | |
| 112 | + | |
| 113 | +void elf_swap_ehdr(struct elfhdr *h) | |
| 71 | 114 | { |
| 72 | 115 | swab16s(&h->e_type); /* Object file type */ |
| 73 | 116 | swab16s(&h-> e_machine); /* Architecture */ |
| 74 | 117 | swab32s(&h-> e_version); /* Object file version */ |
| 75 | - swab32s(&h-> e_entry); /* Entry point virtual address */ | |
| 76 | - swab32s(&h-> e_phoff); /* Program header table file offset */ | |
| 77 | - swab32s(&h-> e_shoff); /* Section header table file offset */ | |
| 118 | + swabls(&h-> e_entry); /* Entry point virtual address */ | |
| 119 | + swabls(&h-> e_phoff); /* Program header table file offset */ | |
| 120 | + swabls(&h-> e_shoff); /* Section header table file offset */ | |
| 78 | 121 | swab32s(&h-> e_flags); /* Processor-specific flags */ |
| 79 | 122 | swab16s(&h-> e_ehsize); /* ELF header size in bytes */ |
| 80 | 123 | swab16s(&h-> e_phentsize); /* Program header table entry size */ |
| ... | ... | @@ -84,34 +127,33 @@ void elf_swap_ehdr(Elf32_Ehdr *h) |
| 84 | 127 | swab16s(&h-> e_shstrndx); /* Section header string table index */ |
| 85 | 128 | } |
| 86 | 129 | |
| 87 | -void elf_swap_shdr(Elf32_Shdr *h) | |
| 130 | +void elf_swap_shdr(struct elf_shdr *h) | |
| 88 | 131 | { |
| 89 | 132 | swab32s(&h-> sh_name); /* Section name (string tbl index) */ |
| 90 | 133 | swab32s(&h-> sh_type); /* Section type */ |
| 91 | - swab32s(&h-> sh_flags); /* Section flags */ | |
| 92 | - swab32s(&h-> sh_addr); /* Section virtual addr at execution */ | |
| 93 | - swab32s(&h-> sh_offset); /* Section file offset */ | |
| 94 | - swab32s(&h-> sh_size); /* Section size in bytes */ | |
| 134 | + swabls(&h-> sh_flags); /* Section flags */ | |
| 135 | + swabls(&h-> sh_addr); /* Section virtual addr at execution */ | |
| 136 | + swabls(&h-> sh_offset); /* Section file offset */ | |
| 137 | + swabls(&h-> sh_size); /* Section size in bytes */ | |
| 95 | 138 | swab32s(&h-> sh_link); /* Link to another section */ |
| 96 | 139 | swab32s(&h-> sh_info); /* Additional section information */ |
| 97 | - swab32s(&h-> sh_addralign); /* Section alignment */ | |
| 98 | - swab32s(&h-> sh_entsize); /* Entry size if section holds table */ | |
| 140 | + swabls(&h-> sh_addralign); /* Section alignment */ | |
| 141 | + swabls(&h-> sh_entsize); /* Entry size if section holds table */ | |
| 99 | 142 | } |
| 100 | 143 | |
| 101 | -void elf_swap_phdr(Elf32_Phdr *h) | |
| 144 | +void elf_swap_phdr(struct elf_phdr *h) | |
| 102 | 145 | { |
| 103 | 146 | swab32s(&h->p_type); /* Segment type */ |
| 104 | - swab32s(&h->p_offset); /* Segment file offset */ | |
| 105 | - swab32s(&h->p_vaddr); /* Segment virtual address */ | |
| 106 | - swab32s(&h->p_paddr); /* Segment physical address */ | |
| 107 | - swab32s(&h->p_filesz); /* Segment size in file */ | |
| 108 | - swab32s(&h->p_memsz); /* Segment size in memory */ | |
| 147 | + swabls(&h->p_offset); /* Segment file offset */ | |
| 148 | + swabls(&h->p_vaddr); /* Segment virtual address */ | |
| 149 | + swabls(&h->p_paddr); /* Segment physical address */ | |
| 150 | + swabls(&h->p_filesz); /* Segment size in file */ | |
| 151 | + swabls(&h->p_memsz); /* Segment size in memory */ | |
| 109 | 152 | swab32s(&h->p_flags); /* Segment flags */ |
| 110 | - swab32s(&h->p_align); /* Segment alignment */ | |
| 153 | + swabls(&h->p_align); /* Segment alignment */ | |
| 111 | 154 | } |
| 112 | 155 | |
| 113 | 156 | int do_swap; |
| 114 | -int e_machine; | |
| 115 | 157 | |
| 116 | 158 | uint16_t get16(uint16_t *p) |
| 117 | 159 | { |
| ... | ... | @@ -157,12 +199,12 @@ void __attribute__((noreturn)) error(const char *fmt, ...) |
| 157 | 199 | } |
| 158 | 200 | |
| 159 | 201 | |
| 160 | -Elf32_Shdr *find_elf_section(Elf32_Shdr *shdr, int shnum, const char *shstr, | |
| 161 | - const char *name) | |
| 202 | +struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr, | |
| 203 | + const char *name) | |
| 162 | 204 | { |
| 163 | 205 | int i; |
| 164 | 206 | const char *shname; |
| 165 | - Elf32_Shdr *sec; | |
| 207 | + struct elf_shdr *sec; | |
| 166 | 208 | |
| 167 | 209 | for(i = 0; i < shnum; i++) { |
| 168 | 210 | sec = &shdr[i]; |
| ... | ... | @@ -209,20 +251,21 @@ int strstart(const char *str, const char *val, const char **ptr) |
| 209 | 251 | #define MAX_ARGS 3 |
| 210 | 252 | |
| 211 | 253 | /* generate op code */ |
| 212 | -void gen_code(const char *name, unsigned long offset, unsigned long size, | |
| 213 | - FILE *outfile, uint8_t *text, void *relocs, int nb_relocs, int reloc_sh_type, | |
| 214 | - Elf32_Sym *symtab, char *strtab, int gen_switch) | |
| 254 | +void gen_code(const char *name, host_ulong offset, host_ulong size, | |
| 255 | + FILE *outfile, uint8_t *text, ELF_RELOC *relocs, int nb_relocs, int reloc_sh_type, | |
| 256 | + ElfW(Sym) *symtab, char *strtab, int gen_switch) | |
| 215 | 257 | { |
| 216 | 258 | int copy_size = 0; |
| 217 | 259 | uint8_t *p_start, *p_end; |
| 218 | - int nb_args, i; | |
| 260 | + int nb_args, i, n; | |
| 219 | 261 | uint8_t args_present[MAX_ARGS]; |
| 220 | 262 | const char *sym_name, *p; |
| 263 | + ELF_RELOC *rel; | |
| 221 | 264 | |
| 222 | 265 | /* compute exact size excluding return instruction */ |
| 223 | 266 | p_start = text + offset; |
| 224 | 267 | p_end = p_start + size; |
| 225 | - switch(e_machine) { | |
| 268 | + switch(ELF_ARCH) { | |
| 226 | 269 | case EM_386: |
| 227 | 270 | { |
| 228 | 271 | uint8_t *p; |
| ... | ... | @@ -256,40 +299,20 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, |
| 256 | 299 | copy_size = p - p_start; |
| 257 | 300 | } |
| 258 | 301 | break; |
| 259 | - default: | |
| 260 | - error("unsupported CPU (%d)", e_machine); | |
| 261 | 302 | } |
| 262 | 303 | |
| 263 | 304 | /* compute the number of arguments by looking at the relocations */ |
| 264 | 305 | for(i = 0;i < MAX_ARGS; i++) |
| 265 | 306 | args_present[i] = 0; |
| 266 | 307 | |
| 267 | - if (reloc_sh_type == SHT_REL) { | |
| 268 | - Elf32_Rel *rel; | |
| 269 | - int n; | |
| 270 | - for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { | |
| 271 | - if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { | |
| 272 | - sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; | |
| 273 | - if (strstart(sym_name, "__op_param", &p)) { | |
| 274 | - n = strtoul(p, NULL, 10); | |
| 275 | - if (n >= MAX_ARGS) | |
| 276 | - error("too many arguments in %s", name); | |
| 277 | - args_present[n - 1] = 1; | |
| 278 | - } | |
| 279 | - } | |
| 280 | - } | |
| 281 | - } else { | |
| 282 | - Elf32_Rela *rel; | |
| 283 | - int n; | |
| 284 | - for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { | |
| 285 | - if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { | |
| 286 | - sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; | |
| 287 | - if (strstart(sym_name, "__op_param", &p)) { | |
| 288 | - n = strtoul(p, NULL, 10); | |
| 289 | - if (n >= MAX_ARGS) | |
| 290 | - error("too many arguments in %s", name); | |
| 291 | - args_present[n - 1] = 1; | |
| 292 | - } | |
| 308 | + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { | |
| 309 | + if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { | |
| 310 | + sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name; | |
| 311 | + if (strstart(sym_name, "__op_param", &p)) { | |
| 312 | + n = strtoul(p, NULL, 10); | |
| 313 | + if (n >= MAX_ARGS) | |
| 314 | + error("too many arguments in %s", name); | |
| 315 | + args_present[n - 1] = 1; | |
| 293 | 316 | } |
| 294 | 317 | } |
| 295 | 318 | } |
| ... | ... | @@ -319,24 +342,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, |
| 319 | 342 | } |
| 320 | 343 | fprintf(outfile, " extern void %s();\n", name); |
| 321 | 344 | |
| 322 | - if (reloc_sh_type == SHT_REL) { | |
| 323 | - Elf32_Rel *rel; | |
| 324 | - for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { | |
| 325 | - if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { | |
| 326 | - sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; | |
| 327 | - if (!strstart(sym_name, "__op_param", &p)) { | |
| 328 | - fprintf(outfile, "extern char %s;\n", sym_name); | |
| 329 | - } | |
| 330 | - } | |
| 331 | - } | |
| 332 | - } else { | |
| 333 | - Elf32_Rela *rel; | |
| 334 | - for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { | |
| 335 | - if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { | |
| 336 | - sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; | |
| 337 | - if (!strstart(sym_name, "__op_param", &p)) { | |
| 338 | - fprintf(outfile, "extern char %s;\n", sym_name); | |
| 339 | - } | |
| 345 | + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { | |
| 346 | + if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { | |
| 347 | + sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; | |
| 348 | + if (!strstart(sym_name, "__op_param", &p)) { | |
| 349 | + fprintf(outfile, "extern char %s;\n", sym_name); | |
| 340 | 350 | } |
| 341 | 351 | } |
| 342 | 352 | } |
| ... | ... | @@ -347,13 +357,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, |
| 347 | 357 | } |
| 348 | 358 | |
| 349 | 359 | /* patch relocations */ |
| 350 | - switch(e_machine) { | |
| 351 | - case EM_386: | |
| 360 | +#if defined(HOST_I386) | |
| 352 | 361 | { |
| 353 | - Elf32_Rel *rel; | |
| 354 | 362 | char name[256]; |
| 355 | 363 | int type; |
| 356 | - long addend; | |
| 364 | + int addend; | |
| 357 | 365 | for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { |
| 358 | 366 | if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { |
| 359 | 367 | sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; |
| ... | ... | @@ -366,11 +374,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, |
| 366 | 374 | addend = get32((uint32_t *)(text + rel->r_offset)); |
| 367 | 375 | switch(type) { |
| 368 | 376 | case R_386_32: |
| 369 | - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n", | |
| 377 | + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n", | |
| 370 | 378 | rel->r_offset - offset, name, addend); |
| 371 | 379 | break; |
| 372 | 380 | case R_386_PC32: |
| 373 | - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s - (long)(gen_code_ptr + %ld) + %ld;\n", | |
| 381 | + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n", | |
| 374 | 382 | rel->r_offset - offset, name, rel->r_offset - offset, addend); |
| 375 | 383 | break; |
| 376 | 384 | default: |
| ... | ... | @@ -379,13 +387,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, |
| 379 | 387 | } |
| 380 | 388 | } |
| 381 | 389 | } |
| 382 | - break; | |
| 383 | - case EM_PPC: | |
| 390 | +#elif defined(HOST_PPC) | |
| 384 | 391 | { |
| 385 | - Elf32_Rela *rel; | |
| 386 | 392 | char name[256]; |
| 387 | 393 | int type; |
| 388 | - long addend; | |
| 394 | + int addend; | |
| 389 | 395 | for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { |
| 390 | 396 | if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { |
| 391 | 397 | sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; |
| ... | ... | @@ -398,24 +404,24 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, |
| 398 | 404 | addend = rel->r_addend; |
| 399 | 405 | switch(type) { |
| 400 | 406 | case R_PPC_ADDR32: |
| 401 | - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n", | |
| 407 | + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n", | |
| 402 | 408 | rel->r_offset - offset, name, addend); |
| 403 | 409 | break; |
| 404 | 410 | case R_PPC_ADDR16_LO: |
| 405 | - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld);\n", | |
| 411 | + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n", | |
| 406 | 412 | rel->r_offset - offset, name, addend); |
| 407 | 413 | break; |
| 408 | 414 | case R_PPC_ADDR16_HI: |
| 409 | - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld) >> 16;\n", | |
| 415 | + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n", | |
| 410 | 416 | rel->r_offset - offset, name, addend); |
| 411 | 417 | break; |
| 412 | 418 | case R_PPC_ADDR16_HA: |
| 413 | - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld + 0x8000) >> 16;\n", | |
| 419 | + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n", | |
| 414 | 420 | rel->r_offset - offset, name, addend); |
| 415 | 421 | break; |
| 416 | 422 | case R_PPC_REL24: |
| 417 | 423 | /* warning: must be at 32 MB distancy */ |
| 418 | - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = (*(uint32_t *)(gen_code_ptr + %ld) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %ld) + %ld) & 0x03fffffc);\n", | |
| 424 | + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n", | |
| 419 | 425 | rel->r_offset - offset, rel->r_offset - offset, name, rel->r_offset - offset, addend); |
| 420 | 426 | break; |
| 421 | 427 | default: |
| ... | ... | @@ -424,13 +430,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, |
| 424 | 430 | } |
| 425 | 431 | } |
| 426 | 432 | } |
| 427 | - break; | |
| 428 | - case EM_S390: | |
| 433 | +#elif defined(HOST_S390) | |
| 429 | 434 | { |
| 430 | - Elf32_Rela *rel; | |
| 431 | 435 | char name[256]; |
| 432 | 436 | int type; |
| 433 | - long addend; | |
| 437 | + int addend; | |
| 434 | 438 | for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { |
| 435 | 439 | if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { |
| 436 | 440 | sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; |
| ... | ... | @@ -443,15 +447,15 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, |
| 443 | 447 | addend = rel->r_addend; |
| 444 | 448 | switch(type) { |
| 445 | 449 | case R_390_32: |
| 446 | - fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n", | |
| 450 | + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n", | |
| 447 | 451 | rel->r_offset - offset, name, addend); |
| 448 | 452 | break; |
| 449 | 453 | case R_390_16: |
| 450 | - fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = %s + %ld;\n", | |
| 454 | + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %d) = %s + %d;\n", | |
| 451 | 455 | rel->r_offset - offset, name, addend); |
| 452 | 456 | break; |
| 453 | 457 | case R_390_8: |
| 454 | - fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %ld) = %s + %ld;\n", | |
| 458 | + fprintf(outfile, " *(uint8_t *)(gen_code_ptr + %d) = %s + %d;\n", | |
| 455 | 459 | rel->r_offset - offset, name, addend); |
| 456 | 460 | break; |
| 457 | 461 | default: |
| ... | ... | @@ -460,10 +464,9 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, |
| 460 | 464 | } |
| 461 | 465 | } |
| 462 | 466 | } |
| 463 | - break; | |
| 464 | - default: | |
| 465 | - error("unsupported CPU for relocations (%d)", e_machine); | |
| 466 | - } | |
| 467 | +#else | |
| 468 | +#error unsupported CPU | |
| 469 | +#endif | |
| 467 | 470 | fprintf(outfile, " gen_code_ptr += %d;\n", copy_size); |
| 468 | 471 | fprintf(outfile, "}\n"); |
| 469 | 472 | fprintf(outfile, "break;\n\n"); |
| ... | ... | @@ -492,11 +495,10 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, |
| 492 | 495 | int load_elf(const char *filename, FILE *outfile, int do_print_enum) |
| 493 | 496 | { |
| 494 | 497 | int fd; |
| 495 | - Elf32_Ehdr ehdr; | |
| 496 | - Elf32_Shdr *sec, *shdr, *symtab_sec, *strtab_sec, *text_sec; | |
| 498 | + struct elfhdr ehdr; | |
| 499 | + struct elf_shdr *sec, *shdr, *symtab_sec, *strtab_sec, *text_sec; | |
| 497 | 500 | int i, j, nb_syms; |
| 498 | - Elf32_Sym *symtab, *sym; | |
| 499 | - const char *cpu_name; | |
| 501 | + ElfW(Sym) *symtab, *sym; | |
| 500 | 502 | char *shstr, *strtab; |
| 501 | 503 | uint8_t *text; |
| 502 | 504 | void *relocs; |
| ... | ... | @@ -515,7 +517,6 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum) |
| 515 | 517 | || ehdr.e_ident[EI_MAG1] != ELFMAG1 |
| 516 | 518 | || ehdr.e_ident[EI_MAG2] != ELFMAG2 |
| 517 | 519 | || ehdr.e_ident[EI_MAG3] != ELFMAG3 |
| 518 | - || ehdr.e_ident[EI_CLASS] != ELFCLASS32 | |
| 519 | 520 | || ehdr.e_ident[EI_VERSION] != EV_CURRENT) { |
| 520 | 521 | error("bad ELF header"); |
| 521 | 522 | } |
| ... | ... | @@ -523,14 +524,17 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum) |
| 523 | 524 | do_swap = elf_must_swap(&ehdr); |
| 524 | 525 | if (do_swap) |
| 525 | 526 | elf_swap_ehdr(&ehdr); |
| 527 | + if (ehdr.e_ident[EI_CLASS] != ELF_CLASS) | |
| 528 | + error("Unsupported ELF class"); | |
| 526 | 529 | if (ehdr.e_type != ET_REL) |
| 527 | 530 | error("ELF object file expected"); |
| 528 | 531 | if (ehdr.e_version != EV_CURRENT) |
| 529 | 532 | error("Invalid ELF version"); |
| 530 | - e_machine = ehdr.e_machine; | |
| 533 | + if (!elf_check_arch(ehdr.e_machine)) | |
| 534 | + error("Unsupported CPU (e_machine=%d)", ehdr.e_machine); | |
| 531 | 535 | |
| 532 | 536 | /* read section headers */ |
| 533 | - shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(Elf32_Shdr)); | |
| 537 | + shdr = load_data(fd, ehdr.e_shoff, ehdr.e_shnum * sizeof(struct elf_shdr)); | |
| 534 | 538 | if (do_swap) { |
| 535 | 539 | for(i = 0; i < ehdr.e_shnum; i++) { |
| 536 | 540 | elf_swap_shdr(&shdr[i]); |
| ... | ... | @@ -590,35 +594,12 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum) |
| 590 | 594 | if (do_swap) { |
| 591 | 595 | for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { |
| 592 | 596 | swab32s(&sym->st_name); |
| 593 | - swab32s(&sym->st_value); | |
| 594 | - swab32s(&sym->st_size); | |
| 597 | + swabls(&sym->st_value); | |
| 598 | + swabls(&sym->st_size); | |
| 595 | 599 | swab16s(&sym->st_shndx); |
| 596 | 600 | } |
| 597 | 601 | } |
| 598 | 602 | |
| 599 | - switch(e_machine) { | |
| 600 | - case EM_386: | |
| 601 | - cpu_name = "i386"; | |
| 602 | - break; | |
| 603 | - case EM_PPC: | |
| 604 | - cpu_name = "ppc"; | |
| 605 | - break; | |
| 606 | - case EM_MIPS: | |
| 607 | - cpu_name = "mips"; | |
| 608 | - break; | |
| 609 | - case EM_ARM: | |
| 610 | - cpu_name = "arm"; | |
| 611 | - break; | |
| 612 | - case EM_SPARC: | |
| 613 | - cpu_name = "sparc"; | |
| 614 | - break; | |
| 615 | - case EM_S390: | |
| 616 | - cpu_name = "s390"; | |
| 617 | - break; | |
| 618 | - default: | |
| 619 | - error("unsupported CPU (e_machine=%d)", e_machine); | |
| 620 | - } | |
| 621 | - | |
| 622 | 603 | if (do_print_enum) { |
| 623 | 604 | fprintf(outfile, "DEF(end, 0)\n"); |
| 624 | 605 | for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { |
| ... | ... | @@ -669,7 +650,7 @@ fprintf(outfile, |
| 669 | 650 | ); |
| 670 | 651 | |
| 671 | 652 | /* generate a return */ |
| 672 | - switch(e_machine) { | |
| 653 | + switch(ELF_ARCH) { | |
| 673 | 654 | case EM_386: |
| 674 | 655 | fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n"); |
| 675 | 656 | break; |
| ... | ... | @@ -679,8 +660,6 @@ fprintf(outfile, |
| 679 | 660 | case EM_S390: |
| 680 | 661 | fprintf(outfile, "*((uint16_t *)gen_code_ptr)++ = 0x07fe; /* br %%r14 */\n"); |
| 681 | 662 | break; |
| 682 | - default: | |
| 683 | - error("no return generation for cpu '%s'", cpu_name); | |
| 684 | 663 | } |
| 685 | 664 | |
| 686 | 665 | fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n"); | ... | ... |