25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: file.c,v 1.99 2005/06/26 09:21:28 debug Exp $ |
* $Id: file.c,v 1.105 2005/08/11 16:11:33 debug Exp $ |
29 |
* |
* |
30 |
* This file contains functions which load executable images into (emulated) |
* This file contains functions which load executable images into (emulated) |
31 |
* memory. File formats recognized so far: |
* memory. File formats recognized so far: |
125 |
|
|
126 |
#define AOUT_FLAG_DECOSF1 1 |
#define AOUT_FLAG_DECOSF1 1 |
127 |
#define AOUT_FLAG_FROM_BEGINNING 2 |
#define AOUT_FLAG_FROM_BEGINNING 2 |
128 |
|
#define AOUT_FLAG_VADDR_ZERO_HACK 4 |
129 |
/* |
/* |
130 |
* file_load_aout(): |
* file_load_aout(): |
131 |
* |
* |
146 |
uint32_t entry, datasize, textsize; |
uint32_t entry, datasize, textsize; |
147 |
int32_t symbsize = 0; |
int32_t symbsize = 0; |
148 |
uint32_t vaddr, total_len; |
uint32_t vaddr, total_len; |
149 |
unsigned char buf[4096]; |
unsigned char buf[65536]; |
150 |
unsigned char *syms; |
unsigned char *syms; |
151 |
|
|
152 |
|
if (m->cpus[0]->byte_order == EMUL_BIG_ENDIAN) |
153 |
|
encoding = ELFDATA2MSB; |
154 |
|
|
155 |
f = fopen(filename, "r"); |
f = fopen(filename, "r"); |
156 |
if (f == NULL) { |
if (f == NULL) { |
157 |
perror(filename); |
perror(filename); |
181 |
} |
} |
182 |
|
|
183 |
unencode(entry, &aout_header.a_entry, uint32_t); |
unencode(entry, &aout_header.a_entry, uint32_t); |
|
vaddr = entry; |
|
184 |
debug("a.out, entry point 0x%08lx\n", (long)entry); |
debug("a.out, entry point 0x%08lx\n", (long)entry); |
185 |
|
vaddr = entry; |
186 |
|
|
187 |
|
if (flags & AOUT_FLAG_VADDR_ZERO_HACK) |
188 |
|
vaddr = 0; |
189 |
|
|
190 |
unencode(textsize, &aout_header.a_text, uint32_t); |
unencode(textsize, &aout_header.a_text, uint32_t); |
191 |
unencode(datasize, &aout_header.a_data, uint32_t); |
unencode(datasize, &aout_header.a_data, uint32_t); |
208 |
/* printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n", |
/* printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n", |
209 |
len, (int)vaddr, buf[0], buf[1], buf[2]); */ |
len, (int)vaddr, buf[0], buf[1], buf[2]); */ |
210 |
|
|
211 |
if (len > 0) |
if (len > 0) { |
212 |
m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr, |
int len2 = 0; |
213 |
&buf[0], len, MEM_WRITE, NO_EXCEPTIONS); |
uint64_t vaddr1 = vaddr & |
214 |
else { |
((1 << BITS_PER_MEMBLOCK) - 1); |
215 |
|
uint64_t vaddr2 = (vaddr + |
216 |
|
len) & ((1 << BITS_PER_MEMBLOCK) - 1); |
217 |
|
if (vaddr2 < vaddr1) { |
218 |
|
len2 = len - vaddr2; |
219 |
|
m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr, |
220 |
|
&buf[0], len2, MEM_WRITE, NO_EXCEPTIONS); |
221 |
|
} |
222 |
|
m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr + len2, |
223 |
|
&buf[len2], len-len2, MEM_WRITE, NO_EXCEPTIONS); |
224 |
|
} else { |
225 |
if (flags & AOUT_FLAG_DECOSF1) |
if (flags & AOUT_FLAG_DECOSF1) |
226 |
break; |
break; |
227 |
else { |
else { |
282 |
|
|
283 |
if (type != 0 && addr != 0) |
if (type != 0 && addr != 0) |
284 |
add_symbol_name(&m->symbol_context, |
add_symbol_name(&m->symbol_context, |
285 |
addr, 0, string_symbols + str_index, 0); |
addr, 0, string_symbols + str_index, 0, -1); |
286 |
i++; |
i++; |
287 |
} |
} |
288 |
|
|
592 |
memcpy(name, sym->name, 8); |
memcpy(name, sym->name, 8); |
593 |
name[8] = '\0'; |
name[8] = '\0'; |
594 |
add_symbol_name(&m->symbol_context, |
add_symbol_name(&m->symbol_context, |
595 |
v, 0, name, 0); |
v, 0, name, 0, -1); |
596 |
n_real_symbols ++; |
n_real_symbols ++; |
597 |
} else if (t == 0x20 && !sym->name[0]) { |
} else if (t == 0x20 && !sym->name[0]) { |
598 |
off_t ofs; |
off_t ofs; |
604 |
/* debug(" [altname=0x%x '%s']", |
/* debug(" [altname=0x%x '%s']", |
605 |
altname, name); */ |
altname, name); */ |
606 |
add_symbol_name(&m->symbol_context, |
add_symbol_name(&m->symbol_context, |
607 |
v, 0, name, 0); |
v, 0, name, 0, -1); |
608 |
n_real_symbols ++; |
n_real_symbols ++; |
609 |
} |
} |
610 |
|
|
675 |
|
|
676 |
add_symbol_name(&m->symbol_context, |
add_symbol_name(&m->symbol_context, |
677 |
extsyms[sym_nr].es_value, 0, |
extsyms[sym_nr].es_value, 0, |
678 |
symbol_data + extsyms[sym_nr].es_strindex, 0); |
symbol_data + extsyms[sym_nr].es_strindex, 0, -1); |
679 |
} |
} |
680 |
|
|
681 |
free(extsyms); |
free(extsyms); |
1077 |
ok = 1; |
ok = 1; |
1078 |
} |
} |
1079 |
break; |
break; |
|
case ARCH_HPPA: |
|
|
switch (emachine) { |
|
|
case EM_PARISC: |
|
|
ok = 1; |
|
|
} |
|
|
break; |
|
1080 |
case ARCH_MIPS: |
case ARCH_MIPS: |
1081 |
switch (emachine) { |
switch (emachine) { |
1082 |
case EM_MIPS: |
case EM_MIPS: |
1117 |
ok = 1; |
ok = 1; |
1118 |
} |
} |
1119 |
break; |
break; |
1120 |
|
case ARCH_IA64: |
1121 |
|
switch (emachine) { |
1122 |
|
case EM_IA_64: |
1123 |
|
ok = 1; |
1124 |
|
} |
1125 |
|
break; |
1126 |
|
case ARCH_M68K: |
1127 |
|
switch (emachine) { |
1128 |
|
case EM_68K: |
1129 |
|
ok = 1; |
1130 |
|
} |
1131 |
|
break; |
1132 |
default: |
default: |
1133 |
fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n"); |
fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n"); |
1134 |
} |
} |
1300 |
} |
} |
1301 |
} |
} |
1302 |
|
|
1303 |
/* Read the section headers to find the address of the _gp symbol: */ |
/* |
1304 |
|
* Read the section headers to find the address of the _gp |
1305 |
|
* symbol (for MIPS): |
1306 |
|
*/ |
1307 |
|
|
1308 |
for (i=0; i<eshnum; i++) { |
for (i=0; i<eshnum; i++) { |
1309 |
int sh_name, sh_type, sh_flags, sh_link, sh_info, sh_entsize; |
int sh_name, sh_type, sh_flags, sh_link, sh_info, sh_entsize; |
1462 |
unencode(size, &sym32.st_size, Elf32_Word); |
unencode(size, &sym32.st_size, Elf32_Word); |
1463 |
} |
} |
1464 |
|
|
1465 |
|
/* debug("symbol info=0x%02x addr=0x%016llx" |
1466 |
|
" (%i) '%s'\n", st_info, (long long)addr, |
1467 |
|
st_name, symbol_strings + st_name); */ |
1468 |
|
|
1469 |
if (size == 0) |
if (size == 0) |
1470 |
size ++; |
size ++; |
1471 |
|
|
1475 |
" '%s'\n", st_info, (long long)addr, |
" '%s'\n", st_info, (long long)addr, |
1476 |
symbol_strings + st_name); */ |
symbol_strings + st_name); */ |
1477 |
add_symbol_name(&m->symbol_context, |
add_symbol_name(&m->symbol_context, |
1478 |
addr, size, symbol_strings + st_name, 0); |
addr, size, symbol_strings + st_name, |
1479 |
|
0, -1); |
1480 |
} |
} |
1481 |
|
|
1482 |
if (strcmp(symbol_strings + st_name, "_gp") == 0) { |
if (strcmp(symbol_strings + st_name, "_gp") == 0) { |
1637 |
entrypointp, arch, byte_orderp); |
entrypointp, arch, byte_orderp); |
1638 |
goto ret; |
goto ret; |
1639 |
} |
} |
1640 |
|
if (buf[0]==0x00 && buf[1]==0x87 && buf[2]==0x01 && buf[3]==0x08) { |
1641 |
|
/* M68K a.out */ |
1642 |
|
file_load_aout(machine, mem, filename, |
1643 |
|
AOUT_FLAG_VADDR_ZERO_HACK /* for OpenBSD/mac68k */, |
1644 |
|
entrypointp, arch, byte_orderp); |
1645 |
|
goto ret; |
1646 |
|
} |
1647 |
if (buf[0]==0x00 && buf[1]==0x86 && buf[2]==0x01 && buf[3]==0x0b) { |
if (buf[0]==0x00 && buf[1]==0x86 && buf[2]==0x01 && buf[3]==0x0b) { |
1648 |
/* i386 a.out (old OpenBSD and NetBSD etc) */ |
/* i386 a.out (old OpenBSD and NetBSD etc) */ |
1649 |
file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING, |
file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING, |