25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: file.c,v 1.88 2005/04/17 00:15:24 debug Exp $ |
* $Id: file.c,v 1.96 2005/06/02 12:31:39 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: |
123 |
} |
} |
124 |
|
|
125 |
|
|
126 |
|
#define AOUT_FLAG_DECOSF1 1 |
127 |
|
#define AOUT_FLAG_FROM_BEGINNING 2 |
128 |
/* |
/* |
129 |
* file_load_aout(): |
* file_load_aout(): |
130 |
* |
* |
135 |
* formats, where text/data are aligned differently. |
* formats, where text/data are aligned differently. |
136 |
*/ |
*/ |
137 |
static void file_load_aout(struct machine *m, struct memory *mem, |
static void file_load_aout(struct machine *m, struct memory *mem, |
138 |
char *filename, int osf1_hack, |
char *filename, int flags, |
139 |
uint64_t *entrypointp, int arch, int *byte_orderp) |
uint64_t *entrypointp, int arch, int *byte_orderp) |
140 |
{ |
{ |
141 |
struct exec aout_header; |
struct exec aout_header; |
154 |
exit(1); |
exit(1); |
155 |
} |
} |
156 |
|
|
157 |
if (osf1_hack) { |
if (flags & AOUT_FLAG_DECOSF1) { |
158 |
fread(&buf, 1, 32, f); |
fread(&buf, 1, 32, f); |
159 |
vaddr = buf[16] + (buf[17] << 8) + |
vaddr = buf[16] + (buf[17] << 8) + |
160 |
(buf[18] << 16) + (buf[19] << 24); |
(buf[18] << 16) + (buf[19] << 24); |
187 |
unencode(symbsize, &aout_header.a_syms, uint32_t); |
unencode(symbsize, &aout_header.a_syms, uint32_t); |
188 |
} |
} |
189 |
|
|
190 |
|
if (flags & AOUT_FLAG_FROM_BEGINNING) { |
191 |
|
fseek(f, 0, SEEK_SET); |
192 |
|
vaddr &= ~0xfff; |
193 |
|
} |
194 |
|
|
195 |
/* Load text and data: */ |
/* Load text and data: */ |
196 |
total_len = textsize + datasize; |
total_len = textsize + datasize; |
197 |
while (total_len != 0) { |
while (total_len != 0) { |
205 |
m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr, |
m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr, |
206 |
&buf[0], len, MEM_WRITE, NO_EXCEPTIONS); |
&buf[0], len, MEM_WRITE, NO_EXCEPTIONS); |
207 |
else { |
else { |
208 |
if (osf1_hack) |
if (flags & AOUT_FLAG_DECOSF1) |
209 |
break; |
break; |
210 |
else { |
else { |
211 |
fprintf(stderr, "could not read from %s\n", |
fprintf(stderr, "could not read from %s\n", |
275 |
|
|
276 |
fclose(f); |
fclose(f); |
277 |
|
|
278 |
*entrypointp = entry; |
*entrypointp = (int32_t)entry; |
279 |
|
|
280 |
if (encoding == ELFDATA2LSB) |
if (encoding == ELFDATA2LSB) |
281 |
*byte_orderp = EMUL_LITTLE_ENDIAN; |
*byte_orderp = EMUL_LITTLE_ENDIAN; |
1006 |
unencode(eshoff, &hdr64.e_shoff, Elf64_Off); |
unencode(eshoff, &hdr64.e_shoff, Elf64_Off); |
1007 |
if (ephentsize != sizeof(Elf64_Phdr)) { |
if (ephentsize != sizeof(Elf64_Phdr)) { |
1008 |
fprintf(stderr, "%s: incorrect phentsize? %i, should " |
fprintf(stderr, "%s: incorrect phentsize? %i, should " |
1009 |
"be %i\n", filename, (int)ephentsize, |
"be %i\nPerhaps this is a dynamically linked " |
1010 |
(int)sizeof(Elf64_Phdr)); |
"binary (which isn't supported yet).\n", filename, |
1011 |
|
(int)ephentsize, (int)sizeof(Elf64_Phdr)); |
1012 |
exit(1); |
exit(1); |
1013 |
} |
} |
1014 |
if (eshentsize != sizeof(Elf64_Shdr)) { |
if (eshentsize != sizeof(Elf64_Shdr)) { |
1015 |
fprintf(stderr, "%s: incorrect phentsize? %i, should " |
fprintf(stderr, "%s: incorrect shentsize? %i, should " |
1016 |
"be %i\n", filename, (int)ephentsize, |
"be %i\nPerhaps this is a dynamically linked " |
1017 |
(int)sizeof(Elf64_Shdr)); |
"binary (which isn't supported yet).\n", filename, |
1018 |
|
(int)eshentsize, (int)sizeof(Elf64_Shdr)); |
1019 |
exit(1); |
exit(1); |
1020 |
} |
} |
1021 |
} else { |
} else { |
1031 |
unencode(eshoff, &hdr32.e_shoff, Elf32_Off); |
unencode(eshoff, &hdr32.e_shoff, Elf32_Off); |
1032 |
if (ephentsize != sizeof(Elf32_Phdr)) { |
if (ephentsize != sizeof(Elf32_Phdr)) { |
1033 |
fprintf(stderr, "%s: incorrect phentsize? %i, should " |
fprintf(stderr, "%s: incorrect phentsize? %i, should " |
1034 |
"be %i\n", filename, (int)ephentsize, |
"be %i\nPerhaps this is a dynamically linked " |
1035 |
(int)sizeof(Elf32_Phdr)); |
"binary (which isn't supported yet).\n", filename, |
1036 |
|
(int)ephentsize, (int)sizeof(Elf32_Phdr)); |
1037 |
exit(1); |
exit(1); |
1038 |
} |
} |
1039 |
if (eshentsize != sizeof(Elf32_Shdr)) { |
if (eshentsize != sizeof(Elf32_Shdr)) { |
1040 |
fprintf(stderr, "%s: incorrect phentsize? %i, should " |
fprintf(stderr, "%s: incorrect shentsize? %i, should " |
1041 |
"be %i\n", filename, (int)ephentsize, |
"be %i\nPerhaps this is a dynamically linked " |
1042 |
(int)sizeof(Elf32_Shdr)); |
"binary (which isn't supported yet).\n", filename, |
1043 |
|
(int)eshentsize, (int)sizeof(Elf32_Shdr)); |
1044 |
exit(1); |
exit(1); |
1045 |
} |
} |
1046 |
} |
} |
1091 |
switch (emachine) { |
switch (emachine) { |
1092 |
case EM_386: |
case EM_386: |
1093 |
case EM_486: |
case EM_486: |
1094 |
|
*tocp = 1; |
1095 |
ok = 1; |
ok = 1; |
1096 |
break; |
break; |
1097 |
case EM_AMD64: |
case EM_AMD64: |
1098 |
*tocp = 1; |
*tocp = 2; |
1099 |
ok = 1; |
ok = 1; |
1100 |
break; |
break; |
1101 |
} |
} |
1102 |
break; |
break; |
1103 |
|
case ARCH_ARM: |
1104 |
|
switch (emachine) { |
1105 |
|
case EM_ARM: |
1106 |
|
ok = 1; |
1107 |
|
} |
1108 |
|
break; |
1109 |
default: |
default: |
1110 |
fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n"); |
fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n"); |
1111 |
} |
} |
1442 |
if (size == 0) |
if (size == 0) |
1443 |
size ++; |
size ++; |
1444 |
|
|
1445 |
if (addr != 0) { |
if (addr != 0) /* && ((st_info >> 4) & 0xf) |
1446 |
|
>= STB_GLOBAL) */ { |
1447 |
/* debug("symbol info=0x%02x addr=0x%016llx" |
/* debug("symbol info=0x%02x addr=0x%016llx" |
1448 |
" '%s'\n", st_info, (long long)addr, |
" '%s'\n", st_info, (long long)addr, |
1449 |
symbol_strings + st_name); */ |
symbol_strings + st_name); */ |
1547 |
int iadd = 4; |
int iadd = 4; |
1548 |
FILE *f; |
FILE *f; |
1549 |
unsigned char buf[12]; |
unsigned char buf[12]; |
1550 |
int len, i; |
unsigned char buf2[2]; |
1551 |
|
size_t len, len2, i; |
1552 |
off_t size; |
off_t size; |
1553 |
|
|
1554 |
if (byte_orderp == NULL) { |
if (byte_orderp == NULL) { |
1585 |
|
|
1586 |
memset(buf, 0, sizeof(buf)); |
memset(buf, 0, sizeof(buf)); |
1587 |
len = fread(buf, 1, sizeof(buf), f); |
len = fread(buf, 1, sizeof(buf), f); |
1588 |
|
fseek(f, 510, SEEK_SET); |
1589 |
|
len2 = fread(buf2, 1, sizeof(buf2), f); |
1590 |
fclose(f); |
fclose(f); |
1591 |
|
|
1592 |
if (len < (signed int)sizeof(buf)) { |
if (len < (signed int)sizeof(buf)) { |
1602 |
goto ret; |
goto ret; |
1603 |
} |
} |
1604 |
|
|
1605 |
/* Is it an a.out? (Special case for DEC OSF1 kernels.) */ |
/* Is it an a.out? */ |
1606 |
if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) { |
if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) { |
1607 |
|
/* MIPS a.out */ |
1608 |
file_load_aout(machine, mem, filename, 0, |
file_load_aout(machine, mem, filename, 0, |
1609 |
entrypointp, arch, byte_orderp); |
entrypointp, arch, byte_orderp); |
1610 |
goto ret; |
goto ret; |
1611 |
} |
} |
1612 |
|
if (buf[0]==0x00 && buf[1]==0x86 && buf[2]==0x01 && buf[3]==0x0b) { |
1613 |
|
/* i386 a.out (old OpenBSD and NetBSD etc) */ |
1614 |
|
file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING, |
1615 |
|
entrypointp, arch, byte_orderp); |
1616 |
|
goto ret; |
1617 |
|
} |
1618 |
if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) { |
if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) { |
1619 |
file_load_aout(machine, mem, filename, 1, |
/* DEC OSF1 on MIPS: */ |
1620 |
|
file_load_aout(machine, mem, filename, AOUT_FLAG_DECOSF1, |
1621 |
entrypointp, arch, byte_orderp); |
entrypointp, arch, byte_orderp); |
1622 |
goto ret; |
goto ret; |
1623 |
} |
} |
1662 |
fprintf(stderr, "\nThis file is very large (%lli bytes)\n", |
fprintf(stderr, "\nThis file is very large (%lli bytes)\n", |
1663 |
(long long)size); |
(long long)size); |
1664 |
fprintf(stderr, "Are you sure it is a kernel and not a disk " |
fprintf(stderr, "Are you sure it is a kernel and not a disk " |
1665 |
"image?\n"); |
"image? (Use the -d option.)\n"); |
1666 |
exit(1); |
exit(1); |
1667 |
} |
} |
1668 |
|
|
1685 |
"unknown.\n\n ", filename); |
"unknown.\n\n ", filename); |
1686 |
for (i=0; i<(signed)sizeof(buf); i++) |
for (i=0; i<(signed)sizeof(buf); i++) |
1687 |
fprintf(stderr, " %02x", buf[i]); |
fprintf(stderr, " %02x", buf[i]); |
1688 |
|
|
1689 |
|
if (len2 == 2 && buf2[0] == 0x55 && buf2[1] == 0xaa) |
1690 |
|
fprintf(stderr, "\n\nIt has a PC-style " |
1691 |
|
"bootsector marker."); |
1692 |
|
|
1693 |
fprintf(stderr, "\n\nPossible explanations:\n\n" |
fprintf(stderr, "\n\nPossible explanations:\n\n" |
1694 |
" o) If this is a disk image, you forgot '-d' " |
" o) If this is a disk image, you forgot '-d' " |
1695 |
"on the command line.\n" |
"on the command line.\n" |