25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: file_elf.c,v 1.1 2007/04/10 16:33:44 debug Exp $ |
* $Id: file_elf.c,v 1.7 2007/07/20 09:03:33 debug Exp $ |
29 |
* |
* |
30 |
* ELF file support. |
* COMMENT: ELF file support |
31 |
*/ |
*/ |
32 |
|
|
33 |
/* Note: Included from file.c. */ |
/* Note: Included from file.c. */ |
36 |
#include "exec_elf.h" |
#include "exec_elf.h" |
37 |
|
|
38 |
/* ELF machine types as strings: (same as exec_elf.h) */ |
/* ELF machine types as strings: (same as exec_elf.h) */ |
39 |
#define N_ELF_MACHINE_TYPES 84 |
#define N_ELF_MACHINE_TYPES 89 |
40 |
static char *elf_machine_type[N_ELF_MACHINE_TYPES] = { |
static char *elf_machine_type[N_ELF_MACHINE_TYPES] = { |
41 |
"NONE", "M32", "SPARC", "386", /* 0..3 */ |
"NONE", "M32", "SPARC", "386", /* 0..3 */ |
42 |
"68K", "88K", "486", "860", /* 4..7 */ |
"68K", "88K", "486", "860", /* 4..7 */ |
43 |
"MIPS", "S370", "MIPS_RS3_LE", "RS6000", /* 8..11 */ |
"MIPS", "S370", "MIPS_RS3_LE", "RS6000", /* 8..11 */ |
44 |
"unknown12", "unknown13", "unknown14", "PARISC", /* 12..15 */ |
"unknown12", "unknown13", "unknown14", "PARISC", /* 12..15 */ |
45 |
"NCUBE", "VPP500", "SPARC32PLUS", "960", /* 16..19 */ |
"NCUBE", "VPP500", "SPARC32PLUS", "960", /* 16..19 */ |
46 |
"PPC", "PPC64", "unknown22", "unknown23", /* 20..23 */ |
"PPC", "PPC64", "unknown22", "unknown23", /* 20..23 */ |
47 |
"unknown24", "unknown25", "unknown26", "unknown27", /* 24..27 */ |
"unknown24", "unknown25", "unknown26", "unknown27", /* 24..27 */ |
48 |
"unknown28", "unknown29", "unknown30", "unknown31", /* 28..31 */ |
"unknown28", "unknown29", "unknown30", "unknown31", /* 28..31 */ |
49 |
"unknown32", "unknown33", "unknown34", "unknown35", /* 32..35 */ |
"unknown32", "unknown33", "unknown34", "unknown35", /* 32..35 */ |
50 |
"V800", "FR20", "RH32", "RCE", /* 36..39 */ |
"V800", "FR20", "RH32", "RCE", /* 36..39 */ |
51 |
"ARM", "ALPHA", "SH", "SPARCV9", /* 40..43 */ |
"ARM", "ALPHA", "SH", "SPARCV9", /* 40..43 */ |
52 |
"TRICORE", "ARC", "H8_300", "H8_300H", /* 44..47 */ |
"TRICORE", "ARC", "H8_300", "H8_300H", /* 44..47 */ |
53 |
"H8S", "H8_500", "IA_64", "MIPS_X", /* 48..51 */ |
"H8S", "H8_500", "IA_64", "MIPS_X", /* 48..51 */ |
54 |
"COLDFIRE", "68HC12", "unknown54", "unknown55", /* 52..55 */ |
"COLDFIRE", "68HC12", "unknown54", "unknown55", /* 52..55 */ |
55 |
"unknown56", "unknown57", "unknown58", "unknown59", /* 56..59 */ |
"unknown56", "unknown57", "unknown58", "unknown59", /* 56..59 */ |
56 |
"unknown60", "unknown61", "AMD64", "unknown63", /* 60..63 */ |
"unknown60", "unknown61", "AMD64", "unknown63", /* 60..63 */ |
57 |
"unknown64", "unknown65", "unknown66", "unknown67", /* 64..67 */ |
"unknown64", "unknown65", "unknown66", "unknown67", /* 64..67 */ |
58 |
"unknown68", "unknown69", "unknown70", "unknown71", /* 68..71 */ |
"unknown68", "unknown69", "unknown70", "unknown71", /* 68..71 */ |
59 |
"unknown72", "unknown73", "unknown74", "unknown75", /* 72..75 */ |
"unknown72", "unknown73", "unknown74", "unknown75", /* 72..75 */ |
60 |
"unknown76", "unknown77", "unknown78", "unknown79", /* 76..79 */ |
"unknown76", "unknown77", "unknown78", "unknown79", /* 76..79 */ |
61 |
"unknown80", "unknown81", "unknown82", "AVR" /* 80..83 */ |
"unknown80", "unknown81", "unknown82", "AVR", /* 80..83 */ |
62 |
|
"unknown84", "unknown85", "unknown86", "unknown87", /* 84..87 */ |
63 |
|
"M32R" /* 88 */ |
64 |
}; |
}; |
65 |
|
|
66 |
|
|
217 |
ok = 1; |
ok = 1; |
218 |
} |
} |
219 |
break; |
break; |
220 |
case ARCH_AVR: |
/* case ARCH_AVR: |
221 |
switch (emachine) { |
switch (emachine) { |
222 |
case EM_AVR: |
case EM_AVR: |
223 |
ok = 1; |
ok = 1; |
224 |
} |
} |
225 |
break; |
break; |
226 |
/* case ARCH_AVR32: |
case ARCH_AVR32: |
227 |
switch (emachine) { |
switch (emachine) { |
228 |
case 6317: |
case 6317: |
229 |
ok = 1; |
ok = 1; |
246 |
case EM_IA_64: |
case EM_IA_64: |
247 |
ok = 1; |
ok = 1; |
248 |
} |
} |
249 |
break; */ |
break; |
250 |
case ARCH_M68K: |
case ARCH_M68K: |
251 |
switch (emachine) { |
switch (emachine) { |
252 |
case EM_68K: |
case EM_68K: |
253 |
ok = 1; |
ok = 1; |
254 |
} |
} |
255 |
|
break; */ |
256 |
|
case ARCH_M32R: |
257 |
|
switch (emachine) { |
258 |
|
case EM_M32R: |
259 |
|
ok = 1; |
260 |
|
} |
261 |
break; |
break; |
262 |
case ARCH_MIPS: |
case ARCH_MIPS: |
263 |
switch (emachine) { |
switch (emachine) { |
319 |
debug("ELF%i %s, %s 0x", elf64? 64 : 32, |
debug("ELF%i %s, %s 0x", elf64? 64 : 32, |
320 |
encoding == ELFDATA2LSB? "LSB (LE)" : "MSB (BE)", s); |
encoding == ELFDATA2LSB? "LSB (LE)" : "MSB (BE)", s); |
321 |
|
|
322 |
|
// XXX force load address to 0 |
323 |
|
eentry -= 0xc0000000; |
324 |
|
|
325 |
if (elf64) |
if (elf64) |
326 |
debug("%016"PRIx64"\n", (uint64_t) eentry); |
debug("%016"PRIx64"\n", (uint64_t) eentry); |
327 |
else |
else |
331 |
* SH64: 32-bit instruction encoding? |
* SH64: 32-bit instruction encoding? |
332 |
*/ |
*/ |
333 |
if (arch == ARCH_SH && (eentry & 1)) { |
if (arch == ARCH_SH && (eentry & 1)) { |
334 |
debug("SH64: 32-bit instruction encoding\n"); |
fatal("SH64: 32-bit instruction encoding: TODO\n"); |
335 |
m->cpus[0]->cd.sh.compact = 0; |
/* m->cpus[0]->cd.sh.compact = 0; */ |
336 |
m->cpus[0]->cd.sh.cpu_type.bits = 64; |
m->cpus[0]->cd.sh.cpu_type.bits = 64; |
337 |
|
exit(1); |
338 |
} |
} |
339 |
|
|
340 |
/* Read the program headers: */ |
/* Read the program headers: */ |
433 |
if ((p_vaddr & 0xffff)==0) align_len = 0x10000; |
if ((p_vaddr & 0xffff)==0) align_len = 0x10000; |
434 |
ofs = 0; len = chunk_len = align_len; |
ofs = 0; len = chunk_len = align_len; |
435 |
while (ofs < (int64_t)p_filesz && len==chunk_len) { |
while (ofs < (int64_t)p_filesz && len==chunk_len) { |
436 |
unsigned char *ch = malloc(chunk_len); |
unsigned char *ch; |
437 |
int i = 0; |
int i = 0; |
438 |
|
|
439 |
|
CHECK_ALLOCATION(ch = malloc(chunk_len)); |
440 |
|
|
441 |
/* Switch to larger size, if possible: */ |
/* Switch to larger size, if possible: */ |
442 |
if (align_len < 0x10000 && |
if (align_len < 0x10000 && |
443 |
((p_vaddr + ofs) & 0xffff)==0) { |
((p_vaddr + ofs) & 0xffff)==0) { |
444 |
align_len = 0x10000; |
align_len = 0x10000; |
445 |
len = chunk_len = align_len; |
len = chunk_len = align_len; |
446 |
free(ch); |
free(ch); |
447 |
ch = malloc(chunk_len); |
CHECK_ALLOCATION(ch=malloc(chunk_len)); |
448 |
} else if (align_len < 0x1000 && |
} else if (align_len < 0x1000 && |
449 |
((p_vaddr + ofs) & 0xfff)==0) { |
((p_vaddr + ofs) & 0xfff)==0) { |
450 |
align_len = 0x1000; |
align_len = 0x1000; |
451 |
len = chunk_len = align_len; |
len = chunk_len = align_len; |
452 |
free(ch); |
free(ch); |
453 |
ch = malloc(chunk_len); |
CHECK_ALLOCATION(ch=malloc(chunk_len)); |
|
} |
|
|
|
|
|
if (ch == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
454 |
} |
} |
455 |
|
|
456 |
len = fread(&ch[0], 1, chunk_len, f); |
len = fread(&ch[0], 1, chunk_len, f); |
544 |
if (elf64) { |
if (elf64) { |
545 |
if (symbols_sym64 != NULL) |
if (symbols_sym64 != NULL) |
546 |
free(symbols_sym64); |
free(symbols_sym64); |
547 |
symbols_sym64 = malloc(sh_size); |
|
548 |
if (symbols_sym64 == NULL) { |
CHECK_ALLOCATION(symbols_sym64 = |
549 |
fprintf(stderr, "out of memory\n"); |
malloc(sh_size)); |
|
exit(1); |
|
|
} |
|
550 |
|
|
551 |
len = fread(symbols_sym64, 1, sh_entsize * |
len = fread(symbols_sym64, 1, sh_entsize * |
552 |
n_entries, f); |
n_entries, f); |
553 |
} else { |
} else { |
554 |
if (symbols_sym32 != NULL) |
if (symbols_sym32 != NULL) |
555 |
free(symbols_sym32); |
free(symbols_sym32); |
556 |
symbols_sym32 = malloc(sh_size); |
|
557 |
if (symbols_sym32 == NULL) { |
CHECK_ALLOCATION(symbols_sym32 = |
558 |
fprintf(stderr, "out of memory\n"); |
malloc(sh_size)); |
|
exit(1); |
|
|
} |
|
559 |
|
|
560 |
len = fread(symbols_sym32, 1, |
len = fread(symbols_sym32, 1, |
561 |
sh_entsize * n_entries, f); |
sh_entsize * n_entries, f); |
587 |
if (symbol_strings != NULL) |
if (symbol_strings != NULL) |
588 |
free(symbol_strings); |
free(symbol_strings); |
589 |
|
|
590 |
symbol_strings = malloc(sh_size + 1); |
CHECK_ALLOCATION(symbol_strings = malloc(sh_size + 1)); |
|
if (symbol_strings == NULL) { |
|
|
fprintf(stderr, "out of memory\n"); |
|
|
exit(1); |
|
|
} |
|
591 |
|
|
592 |
fseek(f, sh_offset, SEEK_SET); |
fseek(f, sh_offset, SEEK_SET); |
593 |
len = fread(symbol_strings, 1, sh_size, f); |
len = fread(symbol_strings, 1, sh_size, f); |