--- trunk/src/file.c 2007/10/08 16:18:06 5 +++ trunk/src/file.c 2007/10/08 16:18:11 6 @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $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 $ * * This file contains functions which load executable images into (emulated) * memory. File formats recognized so far: @@ -123,6 +123,8 @@ } +#define AOUT_FLAG_DECOSF1 1 +#define AOUT_FLAG_FROM_BEGINNING 2 /* * file_load_aout(): * @@ -133,7 +135,7 @@ * formats, where text/data are aligned differently. */ static void file_load_aout(struct machine *m, struct memory *mem, - char *filename, int osf1_hack, + char *filename, int flags, uint64_t *entrypointp, int arch, int *byte_orderp) { struct exec aout_header; @@ -152,7 +154,7 @@ exit(1); } - if (osf1_hack) { + if (flags & AOUT_FLAG_DECOSF1) { fread(&buf, 1, 32, f); vaddr = buf[16] + (buf[17] << 8) + (buf[18] << 16) + (buf[19] << 24); @@ -185,6 +187,11 @@ unencode(symbsize, &aout_header.a_syms, uint32_t); } + if (flags & AOUT_FLAG_FROM_BEGINNING) { + fseek(f, 0, SEEK_SET); + vaddr &= ~0xfff; + } + /* Load text and data: */ total_len = textsize + datasize; while (total_len != 0) { @@ -198,7 +205,7 @@ m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr, &buf[0], len, MEM_WRITE, NO_EXCEPTIONS); else { - if (osf1_hack) + if (flags & AOUT_FLAG_DECOSF1) break; else { fprintf(stderr, "could not read from %s\n", @@ -268,7 +275,7 @@ fclose(f); - *entrypointp = entry; + *entrypointp = (int32_t)entry; if (encoding == ELFDATA2LSB) *byte_orderp = EMUL_LITTLE_ENDIAN; @@ -999,14 +1006,16 @@ unencode(eshoff, &hdr64.e_shoff, Elf64_Off); if (ephentsize != sizeof(Elf64_Phdr)) { fprintf(stderr, "%s: incorrect phentsize? %i, should " - "be %i\n", filename, (int)ephentsize, - (int)sizeof(Elf64_Phdr)); + "be %i\nPerhaps this is a dynamically linked " + "binary (which isn't supported yet).\n", filename, + (int)ephentsize, (int)sizeof(Elf64_Phdr)); exit(1); } if (eshentsize != sizeof(Elf64_Shdr)) { - fprintf(stderr, "%s: incorrect phentsize? %i, should " - "be %i\n", filename, (int)ephentsize, - (int)sizeof(Elf64_Shdr)); + fprintf(stderr, "%s: incorrect shentsize? %i, should " + "be %i\nPerhaps this is a dynamically linked " + "binary (which isn't supported yet).\n", filename, + (int)eshentsize, (int)sizeof(Elf64_Shdr)); exit(1); } } else { @@ -1022,14 +1031,16 @@ unencode(eshoff, &hdr32.e_shoff, Elf32_Off); if (ephentsize != sizeof(Elf32_Phdr)) { fprintf(stderr, "%s: incorrect phentsize? %i, should " - "be %i\n", filename, (int)ephentsize, - (int)sizeof(Elf32_Phdr)); + "be %i\nPerhaps this is a dynamically linked " + "binary (which isn't supported yet).\n", filename, + (int)ephentsize, (int)sizeof(Elf32_Phdr)); exit(1); } if (eshentsize != sizeof(Elf32_Shdr)) { - fprintf(stderr, "%s: incorrect phentsize? %i, should " - "be %i\n", filename, (int)ephentsize, - (int)sizeof(Elf32_Shdr)); + fprintf(stderr, "%s: incorrect shentsize? %i, should " + "be %i\nPerhaps this is a dynamically linked " + "binary (which isn't supported yet).\n", filename, + (int)eshentsize, (int)sizeof(Elf32_Shdr)); exit(1); } } @@ -1080,14 +1091,21 @@ switch (emachine) { case EM_386: case EM_486: + *tocp = 1; ok = 1; break; case EM_AMD64: - *tocp = 1; + *tocp = 2; ok = 1; break; } break; + case ARCH_ARM: + switch (emachine) { + case EM_ARM: + ok = 1; + } + break; default: fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n"); } @@ -1424,7 +1442,8 @@ if (size == 0) size ++; - if (addr != 0) { + if (addr != 0) /* && ((st_info >> 4) & 0xf) + >= STB_GLOBAL) */ { /* debug("symbol info=0x%02x addr=0x%016llx" " '%s'\n", st_info, (long long)addr, symbol_strings + st_name); */ @@ -1528,7 +1547,8 @@ int iadd = 4; FILE *f; unsigned char buf[12]; - int len, i; + unsigned char buf2[2]; + size_t len, len2, i; off_t size; if (byte_orderp == NULL) { @@ -1565,6 +1585,8 @@ memset(buf, 0, sizeof(buf)); len = fread(buf, 1, sizeof(buf), f); + fseek(f, 510, SEEK_SET); + len2 = fread(buf2, 1, sizeof(buf2), f); fclose(f); if (len < (signed int)sizeof(buf)) { @@ -1580,14 +1602,22 @@ goto ret; } - /* Is it an a.out? (Special case for DEC OSF1 kernels.) */ + /* Is it an a.out? */ if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) { + /* MIPS a.out */ file_load_aout(machine, mem, filename, 0, entrypointp, arch, byte_orderp); goto ret; } + if (buf[0]==0x00 && buf[1]==0x86 && buf[2]==0x01 && buf[3]==0x0b) { + /* i386 a.out (old OpenBSD and NetBSD etc) */ + file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING, + entrypointp, arch, byte_orderp); + goto ret; + } if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) { - file_load_aout(machine, mem, filename, 1, + /* DEC OSF1 on MIPS: */ + file_load_aout(machine, mem, filename, AOUT_FLAG_DECOSF1, entrypointp, arch, byte_orderp); goto ret; } @@ -1632,7 +1662,7 @@ fprintf(stderr, "\nThis file is very large (%lli bytes)\n", (long long)size); fprintf(stderr, "Are you sure it is a kernel and not a disk " - "image?\n"); + "image? (Use the -d option.)\n"); exit(1); } @@ -1655,6 +1685,11 @@ "unknown.\n\n ", filename); for (i=0; i<(signed)sizeof(buf); i++) fprintf(stderr, " %02x", buf[i]); + + if (len2 == 2 && buf2[0] == 0x55 && buf2[1] == 0xaa) + fprintf(stderr, "\n\nIt has a PC-style " + "bootsector marker."); + fprintf(stderr, "\n\nPossible explanations:\n\n" " o) If this is a disk image, you forgot '-d' " "on the command line.\n"