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"); | ... | ... |