Commit ce11fedc6ecb6c6bedcff28e2a5ab3a864267245

Authored by bellard
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,25 +22,62 @@
22 #include <string.h> 22 #include <string.h>
23 #include <stdarg.h> 23 #include <stdarg.h>
24 #include <inttypes.h> 24 #include <inttypes.h>
25 -#include <elf.h>  
26 #include <unistd.h> 25 #include <unistd.h>
27 #include <fcntl.h> 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 #endif 71 #endif
39 72
  73 +#include "elf.h"
  74 +
  75 +#include "thunk.h"
  76 +
40 /* all dynamically generated functions begin with this code */ 77 /* all dynamically generated functions begin with this code */
41 #define OP_PREFIX "op_" 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 union { 82 union {
46 uint32_t i; 83 uint32_t i;
@@ -62,19 +99,25 @@ void swab32s(uint32_t *p) @@ -62,19 +99,25 @@ void swab32s(uint32_t *p)
62 *p = bswap32(*p); 99 *p = bswap32(*p);
63 } 100 }
64 101
65 -void swab64s(uint32_t *p) 102 +void swab64s(uint64_t *p)
66 { 103 {
67 *p = bswap64(*p); 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 swab16s(&h->e_type); /* Object file type */ 115 swab16s(&h->e_type); /* Object file type */
73 swab16s(&h-> e_machine); /* Architecture */ 116 swab16s(&h-> e_machine); /* Architecture */
74 swab32s(&h-> e_version); /* Object file version */ 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 swab32s(&h-> e_flags); /* Processor-specific flags */ 121 swab32s(&h-> e_flags); /* Processor-specific flags */
79 swab16s(&h-> e_ehsize); /* ELF header size in bytes */ 122 swab16s(&h-> e_ehsize); /* ELF header size in bytes */
80 swab16s(&h-> e_phentsize); /* Program header table entry size */ 123 swab16s(&h-> e_phentsize); /* Program header table entry size */
@@ -84,34 +127,33 @@ void elf_swap_ehdr(Elf32_Ehdr *h) @@ -84,34 +127,33 @@ void elf_swap_ehdr(Elf32_Ehdr *h)
84 swab16s(&h-> e_shstrndx); /* Section header string table index */ 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 swab32s(&h-> sh_name); /* Section name (string tbl index) */ 132 swab32s(&h-> sh_name); /* Section name (string tbl index) */
90 swab32s(&h-> sh_type); /* Section type */ 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 swab32s(&h-> sh_link); /* Link to another section */ 138 swab32s(&h-> sh_link); /* Link to another section */
96 swab32s(&h-> sh_info); /* Additional section information */ 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 swab32s(&h->p_type); /* Segment type */ 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 swab32s(&h->p_flags); /* Segment flags */ 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 int do_swap; 156 int do_swap;
114 -int e_machine;  
115 157
116 uint16_t get16(uint16_t *p) 158 uint16_t get16(uint16_t *p)
117 { 159 {
@@ -157,12 +199,12 @@ void __attribute__((noreturn)) error(const char *fmt, ...) @@ -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 int i; 205 int i;
164 const char *shname; 206 const char *shname;
165 - Elf32_Shdr *sec; 207 + struct elf_shdr *sec;
166 208
167 for(i = 0; i < shnum; i++) { 209 for(i = 0; i < shnum; i++) {
168 sec = &shdr[i]; 210 sec = &shdr[i];
@@ -209,20 +251,21 @@ int strstart(const char *str, const char *val, const char **ptr) @@ -209,20 +251,21 @@ int strstart(const char *str, const char *val, const char **ptr)
209 #define MAX_ARGS 3 251 #define MAX_ARGS 3
210 252
211 /* generate op code */ 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 int copy_size = 0; 258 int copy_size = 0;
217 uint8_t *p_start, *p_end; 259 uint8_t *p_start, *p_end;
218 - int nb_args, i; 260 + int nb_args, i, n;
219 uint8_t args_present[MAX_ARGS]; 261 uint8_t args_present[MAX_ARGS];
220 const char *sym_name, *p; 262 const char *sym_name, *p;
  263 + ELF_RELOC *rel;
221 264
222 /* compute exact size excluding return instruction */ 265 /* compute exact size excluding return instruction */
223 p_start = text + offset; 266 p_start = text + offset;
224 p_end = p_start + size; 267 p_end = p_start + size;
225 - switch(e_machine) { 268 + switch(ELF_ARCH) {
226 case EM_386: 269 case EM_386:
227 { 270 {
228 uint8_t *p; 271 uint8_t *p;
@@ -256,40 +299,20 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, @@ -256,40 +299,20 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
256 copy_size = p - p_start; 299 copy_size = p - p_start;
257 } 300 }
258 break; 301 break;
259 - default:  
260 - error("unsupported CPU (%d)", e_machine);  
261 } 302 }
262 303
263 /* compute the number of arguments by looking at the relocations */ 304 /* compute the number of arguments by looking at the relocations */
264 for(i = 0;i < MAX_ARGS; i++) 305 for(i = 0;i < MAX_ARGS; i++)
265 args_present[i] = 0; 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,24 +342,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
319 } 342 }
320 fprintf(outfile, " extern void %s();\n", name); 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,13 +357,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
347 } 357 }
348 358
349 /* patch relocations */ 359 /* patch relocations */
350 - switch(e_machine) {  
351 - case EM_386: 360 +#if defined(HOST_I386)
352 { 361 {
353 - Elf32_Rel *rel;  
354 char name[256]; 362 char name[256];
355 int type; 363 int type;
356 - long addend; 364 + int addend;
357 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { 365 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
358 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { 366 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
359 sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; 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,11 +374,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
366 addend = get32((uint32_t *)(text + rel->r_offset)); 374 addend = get32((uint32_t *)(text + rel->r_offset));
367 switch(type) { 375 switch(type) {
368 case R_386_32: 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 rel->r_offset - offset, name, addend); 378 rel->r_offset - offset, name, addend);
371 break; 379 break;
372 case R_386_PC32: 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 rel->r_offset - offset, name, rel->r_offset - offset, addend); 382 rel->r_offset - offset, name, rel->r_offset - offset, addend);
375 break; 383 break;
376 default: 384 default:
@@ -379,13 +387,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, @@ -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 char name[256]; 392 char name[256];
387 int type; 393 int type;
388 - long addend; 394 + int addend;
389 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { 395 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
390 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { 396 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
391 sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; 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,24 +404,24 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
398 addend = rel->r_addend; 404 addend = rel->r_addend;
399 switch(type) { 405 switch(type) {
400 case R_PPC_ADDR32: 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 rel->r_offset - offset, name, addend); 408 rel->r_offset - offset, name, addend);
403 break; 409 break;
404 case R_PPC_ADDR16_LO: 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 rel->r_offset - offset, name, addend); 412 rel->r_offset - offset, name, addend);
407 break; 413 break;
408 case R_PPC_ADDR16_HI: 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 rel->r_offset - offset, name, addend); 416 rel->r_offset - offset, name, addend);
411 break; 417 break;
412 case R_PPC_ADDR16_HA: 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 rel->r_offset - offset, name, addend); 420 rel->r_offset - offset, name, addend);
415 break; 421 break;
416 case R_PPC_REL24: 422 case R_PPC_REL24:
417 /* warning: must be at 32 MB distancy */ 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 rel->r_offset - offset, rel->r_offset - offset, name, rel->r_offset - offset, addend); 425 rel->r_offset - offset, rel->r_offset - offset, name, rel->r_offset - offset, addend);
420 break; 426 break;
421 default: 427 default:
@@ -424,13 +430,11 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, @@ -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 char name[256]; 435 char name[256];
432 int type; 436 int type;
433 - long addend; 437 + int addend;
434 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) { 438 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
435 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) { 439 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
436 sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name; 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,15 +447,15 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
443 addend = rel->r_addend; 447 addend = rel->r_addend;
444 switch(type) { 448 switch(type) {
445 case R_390_32: 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 rel->r_offset - offset, name, addend); 451 rel->r_offset - offset, name, addend);
448 break; 452 break;
449 case R_390_16: 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 rel->r_offset - offset, name, addend); 455 rel->r_offset - offset, name, addend);
452 break; 456 break;
453 case R_390_8: 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 rel->r_offset - offset, name, addend); 459 rel->r_offset - offset, name, addend);
456 break; 460 break;
457 default: 461 default:
@@ -460,10 +464,9 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, @@ -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 fprintf(outfile, " gen_code_ptr += %d;\n", copy_size); 470 fprintf(outfile, " gen_code_ptr += %d;\n", copy_size);
468 fprintf(outfile, "}\n"); 471 fprintf(outfile, "}\n");
469 fprintf(outfile, "break;\n\n"); 472 fprintf(outfile, "break;\n\n");
@@ -492,11 +495,10 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, @@ -492,11 +495,10 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
492 int load_elf(const char *filename, FILE *outfile, int do_print_enum) 495 int load_elf(const char *filename, FILE *outfile, int do_print_enum)
493 { 496 {
494 int fd; 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 int i, j, nb_syms; 500 int i, j, nb_syms;
498 - Elf32_Sym *symtab, *sym;  
499 - const char *cpu_name; 501 + ElfW(Sym) *symtab, *sym;
500 char *shstr, *strtab; 502 char *shstr, *strtab;
501 uint8_t *text; 503 uint8_t *text;
502 void *relocs; 504 void *relocs;
@@ -515,7 +517,6 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum) @@ -515,7 +517,6 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
515 || ehdr.e_ident[EI_MAG1] != ELFMAG1 517 || ehdr.e_ident[EI_MAG1] != ELFMAG1
516 || ehdr.e_ident[EI_MAG2] != ELFMAG2 518 || ehdr.e_ident[EI_MAG2] != ELFMAG2
517 || ehdr.e_ident[EI_MAG3] != ELFMAG3 519 || ehdr.e_ident[EI_MAG3] != ELFMAG3
518 - || ehdr.e_ident[EI_CLASS] != ELFCLASS32  
519 || ehdr.e_ident[EI_VERSION] != EV_CURRENT) { 520 || ehdr.e_ident[EI_VERSION] != EV_CURRENT) {
520 error("bad ELF header"); 521 error("bad ELF header");
521 } 522 }
@@ -523,14 +524,17 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum) @@ -523,14 +524,17 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
523 do_swap = elf_must_swap(&ehdr); 524 do_swap = elf_must_swap(&ehdr);
524 if (do_swap) 525 if (do_swap)
525 elf_swap_ehdr(&ehdr); 526 elf_swap_ehdr(&ehdr);
  527 + if (ehdr.e_ident[EI_CLASS] != ELF_CLASS)
  528 + error("Unsupported ELF class");
526 if (ehdr.e_type != ET_REL) 529 if (ehdr.e_type != ET_REL)
527 error("ELF object file expected"); 530 error("ELF object file expected");
528 if (ehdr.e_version != EV_CURRENT) 531 if (ehdr.e_version != EV_CURRENT)
529 error("Invalid ELF version"); 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 /* read section headers */ 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 if (do_swap) { 538 if (do_swap) {
535 for(i = 0; i < ehdr.e_shnum; i++) { 539 for(i = 0; i < ehdr.e_shnum; i++) {
536 elf_swap_shdr(&shdr[i]); 540 elf_swap_shdr(&shdr[i]);
@@ -590,35 +594,12 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum) @@ -590,35 +594,12 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
590 if (do_swap) { 594 if (do_swap) {
591 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { 595 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
592 swab32s(&sym->st_name); 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 swab16s(&sym->st_shndx); 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 if (do_print_enum) { 603 if (do_print_enum) {
623 fprintf(outfile, "DEF(end, 0)\n"); 604 fprintf(outfile, "DEF(end, 0)\n");
624 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { 605 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
@@ -669,7 +650,7 @@ fprintf(outfile, @@ -669,7 +650,7 @@ fprintf(outfile,
669 ); 650 );
670 651
671 /* generate a return */ 652 /* generate a return */
672 - switch(e_machine) { 653 + switch(ELF_ARCH) {
673 case EM_386: 654 case EM_386:
674 fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n"); 655 fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n");
675 break; 656 break;
@@ -679,8 +660,6 @@ fprintf(outfile, @@ -679,8 +660,6 @@ fprintf(outfile,
679 case EM_S390: 660 case EM_S390:
680 fprintf(outfile, "*((uint16_t *)gen_code_ptr)++ = 0x07fe; /* br %%r14 */\n"); 661 fprintf(outfile, "*((uint16_t *)gen_code_ptr)++ = 0x07fe; /* br %%r14 */\n");
681 break; 662 break;
682 - default:  
683 - error("no return generation for cpu '%s'", cpu_name);  
684 } 663 }
685 664
686 fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n"); 665 fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n");