/[gxemul]/trunk/src/file.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /trunk/src/file.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4 - (show annotations)
Mon Oct 8 16:18:00 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 46138 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.707 2005/04/27 16:37:33 debug Exp $
20050408	Some minor updates to the wdc. Linux now doesn't complain
		anymore if a disk is non-present.
20050409	Various minor fixes (a bintrans bug, and some other things).
		The wdc seems to work with Playstation2 emulation, but there
		is a _long_ annoying delay when disks are detected.
		Fixing a really important bintrans bug (when devices and RAM
		are mixed within 4KB pages), which was triggered with
		NetBSD/playstation2 kernels.
20050410	Adding a dummy dev_ps2_ether (just so that NetBSD doesn't
		complain as much during bootup).
		Symbols starting with '$' are now ignored.
		Renaming dev_ps2_ohci.c to dev_ohci.c, etc.
20050411	Moving the bintrans-cache-isolation check from cpu_mips.c to
		cpu_mips_coproc.c. (I thought this would give a speedup, but
		it's not noticable.)
		Better playstation2 sbus interrupt code.
		Skip ahead many ticks if the count register is read manually.
		(This increases the speed of delay-loops that simply read
		the count register.)
20050412	Updates to the playstation2 timer/interrupt code.
		Some other minor updates.
20050413	NetBSD/cobalt runs from a disk image :-) including userland;
		updating the documentation on how to install NetBSD/cobalt
		using NetBSD/pmax (!).
		Some minor bintrans updates (no real speed improvement) and
		other minor updates (playstation2 now uses the -o options).
20050414	Adding a dummy x86 (and AMD64) mode.
20050415	Adding some (32-bit and 16-bit) x86 instructions.
		Adding some initial support for non-SCSI, non-IDE floppy
		images. (The x86 mode can boot from these, more or less.)
		Moving the devices/ and include/ directories to src/devices/
		and src/include/, respectively.
20050416	Continuing on the x86 stuff. (Adding pc_bios.c and some simple
		support for software interrupts in 16-bit mode.)
20050417	Ripping out most of the x86 instruction decoding stuff, trying
		to rewrite it in a cleaner way.
		Disabling some of the least working CPU families in the
		configure script (sparc, x86, alpha, hppa), so that they are
		not enabled by default.
20050418	Trying to fix the bug which caused problems when turning on
		and off bintrans interactively, by flushing the bintrans cache
		whenever bintrans is manually (re)enabled.
20050419	Adding the 'lswi' ppc instruction.
		Minor updates to the x86 instruction decoding.
20050420	Renaming x86 register name indices from R_xx to X86_R_xx (this
		makes building on Tru64 nicer).
20050422	Adding a check for duplicate MIPS TLB entries on tlbwr/tlbwi.
20050427	Adding screenshots to guestoses.html.
		Some minor fixes and testing for the next release.

==============  RELEASE 0.3.2  ==============


1 /*
2 * Copyright (C) 2003-2005 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: file.c,v 1.88 2005/04/17 00:15:24 debug Exp $
29 *
30 * This file contains functions which load executable images into (emulated)
31 * memory. File formats recognized so far:
32 *
33 * ELF 32-bit and 64-bit ELFs
34 * a.out old format used by OpenBSD 2.x pmax kernels
35 * ecoff old format used by Ultrix, Windows NT, etc
36 * srec Motorola SREC format
37 * raw raw binaries, "address:[skiplen:[entrypoint:]]filename"
38 *
39 * If a file is not of one of the above mentioned formats, it is assumed
40 * to be symbol data generated by 'nm' or 'nm -S'.
41 */
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <sys/types.h>
47
48 #include "cpu.h"
49 #include "exec_aout.h"
50 #include "exec_ecoff.h"
51 #include "exec_elf.h"
52 #include "machine.h"
53 #include "memory.h"
54 #include "misc.h"
55 #include "symbol.h"
56
57
58 /* ELF machine types as strings: (same as exec_elf.h) */
59 #define N_ELF_MACHINE_TYPES 64
60 static char *elf_machine_type[N_ELF_MACHINE_TYPES] = {
61 "NONE", "M32", "SPARC", "386", /* 0..3 */
62 "68K", "88K", "486", "860", /* 4..7 */
63 "MIPS", "S370", "MIPS_RS3_LE", "RS6000", /* 8..11 */
64 "unknown12", "unknown13", "unknown14", "PARISC", /* 12..15 */
65 "NCUBE", "VPP500", "SPARC32PLUS", "960", /* 16..19 */
66 "PPC", "PPC64", "unknown22", "unknown23", /* 20..23 */
67 "unknown24", "unknown25", "unknown26", "unknown27", /* 24..27 */
68 "unknown28", "unknown29", "unknown30", "unknown31", /* 28..31 */
69 "unknown32", "unknown33", "unknown34", "unknown35", /* 32..35 */
70 "V800", "FR20", "RH32", "RCE", /* 36..39 */
71 "ARM", "ALPHA", "SH", "SPARCV9", /* 40..43 */
72 "TRICORE", "ARC", "H8_300", "H8_300H", /* 44..47 */
73 "H8S", "H8_500", "IA_64", "MIPS_X", /* 48..51 */
74 "COLDFIRE", "68HC12", "unknown54", "unknown55", /* 52..55 */
75 "unknown56", "unknown57", "unknown58", "unknown59", /* 56..59 */
76 "unknown60", "unknown61", "AMD64", "unknown63" /* 60..63 */
77 };
78
79
80 /*
81 * This should be increased by every routine here that actually loads an
82 * executable file into memory. (For example, loading a symbol file should
83 * NOT increase this.)
84 */
85 static int n_executables_loaded = 0;
86
87
88 struct aout_symbol {
89 uint32_t strindex;
90 uint32_t type;
91 uint32_t addr;
92 };
93
94 /* Special symbol format used by Microsoft-ish COFF files: */
95 struct ms_sym {
96 unsigned char name[8];
97 unsigned char value[4];
98 unsigned char section[2];
99 unsigned char type[2];
100 unsigned char storage_class;
101 unsigned char n_aux_syms;
102 };
103
104
105 #define unencode(var,dataptr,typ) { \
106 int Wi; unsigned char Wb; \
107 unsigned char *Wp = (unsigned char *) dataptr; \
108 int Wlen = sizeof(typ); \
109 var = 0; \
110 for (Wi=0; Wi<Wlen; Wi++) { \
111 if (encoding == ELFDATA2LSB) \
112 Wb = Wp[Wlen-1 - Wi]; \
113 else \
114 Wb = Wp[Wi]; \
115 if (Wi == 0 && (Wb & 0x80)) { \
116 var --; /* set var to -1 :-) */ \
117 var <<= 8; \
118 } \
119 var |= Wb; \
120 if (Wi < Wlen-1) \
121 var <<= 8; \
122 } \
123 }
124
125
126 /*
127 * file_load_aout():
128 *
129 * Loads an a.out binary image into the emulated memory. The entry point
130 * (read from the a.out header) is stored in the specified CPU's registers.
131 *
132 * TODO: This has to be rewritten / corrected to support multiple a.out
133 * formats, where text/data are aligned differently.
134 */
135 static void file_load_aout(struct machine *m, struct memory *mem,
136 char *filename, int osf1_hack,
137 uint64_t *entrypointp, int arch, int *byte_orderp)
138 {
139 struct exec aout_header;
140 FILE *f;
141 int len;
142 int encoding = ELFDATA2LSB;
143 uint32_t entry, datasize, textsize;
144 int32_t symbsize = 0;
145 uint32_t vaddr, total_len;
146 unsigned char buf[4096];
147 unsigned char *syms;
148
149 f = fopen(filename, "r");
150 if (f == NULL) {
151 perror(filename);
152 exit(1);
153 }
154
155 if (osf1_hack) {
156 fread(&buf, 1, 32, f);
157 vaddr = buf[16] + (buf[17] << 8) +
158 (buf[18] << 16) + (buf[19] << 24);
159 entry = buf[20] + (buf[21] << 8) +
160 (buf[22] << 16) + (buf[23] << 24);
161 debug("OSF1 a.out, load address 0x%08lx, "
162 "entry point 0x%08x\n", (long)vaddr, (long)entry);
163 symbsize = 0;
164 fseek(f, 0, SEEK_END);
165 /* This is of course wrong, but should work anyway: */
166 textsize = ftell(f) - 512;
167 datasize = 0;
168 fseek(f, 512, SEEK_SET);
169 } else {
170 len = fread(&aout_header, 1, sizeof(aout_header), f);
171 if (len != sizeof(aout_header)) {
172 fprintf(stderr, "%s: not a complete a.out image\n",
173 filename);
174 exit(1);
175 }
176
177 unencode(entry, &aout_header.a_entry, uint32_t);
178 vaddr = entry;
179 debug("a.out, entry point 0x%08lx\n", (long)entry);
180
181 unencode(textsize, &aout_header.a_text, uint32_t);
182 unencode(datasize, &aout_header.a_data, uint32_t);
183 debug("text + data = %i + %i bytes\n", textsize, datasize);
184
185 unencode(symbsize, &aout_header.a_syms, uint32_t);
186 }
187
188 /* Load text and data: */
189 total_len = textsize + datasize;
190 while (total_len != 0) {
191 len = total_len > sizeof(buf) ? sizeof(buf) : total_len;
192 len = fread(buf, 1, len, f);
193
194 /* printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",
195 len, (int)vaddr, buf[0], buf[1], buf[2]); */
196
197 if (len > 0)
198 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
199 &buf[0], len, MEM_WRITE, NO_EXCEPTIONS);
200 else {
201 if (osf1_hack)
202 break;
203 else {
204 fprintf(stderr, "could not read from %s\n",
205 filename);
206 exit(1);
207 }
208 }
209
210 vaddr += len;
211 total_len -= len;
212 }
213
214 if (symbsize != 0) {
215 struct aout_symbol *aout_symbol_ptr;
216 int i, n_symbols;
217 uint32_t type, addr, str_index;
218 uint32_t strings_len;
219 char *string_symbols;
220 off_t oldpos;
221
222 debug("symbols: %i bytes @ 0x%x\n", symbsize, (int)ftell(f));
223 syms = malloc(symbsize);
224 if (syms == NULL) {
225 fprintf(stderr, "out of memory\n");
226 exit(1);
227 }
228 len = fread(syms, 1, symbsize, f);
229 if (len != symbsize) {
230 fprintf(stderr, "error reading symbols from %s\n",
231 filename);
232 exit(1);
233 }
234
235 oldpos = ftell(f);
236 fseek(f, 0, SEEK_END);
237 strings_len = ftell(f) - oldpos;
238 fseek(f, oldpos, SEEK_SET);
239 debug("strings: %i bytes @ 0x%x\n", strings_len, (int)ftell(f));
240 string_symbols = malloc(strings_len);
241 if (string_symbols == NULL) {
242 fprintf(stderr, "out of memory\n");
243 exit(1);
244 }
245 fread(string_symbols, 1, strings_len, f);
246
247 aout_symbol_ptr = (struct aout_symbol *) syms;
248 n_symbols = symbsize / sizeof(struct aout_symbol);
249 i = 0;
250 while (i < n_symbols) {
251 unencode(str_index, &aout_symbol_ptr[i].strindex,
252 uint32_t);
253 unencode(type, &aout_symbol_ptr[i].type, uint32_t);
254 unencode(addr, &aout_symbol_ptr[i].addr, uint32_t);
255
256 /* debug("symbol type 0x%04x @ 0x%08x: %s\n",
257 type, addr, string_symbols + str_index); */
258
259 if (type != 0 && addr != 0)
260 add_symbol_name(&m->symbol_context,
261 addr, 0, string_symbols + str_index, 0);
262 i++;
263 }
264
265 free(string_symbols);
266 free(syms);
267 }
268
269 fclose(f);
270
271 *entrypointp = entry;
272
273 if (encoding == ELFDATA2LSB)
274 *byte_orderp = EMUL_LITTLE_ENDIAN;
275 else
276 *byte_orderp = EMUL_BIG_ENDIAN;
277
278 n_executables_loaded ++;
279 }
280
281
282 /*
283 * file_load_ecoff():
284 *
285 * Loads an ecoff binary image into the emulated memory. The entry point
286 * (read from the ecoff header) is stored in the specified CPU's registers.
287 */
288 static void file_load_ecoff(struct machine *m, struct memory *mem,
289 char *filename, uint64_t *entrypointp,
290 int arch, uint64_t *gpp, int *byte_orderp)
291 {
292 struct ecoff_exechdr exechdr;
293 int f_magic, f_nscns, f_nsyms;
294 int a_magic;
295 off_t f_symptr, a_tsize, a_dsize, a_bsize;
296 uint64_t a_entry, a_tstart, a_dstart, a_bstart, a_gp, end_addr=0;
297 char *format_name;
298 struct ecoff_scnhdr scnhdr;
299 FILE *f;
300 int len, secn, total_len, chunk_size;
301 int encoding = ELFDATA2LSB; /* Assume little-endian. See below */
302 int program_byte_order = -1;
303 unsigned char buf[8192];
304
305 f = fopen(filename, "r");
306 if (f == NULL) {
307 perror(filename);
308 exit(1);
309 }
310
311 len = fread(&exechdr, 1, sizeof(exechdr), f);
312 if (len != sizeof(exechdr)) {
313 fprintf(stderr, " not a complete ecoff image\n");
314 exit(1);
315 }
316
317 /*
318 * The following code looks a bit ugly, but it should work. The ECOFF
319 * 16-bit magic value seems to be stored in MSB byte order for
320 * big-endian binaries, and LSB byte order for little-endian binaries.
321 *
322 * The unencode() assumes little-endianness by default.
323 */
324 unencode(f_magic, &exechdr.f.f_magic, uint16_t);
325 switch (f_magic) {
326 case ((ECOFF_MAGIC_MIPSEB & 0xff) << 8) +
327 ((ECOFF_MAGIC_MIPSEB >> 8) & 0xff):
328 format_name = "MIPS1 BE";
329 encoding = ELFDATA2MSB;
330 break;
331 case ECOFF_MAGIC_MIPSEB:
332 /* NOTE: Big-endian header, little-endian code! */
333 format_name = "MIPS1 BE-LE";
334 encoding = ELFDATA2MSB;
335 program_byte_order = ELFDATA2LSB;
336 break;
337 case ECOFF_MAGIC_MIPSEL:
338 format_name = "MIPS1 LE";
339 encoding = ELFDATA2LSB;
340 break;
341 case ((ECOFF_MAGIC_MIPSEB2 & 0xff) << 8) +
342 ((ECOFF_MAGIC_MIPSEB2 >> 8) & 0xff):
343 format_name = "MIPS2 BE";
344 encoding = ELFDATA2MSB;
345 break;
346 case ECOFF_MAGIC_MIPSEL2:
347 format_name = "MIPS2 LE";
348 encoding = ELFDATA2LSB;
349 break;
350 case ((ECOFF_MAGIC_MIPSEB3 & 0xff) << 8) +
351 ((ECOFF_MAGIC_MIPSEB3 >> 8) & 0xff):
352 format_name = "MIPS3 BE";
353 encoding = ELFDATA2MSB;
354 break;
355 case ECOFF_MAGIC_MIPSEL3:
356 format_name = "MIPS3 LE";
357 encoding = ELFDATA2LSB;
358 break;
359 default:
360 fprintf(stderr, "%s: unimplemented ECOFF format, magic = "
361 "0x%04x\n", filename, (int)f_magic);
362 exit(1);
363 }
364
365 /* Read various header information: */
366 unencode(f_nscns, &exechdr.f.f_nscns, uint16_t);
367 unencode(f_symptr, &exechdr.f.f_symptr, uint32_t);
368 unencode(f_nsyms, &exechdr.f.f_nsyms, uint32_t);
369 debug("ECOFF, %s, %i sections, %i symbols @ 0x%lx\n",
370 format_name, f_nscns, f_nsyms, (long)f_symptr);
371
372 unencode(a_magic, &exechdr.a.magic, uint16_t);
373 unencode(a_tsize, &exechdr.a.tsize, uint32_t);
374 unencode(a_dsize, &exechdr.a.dsize, uint32_t);
375 unencode(a_bsize, &exechdr.a.bsize, uint32_t);
376 debug("magic 0x%04x, tsize 0x%x, dsize 0x%x, bsize 0x%x\n",
377 a_magic, (int)a_tsize, (int)a_dsize, (int)a_bsize);
378
379 unencode(a_tstart, &exechdr.a.text_start, uint32_t);
380 unencode(a_dstart, &exechdr.a.data_start, uint32_t);
381 unencode(a_bstart, &exechdr.a.bss_start, uint32_t);
382 debug("text @ 0x%08x, data @ 0x%08x, bss @ 0x%08x\n",
383 (int)a_tstart, (int)a_dstart, (int)a_bstart);
384
385 unencode(a_entry, &exechdr.a.entry, uint32_t);
386 unencode(a_gp, &exechdr.a.gp_value, uint32_t);
387 debug("entrypoint 0x%08x, gp = 0x%08x\n",
388 (int)a_entry, (int)a_gp);
389
390 /*
391 * Special hack for a MACH/pmax kernel, I don't know how applicable
392 * this is for other files:
393 * there are no sections (!), and a_magic = 0x0108 instead of
394 * 0x0107 as it is on most other (E)COFF files I've seen.
395 *
396 * Then load everything after the header to the text start address.
397 */
398 if (f_nscns == 0 && a_magic == 0x108) {
399 uint64_t where = a_tstart;
400 total_len = 0;
401 fseek(f, 0x50, SEEK_SET);
402 while (!feof(f)) {
403 chunk_size = 256;
404 len = fread(buf, 1, chunk_size, f);
405
406 if (len > 0)
407 m->cpus[0]->memory_rw(m->cpus[0], mem, where,
408 &buf[0], len, MEM_WRITE, NO_EXCEPTIONS);
409 where += len;
410 total_len += len;
411 }
412 debug("MACH/pmax hack (!), read 0x%x bytes\n", total_len);
413 }
414
415 /* Go through all the section headers: */
416 for (secn=0; secn<f_nscns; secn++) {
417 off_t s_scnptr, s_relptr, s_lnnoptr, oldpos;
418 int s_nreloc, s_nlnno, s_flags;
419 int s_size;
420 unsigned int i;
421 uint64_t s_paddr, s_vaddr;
422
423 /* Read a section header: */
424 len = fread(&scnhdr, 1, sizeof(scnhdr), f);
425 if (len != sizeof(scnhdr)) {
426 fprintf(stderr, "%s: incomplete section "
427 "header %i\n", filename, secn);
428 exit(1);
429 }
430
431 /* Show the section name: */
432 debug("section ");
433 for (i=0; i<sizeof(scnhdr.s_name); i++)
434 if (scnhdr.s_name[i] >= 32 && scnhdr.s_name[i] < 127)
435 debug("%c", scnhdr.s_name[i]);
436 else
437 break;
438 debug(" (");
439
440 unencode(s_paddr, &scnhdr.s_paddr, uint32_t);
441 unencode(s_vaddr, &scnhdr.s_vaddr, uint32_t);
442 unencode(s_size, &scnhdr.s_size, uint32_t);
443 unencode(s_scnptr, &scnhdr.s_scnptr, uint32_t);
444 unencode(s_relptr, &scnhdr.s_relptr, uint32_t);
445 unencode(s_lnnoptr, &scnhdr.s_lnnoptr, uint32_t);
446 unencode(s_nreloc, &scnhdr.s_nreloc, uint16_t);
447 unencode(s_nlnno, &scnhdr.s_nlnno, uint16_t);
448 unencode(s_flags, &scnhdr.s_flags, uint32_t);
449
450 debug("0x%x @ 0x%08x, offset 0x%lx, flags 0x%x)\n",
451 (int)s_size, (int)s_vaddr, (long)s_scnptr, (int)s_flags);
452
453 end_addr = s_vaddr + s_size;
454
455 if (s_relptr != 0) {
456 /*
457 * TODO: Read this url, or similar:
458 * http://www.iecc.com/linker/linker07.html
459 */
460 fprintf(stderr, "%s: relocatable code/data in "
461 "section nr %i: not yet implemented\n",
462 filename, secn);
463 exit(1);
464 }
465
466 /* Loadable? Then load the section: */
467 if (s_scnptr != 0 && s_size != 0 &&
468 s_vaddr != 0 && !(s_flags & 0x02)) {
469 /* Remember the current file offset: */
470 oldpos = ftell(f);
471
472 /* Load the section into emulated memory: */
473 fseek(f, s_scnptr, SEEK_SET);
474 total_len = 0;
475 chunk_size = 1;
476 if ((s_vaddr & 0xf) == 0) chunk_size = 0x10;
477 if ((s_vaddr & 0xff) == 0) chunk_size = 0x100;
478 if ((s_vaddr & 0xfff) == 0) chunk_size = 0x1000;
479 while (total_len < s_size) {
480 len = chunk_size;
481 if (total_len + len > s_size)
482 len = s_size - total_len;
483 len = fread(buf, 1, chunk_size, f);
484 if (len == 0) {
485 debug("!!! total_len = %i, "
486 "chunk_size = %i, len = %i\n",
487 total_len, chunk_size, len);
488 break;
489 }
490
491 m->cpus[0]->memory_rw(m->cpus[0], mem, s_vaddr,
492 &buf[0], len, MEM_WRITE, NO_EXCEPTIONS);
493 s_vaddr += len;
494 total_len += len;
495 }
496
497 /* Return to position inside the section headers: */
498 fseek(f, oldpos, SEEK_SET);
499 }
500 }
501
502 if (f_symptr != 0 && f_nsyms != 0) {
503 struct ecoff_symhdr symhdr;
504 int sym_magic, iextMax, issExtMax, issMax, crfd;
505 off_t cbRfdOffset, cbExtOffset, cbSsExtOffset, cbSsOffset;
506 char *symbol_data;
507 struct ecoff_extsym *extsyms;
508 int nsymbols, sym_nr;
509
510 fseek(f, f_symptr, SEEK_SET);
511
512 len = fread(&symhdr, 1, sizeof(symhdr), f);
513 if (len != sizeof(symhdr)) {
514 fprintf(stderr, "%s: not a complete "
515 "ecoff image: symhdr broken\n", filename);
516 exit(1);
517 }
518
519 unencode(sym_magic, &symhdr.magic, uint16_t);
520 unencode(crfd, &symhdr.crfd, uint32_t);
521 unencode(cbRfdOffset, &symhdr.cbRfdOffset, uint32_t);
522 unencode(issMax, &symhdr.issMax, uint32_t);
523 unencode(cbSsOffset, &symhdr.cbSsOffset, uint32_t);
524 unencode(issExtMax, &symhdr.issExtMax, uint32_t);
525 unencode(cbSsExtOffset, &symhdr.cbSsExtOffset, uint32_t);
526 unencode(iextMax, &symhdr.iextMax, uint32_t);
527 unencode(cbExtOffset, &symhdr.cbExtOffset, uint32_t);
528
529 if (sym_magic != MIPS_MAGIC_SYM) {
530 unsigned char *ms_sym_buf;
531 struct ms_sym *sym;
532 int n_real_symbols = 0;
533
534 debug("bad symbol magic, assuming Microsoft format: ");
535
536 /*
537 * See http://www.lisoleg.net/lisoleg/elfandlib/
538 * Microsoft%20Portable%20Executable%20COFF%20For
539 * mat%20Specification.txt
540 * for more details.
541 */
542 ms_sym_buf = malloc(sizeof(struct ms_sym) * f_nsyms);
543 if (ms_sym_buf == NULL) {
544 fprintf(stderr, "out of memory\n");
545 exit(1);
546 }
547 fseek(f, f_symptr, SEEK_SET);
548 len = fread(ms_sym_buf, 1,
549 sizeof(struct ms_sym) * f_nsyms, f);
550 sym = (struct ms_sym *) ms_sym_buf;
551 for (sym_nr=0; sym_nr<f_nsyms; sym_nr++) {
552 char name[300];
553 uint32_t v, t, altname;
554 /* debug("sym %5i: '", sym_nr);
555 for (i=0; i<8 && sym->name[i]; i++)
556 debug("%c", sym->name[i]); */
557 v = sym->value[0] + (sym->value[1] << 8)
558 + (sym->value[2] << 16)
559 + (sym->value[3] << 24);
560 altname = sym->name[4] + (sym->name[5] << 8)
561 + (sym->name[6] << 16)
562 + (sym->name[3] << 24);
563 t = (sym->type[1] << 8) + sym->type[0];
564 /* TODO: big endian COFF? */
565 /* debug("' value=0x%x type=0x%04x", v, t); */
566
567 if (t == 0x20 && sym->name[0]) {
568 memcpy(name, sym->name, 8);
569 name[8] = '\0';
570 add_symbol_name(&m->symbol_context,
571 v, 0, name, 0);
572 n_real_symbols ++;
573 } else if (t == 0x20 && !sym->name[0]) {
574 off_t ofs;
575 ofs = f_symptr + altname +
576 sizeof(struct ms_sym) * f_nsyms;
577 fseek(f, ofs, SEEK_SET);
578 fread(name, 1, sizeof(name), f);
579 name[sizeof(name)-1] = '\0';
580 /* debug(" [altname=0x%x '%s']",
581 altname, name); */
582 add_symbol_name(&m->symbol_context,
583 v, 0, name, 0);
584 n_real_symbols ++;
585 }
586
587
588 if (sym->n_aux_syms) {
589 int n = sym->n_aux_syms;
590 /* debug(" aux='"); */
591 while (n-- > 0) {
592 sym ++; sym_nr ++;
593 /* for (i=0; i<8 &&
594 sym->name[i]; i++)
595 debug("%c",
596 sym->name[i]); */
597 }
598 /* debug("'"); */
599 }
600 /* debug("\n"); */
601 sym ++;
602 }
603
604 debug("%i symbols\n", n_real_symbols);
605 free(ms_sym_buf);
606
607 goto skip_normal_coff_symbols;
608 }
609
610 debug("symbol header: magic = 0x%x\n", sym_magic);
611
612 debug("%i symbols @ 0x%08x (strings @ 0x%08x)\n",
613 iextMax, cbExtOffset, cbSsExtOffset);
614
615 symbol_data = malloc(issExtMax + 2);
616 if (symbol_data == NULL) {
617 fprintf(stderr, "out of memory\n");
618 exit(1);
619 }
620 memset(symbol_data, 0, issExtMax + 2);
621 fseek(f, cbSsExtOffset, SEEK_SET);
622 fread(symbol_data, 1, issExtMax + 1, f);
623
624 nsymbols = iextMax;
625
626 extsyms = malloc(iextMax * sizeof(struct ecoff_extsym));
627 if (extsyms == NULL) {
628 fprintf(stderr, "out of memory\n");
629 exit(1);
630 }
631 memset(extsyms, 0, iextMax * sizeof(struct ecoff_extsym));
632 fseek(f, cbExtOffset, SEEK_SET);
633 fread(extsyms, 1, iextMax * sizeof(struct ecoff_extsym), f);
634
635 /* Unencode the strindex and value first: */
636 for (sym_nr=0; sym_nr<nsymbols; sym_nr++) {
637 uint64_t value, strindex;
638
639 unencode(strindex, &extsyms[sym_nr].es_strindex,
640 uint32_t);
641 unencode(value, &extsyms[sym_nr].es_value, uint32_t);
642
643 extsyms[sym_nr].es_strindex = strindex;
644 extsyms[sym_nr].es_value = value;
645 }
646
647 for (sym_nr=0; sym_nr<nsymbols; sym_nr++) {
648 /* debug("symbol%6i: 0x%08x = %s\n",
649 sym_nr, (int)extsyms[sym_nr].es_value,
650 symbol_data + extsyms[sym_nr].es_strindex); */
651
652 add_symbol_name(&m->symbol_context,
653 extsyms[sym_nr].es_value, 0,
654 symbol_data + extsyms[sym_nr].es_strindex, 0);
655 }
656
657 free(extsyms);
658 free(symbol_data);
659
660 skip_normal_coff_symbols:
661 ;
662 }
663
664 fclose(f);
665
666 *entrypointp = a_entry;
667 *gpp = a_gp;
668 m->file_loaded_end_addr = end_addr;
669
670 if (program_byte_order != -1)
671 encoding = program_byte_order;
672
673 if (encoding == ELFDATA2LSB)
674 *byte_orderp = EMUL_LITTLE_ENDIAN;
675 else
676 *byte_orderp = EMUL_BIG_ENDIAN;
677
678 n_executables_loaded ++;
679 }
680
681
682 /*
683 * file_load_srec():
684 *
685 * Loads a Motorola SREC file into emulated memory. Description of the SREC
686 * file format can be found at here:
687 *
688 * http://www.ndsu.nodak.edu/instruct/tareski/373f98/notes/srecord.htm
689 * or http://www.amelek.gda.pl/avr/uisp/srecord.htm
690 */
691 static void file_load_srec(struct machine *m, struct memory *mem,
692 char *filename, uint64_t *entrypointp)
693 {
694 FILE *f;
695 unsigned char buf[516];
696 unsigned char bytes[270];
697 uint64_t entry = 0, vaddr = 0;
698 int i, j, count;
699 char ch;
700 int buf_len, data_start = 0;
701 int entry_set = 0;
702 int warning = 0;
703 int warning_len = 0;
704 int total_bytes_loaded = 0;
705
706 f = fopen(filename, "r");
707 if (f == NULL) {
708 perror(filename);
709 exit(1);
710 }
711
712 /* Load file contents: */
713 while (!feof(f)) {
714 memset(buf, 0, sizeof(buf));
715 fgets((char *)buf, sizeof(buf)-1, f);
716
717 if (buf[0] == 0 || buf[0]=='\r' || buf[0]=='\n')
718 continue;
719
720 if (buf[0] != 'S') {
721 if (!warning)
722 debug("WARNING! non-S-record found\n");
723 warning = 1;
724 continue;
725 }
726
727 buf_len = strlen((char *)buf);
728
729 if (buf_len < 10) {
730 if (!warning_len)
731 debug("WARNING! invalid S-record found\n");
732 warning_len = 1;
733 continue;
734 }
735
736 /*
737 * Stype count address data checksum
738 * 01 23 4.. .. (last 2 bytes)
739 *
740 * TODO: actually check the checksum
741 */
742
743 j = 0;
744 for (i=1; i<buf_len; i++) {
745 if (buf[i]>='a' && buf[i]<='f')
746 buf[i] += 10 - 'a';
747 else if (buf[i] >= 'A' && buf[i] <= 'F')
748 buf[i] += 10 - 'A';
749 else if (buf[i] >= '0' && buf[i] <= '9')
750 buf[i] -= '0';
751 else if (buf[i] == '\r' || buf[i] == '\n') {
752 } else
753 fatal("invalid characters '%c' in S-record\n",
754 buf[i]);
755
756 if (i >= 4) {
757 if (i & 1)
758 bytes[j++] += buf[i];
759 else
760 bytes[j] = buf[i] * 16;
761 }
762 }
763
764 count = buf[2] * 16 + buf[3];
765 /* debug("count=%i j=%i\n", count, j); */
766 /* count is j - 1. */
767
768 switch (buf[1]) {
769 case 0:
770 debug("SREC \"");
771 for (i=2; i<count-1; i++) {
772 ch = bytes[i];
773 if (ch >= ' ' && ch < 127)
774 debug("%c", ch);
775 else
776 debug("?");
777 }
778 debug("\"\n");
779 break;
780 case 1:
781 case 2:
782 case 3:
783 /* switch again, to get the load address: */
784 switch (buf[1]) {
785 case 1: data_start = 2;
786 vaddr = (bytes[0] << 8) + bytes[1];
787 break;
788 case 2: data_start = 3;
789 vaddr = (bytes[0] << 16) + (bytes[1] << 8) +
790 bytes[2];
791 break;
792 case 3: data_start = 4;
793 vaddr = (bytes[0] << 24) + (bytes[1] << 16) +
794 (bytes[2] << 8) + bytes[3];
795 }
796 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
797 &bytes[data_start], count - 1 - data_start,
798 MEM_WRITE, NO_EXCEPTIONS);
799 total_bytes_loaded += count - 1 - data_start;
800 break;
801 case 7:
802 case 8:
803 case 9:
804 /* switch again, to get the entry point: */
805 switch (buf[1]) {
806 case 7: entry = (bytes[0] << 24) + (bytes[1] << 16) +
807 (bytes[2] << 8) + bytes[3];
808 break;
809 case 8: entry = (bytes[0] << 16) + (bytes[1] << 8) +
810 bytes[2];
811 break;
812 case 9: entry = (bytes[0] << 8) + bytes[1];
813 break;
814 }
815 entry_set = 1;
816 debug("entry point 0x%08x\n", (unsigned int)entry);
817 break;
818 default:
819 debug("unimplemented S-record type %i\n", buf[1]);
820 }
821 }
822
823 debug("0x%x bytes loaded\n", total_bytes_loaded);
824
825 fclose(f);
826
827 if (!entry_set)
828 debug("WARNING! no entrypoint found!\n");
829 else
830 *entrypointp = entry;
831
832 n_executables_loaded ++;
833 }
834
835
836 /*
837 * file_load_raw():
838 *
839 * Loads a raw binary into emulated memory. The filename should be
840 * of the following form: loadaddress:filename
841 * or loadaddress:skiplen:filename
842 * or loadaddress:skiplen:pc:filename
843 */
844 static void file_load_raw(struct machine *m, struct memory *mem,
845 char *filename, uint64_t *entrypointp)
846 {
847 FILE *f;
848 int len;
849 unsigned char buf[4096];
850 uint64_t entry, loadaddr, vaddr, skip = 0;
851 char *p, *p2;
852
853 p = strchr(filename, ':');
854 if (p == NULL) {
855 fprintf(stderr, "\n");
856 perror(filename);
857 exit(1);
858 }
859
860 loadaddr = vaddr = entry = strtoull(filename, NULL, 0);
861 p2 = p+1;
862
863 /* A second value? That's the optional skip value */
864 p = strchr(p2, ':');
865 if (p != NULL) {
866 skip = strtoull(p2, NULL, 0);
867 p = p+1;
868 /* A third value? That's the initial pc: */
869 if (strchr(p, ':') != NULL) {
870 entry = strtoull(p, NULL, 0);
871 p = strchr(p, ':') + 1;
872 }
873 } else
874 p = p2;
875
876 f = fopen(strrchr(filename, ':')+1, "r");
877 if (f == NULL) {
878 perror(p);
879 exit(1);
880 }
881
882 fseek(f, skip, SEEK_SET);
883
884 /* Load file contents: */
885 while (!feof(f)) {
886 len = fread(buf, 1, sizeof(buf), f);
887
888 if (len > 0)
889 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr, &buf[0],
890 len, MEM_WRITE, NO_EXCEPTIONS);
891
892 vaddr += len;
893 }
894
895 debug("RAW: 0x%llx bytes @ 0x%08llx",
896 (long long) (ftell(f) - skip), (long long)loadaddr);
897 if (skip != 0)
898 debug(" (0x%llx bytes of header skipped)", (long long)skip);
899 debug("\n");
900
901 fclose(f);
902
903 *entrypointp = entry;
904
905 n_executables_loaded ++;
906 }
907
908
909 /*
910 * file_load_elf():
911 *
912 * Loads an ELF image into the emulated memory. The entry point (read from
913 * the ELF header) and the initial value of the gp register (read from the
914 * ELF symbol table) are stored in the specified CPU's registers.
915 *
916 * This is pretty heavy stuff, but is needed because of the heaviness of
917 * ELF files. :-/ Hopefully it will be able to recognize most valid ELFs.
918 */
919 static void file_load_elf(struct machine *m, struct memory *mem,
920 char *filename, uint64_t *entrypointp, int arch, uint64_t *gpp,
921 int *byte_order, uint64_t *tocp)
922 {
923 Elf32_Ehdr hdr32;
924 Elf64_Ehdr hdr64;
925 FILE *f;
926 uint64_t eentry;
927 int len, i, ok;
928 int elf64, encoding, eflags;
929 int etype, emachine;
930 int ephnum, ephentsize, eshnum, eshentsize;
931 off_t ephoff, eshoff;
932 Elf32_Phdr phdr32;
933 Elf64_Phdr phdr64;
934 Elf32_Shdr shdr32;
935 Elf64_Shdr shdr64;
936 Elf32_Sym sym32;
937 Elf64_Sym sym64;
938 int ofs;
939 int chunk_len = 1024, align_len;
940 char *symbol_strings = NULL; size_t symbol_length = 0;
941 char *s;
942 Elf32_Sym *symbols_sym32 = NULL; int n_symbols = 0;
943 Elf64_Sym *symbols_sym64 = NULL;
944
945 f = fopen(filename, "r");
946 if (f == NULL) {
947 perror(filename);
948 exit(1);
949 }
950
951 len = fread(&hdr32, 1, sizeof(Elf32_Ehdr), f);
952 if (len < (signed int)sizeof(Elf32_Ehdr)) {
953 fprintf(stderr, "%s: not an ELF file image\n", filename);
954 exit(1);
955 }
956
957 if (memcmp(&hdr32.e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0) {
958 fprintf(stderr, "%s: not an ELF file image\n", filename);
959 exit(1);
960 }
961
962 switch (hdr32.e_ident[EI_CLASS]) {
963 case ELFCLASS32:
964 elf64 = 0;
965 break;
966 case ELFCLASS64:
967 elf64 = 1;
968 fseek(f, 0, SEEK_SET);
969 len = fread(&hdr64, 1, sizeof(Elf64_Ehdr), f);
970 if (len < (signed int)sizeof(Elf64_Ehdr)) {
971 fprintf(stderr, "%s: not an ELF64 file image\n",
972 filename);
973 exit(1);
974 }
975 break;
976 default:
977 fprintf(stderr, "%s: unknown ELF class '%i'\n",
978 filename, hdr32.e_ident[EI_CLASS]);
979 exit(1);
980 }
981
982 encoding = hdr32.e_ident[EI_DATA];
983 if (encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) {
984 fprintf(stderr, "%s: unknown data encoding '%i'\n",
985 filename, hdr32.e_ident[EI_DATA]);
986 exit(1);
987 }
988
989 if (elf64) {
990 unencode(etype, &hdr64.e_type, Elf64_Quarter);
991 unencode(eflags, &hdr64.e_flags, Elf64_Half);
992 unencode(emachine, &hdr64.e_machine, Elf64_Quarter);
993 unencode(eentry, &hdr64.e_entry, Elf64_Addr);
994 unencode(ephnum, &hdr64.e_phnum, Elf64_Quarter);
995 unencode(ephentsize, &hdr64.e_phentsize, Elf64_Quarter);
996 unencode(ephoff, &hdr64.e_phoff, Elf64_Off);
997 unencode(eshnum, &hdr64.e_shnum, Elf64_Quarter);
998 unencode(eshentsize, &hdr64.e_shentsize, Elf64_Quarter);
999 unencode(eshoff, &hdr64.e_shoff, Elf64_Off);
1000 if (ephentsize != sizeof(Elf64_Phdr)) {
1001 fprintf(stderr, "%s: incorrect phentsize? %i, should "
1002 "be %i\n", filename, (int)ephentsize,
1003 (int)sizeof(Elf64_Phdr));
1004 exit(1);
1005 }
1006 if (eshentsize != sizeof(Elf64_Shdr)) {
1007 fprintf(stderr, "%s: incorrect phentsize? %i, should "
1008 "be %i\n", filename, (int)ephentsize,
1009 (int)sizeof(Elf64_Shdr));
1010 exit(1);
1011 }
1012 } else {
1013 unencode(etype, &hdr32.e_type, Elf32_Half);
1014 unencode(eflags, &hdr32.e_flags, Elf32_Word);
1015 unencode(emachine, &hdr32.e_machine, Elf32_Half);
1016 unencode(eentry, &hdr32.e_entry, Elf32_Addr);
1017 unencode(ephnum, &hdr32.e_phnum, Elf32_Half);
1018 unencode(ephentsize, &hdr32.e_phentsize, Elf32_Half);
1019 unencode(ephoff, &hdr32.e_phoff, Elf32_Off);
1020 unencode(eshnum, &hdr32.e_shnum, Elf32_Half);
1021 unencode(eshentsize, &hdr32.e_shentsize, Elf32_Half);
1022 unencode(eshoff, &hdr32.e_shoff, Elf32_Off);
1023 if (ephentsize != sizeof(Elf32_Phdr)) {
1024 fprintf(stderr, "%s: incorrect phentsize? %i, should "
1025 "be %i\n", filename, (int)ephentsize,
1026 (int)sizeof(Elf32_Phdr));
1027 exit(1);
1028 }
1029 if (eshentsize != sizeof(Elf32_Shdr)) {
1030 fprintf(stderr, "%s: incorrect phentsize? %i, should "
1031 "be %i\n", filename, (int)ephentsize,
1032 (int)sizeof(Elf32_Shdr));
1033 exit(1);
1034 }
1035 }
1036
1037 if ( etype != ET_EXEC ) {
1038 fprintf(stderr, "%s is not an ELF Executable file, type = %i\n",
1039 filename, etype);
1040 exit(1);
1041 }
1042
1043 ok = 0;
1044 switch (arch) {
1045 case ARCH_ALPHA:
1046 switch (emachine) {
1047 case EM_ALPHA:
1048 case -28634:
1049 ok = 1;
1050 }
1051 break;
1052 case ARCH_HPPA:
1053 switch (emachine) {
1054 case EM_PARISC:
1055 ok = 1;
1056 }
1057 break;
1058 case ARCH_MIPS:
1059 switch (emachine) {
1060 case EM_MIPS:
1061 case EM_MIPS_RS3_LE:
1062 ok = 1;
1063 }
1064 break;
1065 case ARCH_PPC:
1066 switch (emachine) {
1067 case EM_PPC:
1068 case EM_PPC64:
1069 ok = 1;
1070 }
1071 break;
1072 case ARCH_SPARC:
1073 switch (emachine) {
1074 case EM_SPARC:
1075 case EM_SPARCV9:
1076 ok = 1;
1077 }
1078 break;
1079 case ARCH_X86:
1080 switch (emachine) {
1081 case EM_386:
1082 case EM_486:
1083 ok = 1;
1084 break;
1085 case EM_AMD64:
1086 *tocp = 1;
1087 ok = 1;
1088 break;
1089 }
1090 break;
1091 default:
1092 fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n");
1093 }
1094 if (!ok) {
1095 fprintf(stderr, "%s: this is a ", filename);
1096 if (emachine >= 0 && emachine < N_ELF_MACHINE_TYPES)
1097 fprintf(stderr, elf_machine_type[emachine]);
1098 else
1099 fprintf(stderr, "machine type '%i'", emachine);
1100 fprintf(stderr, " ELF binary!\n");
1101 exit(1);
1102 }
1103
1104 s = "entry point";
1105 if (elf64 && arch == ARCH_PPC)
1106 s = "function descriptor at";
1107
1108 debug("ELF%i %s, %s 0x", elf64? 64 : 32,
1109 encoding == ELFDATA2LSB? "LSB (LE)" : "MSB (BE)", s);
1110
1111 if (elf64)
1112 debug("%016llx\n", (long long)eentry);
1113 else
1114 debug("%08x\n", (int)eentry);
1115
1116 /*
1117 * MIPS16 encoding?
1118 *
1119 * TODO: Find out what e_flag actually contains.
1120 * TODO 2: This only sets mips16 for cpu 0. Yuck. Fix this!
1121 */
1122
1123 if (((eflags >> 24) & 0xff) == 0x24) {
1124 debug("MIPS16 encoding (e_flags = 0x%08x)\n", eflags);
1125 #ifdef ENABLE_MIPS16
1126 m->cpus[0]->cd.mips.mips16 = 1;
1127 #else
1128 fatal("ENABLE_MIPS16 must be defined in misc.h.\n"
1129 "(or use the --mips16 configure option)\n");
1130 exit(1);
1131 #endif
1132 } else if (eentry & 0x3) {
1133 debug("MIPS16 encoding (eentry not 32-bit aligned)\n");
1134 #ifdef ENABLE_MIPS16
1135 m->cpus[0]->cd.mips.mips16 = 1;
1136 #else
1137 fatal("ENABLE_MIPS16 must be defined in misc.h.\n"
1138 "(or use the --mips16 configure option)\n");
1139 exit(1);
1140 #endif
1141 }
1142
1143 /* Read the program headers: */
1144
1145 for (i=0; i<ephnum; i++) {
1146 int p_type;
1147 uint64_t p_offset;
1148 uint64_t p_vaddr;
1149 uint64_t p_paddr;
1150 uint64_t p_filesz;
1151 uint64_t p_memsz;
1152 int p_flags;
1153 int p_align;
1154
1155 fseek(f, ephoff + i * ephentsize, SEEK_SET);
1156
1157 if (elf64) {
1158 fread(&phdr64, 1, sizeof(Elf64_Phdr), f);
1159 unencode(p_type, &phdr64.p_type, Elf64_Half);
1160 unencode(p_flags, &phdr64.p_flags, Elf64_Half);
1161 unencode(p_offset, &phdr64.p_offset, Elf64_Off);
1162 unencode(p_vaddr, &phdr64.p_vaddr, Elf64_Addr);
1163 unencode(p_paddr, &phdr64.p_paddr, Elf64_Addr);
1164 unencode(p_filesz, &phdr64.p_filesz, Elf64_Xword);
1165 unencode(p_memsz, &phdr64.p_memsz, Elf64_Xword);
1166 unencode(p_align, &phdr64.p_align, Elf64_Xword);
1167 } else {
1168 fread(&phdr32, 1, sizeof(Elf32_Phdr), f);
1169 unencode(p_type, &phdr32.p_type, Elf32_Word);
1170 unencode(p_offset, &phdr32.p_offset, Elf32_Off);
1171 unencode(p_vaddr, &phdr32.p_vaddr, Elf32_Addr);
1172 unencode(p_paddr, &phdr32.p_paddr, Elf32_Addr);
1173 unencode(p_filesz, &phdr32.p_filesz, Elf32_Word);
1174 unencode(p_memsz, &phdr32.p_memsz, Elf32_Word);
1175 unencode(p_flags, &phdr32.p_flags, Elf32_Word);
1176 unencode(p_align, &phdr32.p_align, Elf32_Word);
1177 }
1178
1179 if (p_memsz != 0 && (p_type == PT_LOAD ||
1180 (p_type & PF_MASKPROC) == PT_MIPS_REGINFO)) {
1181 debug("chunk %i (", i);
1182 if (p_type == PT_LOAD)
1183 debug("load");
1184 else
1185 debug("0x%08x", (int)p_type);
1186
1187 debug(") @ 0x%llx, vaddr 0x", (long long)p_offset);
1188
1189 if (elf64)
1190 debug("%016llx", (long long)p_vaddr);
1191 else
1192 debug("%08x", (int)p_vaddr);
1193
1194 debug(" len=0x%llx\n", (long long)p_memsz);
1195
1196 if (p_vaddr != p_paddr) {
1197 fprintf(stderr, "%s: vaddr != paddr. TODO: "
1198 "how to handle this? vaddr=%016llx paddr"
1199 "=%016llx\n", filename, (long long)p_vaddr,
1200 (long long)p_paddr);
1201 exit(1);
1202 }
1203
1204 if (p_memsz < p_filesz) {
1205 fprintf(stderr, "%s: memsz < filesz. TODO: how"
1206 " to handle this? memsz=%016llx filesz="
1207 "%016llx\n", filename, (long long)p_memsz,
1208 (long long)p_filesz);
1209 exit(1);
1210 }
1211
1212 fseek(f, p_offset, SEEK_SET);
1213 align_len = 1;
1214 if ((p_vaddr & 0xf)==0) align_len = 0x10;
1215 if ((p_vaddr & 0x3f)==0) align_len = 0x40;
1216 if ((p_vaddr & 0xff)==0) align_len = 0x100;
1217 if ((p_vaddr & 0xfff)==0) align_len = 0x1000;
1218 if ((p_vaddr & 0x3fff)==0) align_len = 0x4000;
1219 if ((p_vaddr & 0xffff)==0) align_len = 0x10000;
1220 ofs = 0; len = chunk_len = align_len;
1221 while (ofs < (int64_t)p_filesz && len==chunk_len) {
1222 unsigned char *ch = malloc(chunk_len);
1223 int i = 0;
1224
1225 /* Switch to larger size, if possible: */
1226 if (align_len < 0x10000 &&
1227 ((p_vaddr + ofs) & 0xffff)==0) {
1228 align_len = 0x10000;
1229 len = chunk_len = align_len;
1230 free(ch);
1231 ch = malloc(chunk_len);
1232 } else if (align_len < 0x1000 &&
1233 ((p_vaddr + ofs) & 0xfff)==0) {
1234 align_len = 0x1000;
1235 len = chunk_len = align_len;
1236 free(ch);
1237 ch = malloc(chunk_len);
1238 }
1239
1240 if (ch == NULL) {
1241 fprintf(stderr, "out of memory\n");
1242 exit(1);
1243 }
1244
1245 len = fread(&ch[0], 1, chunk_len, f);
1246 if (ofs + len > (int64_t)p_filesz)
1247 len = p_filesz - ofs;
1248
1249 while (i < len) {
1250 size_t len_to_copy;
1251 len_to_copy = (i + align_len) <= len?
1252 align_len : len - i;
1253 m->cpus[0]->memory_rw(m->cpus[0], mem,
1254 p_vaddr + ofs, &ch[i], len_to_copy,
1255 MEM_WRITE, NO_EXCEPTIONS);
1256 ofs += align_len;
1257 i += align_len;
1258 }
1259
1260 free(ch);
1261 }
1262 }
1263 }
1264
1265 /* Read the section headers to find the address of the _gp symbol: */
1266
1267 for (i=0; i<eshnum; i++) {
1268 int sh_name, sh_type, sh_flags, sh_link, sh_info, sh_entsize;
1269 uint64_t sh_addr, sh_size, sh_addralign;
1270 off_t sh_offset;
1271 int n_entries; /* for reading the symbol / string tables */
1272
1273 /* debug("section header %i at %016llx\n", i,
1274 (long long) eshoff+i*eshentsize); */
1275
1276 fseek(f, eshoff + i * eshentsize, SEEK_SET);
1277
1278 if (elf64) {
1279 len = fread(&shdr64, 1, sizeof(Elf64_Shdr), f);
1280 if (len != sizeof(Elf64_Shdr)) {
1281 fprintf(stderr, "couldn't read header\n");
1282 exit(1);
1283 }
1284 unencode(sh_name, &shdr64.sh_name, Elf64_Half);
1285 unencode(sh_type, &shdr64.sh_type, Elf64_Half);
1286 unencode(sh_flags, &shdr64.sh_flags, Elf64_Xword);
1287 unencode(sh_addr, &shdr64.sh_addr, Elf64_Addr);
1288 unencode(sh_offset, &shdr64.sh_offset, Elf64_Off);
1289 unencode(sh_size, &shdr64.sh_size, Elf64_Xword);
1290 unencode(sh_link, &shdr64.sh_link, Elf64_Half);
1291 unencode(sh_info, &shdr64.sh_info, Elf64_Half);
1292 unencode(sh_addralign, &shdr64.sh_addralign,
1293 Elf64_Xword);
1294 unencode(sh_entsize, &shdr64.sh_entsize, Elf64_Xword);
1295 } else {
1296 len = fread(&shdr32, 1, sizeof(Elf32_Shdr), f);
1297 if (len != sizeof(Elf32_Shdr)) {
1298 fprintf(stderr, "couldn't read header\n");
1299 exit(1);
1300 }
1301 unencode(sh_name, &shdr32.sh_name, Elf32_Word);
1302 unencode(sh_type, &shdr32.sh_type, Elf32_Word);
1303 unencode(sh_flags, &shdr32.sh_flags, Elf32_Word);
1304 unencode(sh_addr, &shdr32.sh_addr, Elf32_Addr);
1305 unencode(sh_offset, &shdr32.sh_offset, Elf32_Off);
1306 unencode(sh_size, &shdr32.sh_size, Elf32_Word);
1307 unencode(sh_link, &shdr32.sh_link, Elf32_Word);
1308 unencode(sh_info, &shdr32.sh_info, Elf32_Word);
1309 unencode(sh_addralign, &shdr32.sh_addralign,Elf32_Word);
1310 unencode(sh_entsize, &shdr32.sh_entsize, Elf32_Word);
1311 }
1312
1313 /* debug("sh_name=%04lx, sh_type=%08lx, sh_flags=%08lx"
1314 " sh_size=%06lx sh_entsize=%03lx\n",
1315 (long)sh_name, (long)sh_type, (long)sh_flags,
1316 (long)sh_size, (long)sh_entsize); */
1317
1318 /* Perhaps it is bad to reuse sh_entsize like this? TODO */
1319 if (elf64)
1320 sh_entsize = sizeof(Elf64_Sym);
1321 else
1322 sh_entsize = sizeof(Elf32_Sym);
1323
1324 if (sh_type == SHT_SYMTAB) {
1325 size_t len;
1326 n_entries = sh_size / sh_entsize;
1327
1328 fseek(f, sh_offset, SEEK_SET);
1329
1330 if (elf64) {
1331 if (symbols_sym64 != NULL)
1332 free(symbols_sym64);
1333 symbols_sym64 = malloc(sh_size);
1334 if (symbols_sym64 == NULL) {
1335 fprintf(stderr, "out of memory\n");
1336 exit(1);
1337 }
1338
1339 len = fread(symbols_sym64, 1, sh_entsize *
1340 n_entries, f);
1341 } else {
1342 if (symbols_sym32 != NULL)
1343 free(symbols_sym32);
1344 symbols_sym32 = malloc(sh_size);
1345 if (symbols_sym32 == NULL) {
1346 fprintf(stderr, "out of memory\n");
1347 exit(1);
1348 }
1349
1350 len = fread(symbols_sym32, 1,
1351 sh_entsize * n_entries, f);
1352 }
1353
1354 if (len != sh_size) {
1355 fprintf(stderr, "could not read symbols from "
1356 "%s\n", filename);
1357 exit(1);
1358 }
1359
1360 debug("%i symbol entries at 0x%llx\n",
1361 (int)n_entries, (long long)sh_offset);
1362
1363 n_symbols = n_entries;
1364 }
1365
1366 /*
1367 * TODO: This is incorrect, there may be several strtab
1368 * sections.
1369 *
1370 * For now, the simple/stupid guess that the largest string
1371 * table is the one to use seems to be good enough.
1372 */
1373
1374 if (sh_type == SHT_STRTAB && sh_size > symbol_length) {
1375 size_t len;
1376
1377 if (symbol_strings != NULL)
1378 free(symbol_strings);
1379
1380 symbol_strings = malloc(sh_size + 1);
1381 if (symbol_strings == NULL) {
1382 fprintf(stderr, "out of memory\n");
1383 exit(1);
1384 }
1385
1386 fseek(f, sh_offset, SEEK_SET);
1387 len = fread(symbol_strings, 1, sh_size, f);
1388 if (len != sh_size) {
1389 fprintf(stderr, "could not read symbols from "
1390 "%s\n", filename);
1391 exit(1);
1392 }
1393
1394 debug("%i bytes of symbol strings at 0x%llx\n",
1395 (int)sh_size, (long long)sh_offset);
1396
1397 symbol_strings[sh_size] = '\0';
1398 symbol_length = sh_size;
1399 }
1400 }
1401
1402 fclose(f);
1403
1404 /* Decode symbols: */
1405 if (symbol_strings != NULL) {
1406 for (i=0; i<n_symbols; i++) {
1407 uint64_t st_name, addr, size;
1408 int st_info;
1409
1410 if (elf64) {
1411 sym64 = symbols_sym64[i];
1412 unencode(st_name, &sym64.st_name, Elf64_Half);
1413 unencode(st_info, &sym64.st_info, Elf_Byte);
1414 unencode(addr, &sym64.st_value, Elf64_Addr);
1415 unencode(size, &sym64.st_size, Elf64_Xword);
1416 } else {
1417 sym32 = symbols_sym32[i];
1418 unencode(st_name, &sym32.st_name, Elf32_Word);
1419 unencode(st_info, &sym64.st_info, Elf_Byte);
1420 unencode(addr, &sym32.st_value, Elf32_Word);
1421 unencode(size, &sym32.st_size, Elf32_Word);
1422 }
1423
1424 if (size == 0)
1425 size ++;
1426
1427 if (addr != 0) {
1428 /* debug("symbol info=0x%02x addr=0x%016llx"
1429 " '%s'\n", st_info, (long long)addr,
1430 symbol_strings + st_name); */
1431 add_symbol_name(&m->symbol_context,
1432 addr, size, symbol_strings + st_name, 0);
1433 }
1434
1435 if (strcmp(symbol_strings + st_name, "_gp") == 0) {
1436 debug("found _gp address: 0x");
1437 if (elf64)
1438 debug("%016llx\n", (long long)addr);
1439 else
1440 debug("%08x\n", (int)addr);
1441 *gpp = addr;
1442 }
1443 }
1444 }
1445
1446 *entrypointp = eentry;
1447
1448 if (encoding == ELFDATA2LSB)
1449 *byte_order = EMUL_LITTLE_ENDIAN;
1450 else
1451 *byte_order = EMUL_BIG_ENDIAN;
1452
1453 if (elf64 && arch == ARCH_PPC) {
1454 /*
1455 * Special case for 64-bit PPC ELFs:
1456 *
1457 * The ELF starting symbol points to a ".opd" section
1458 * which contains a function descriptor:
1459 *
1460 * uint64_t start;
1461 * uint64_t toc_base;
1462 * uint64_t something_else; (?)
1463 */
1464 int res;
1465 unsigned char b[sizeof(uint64_t)];
1466 uint64_t toc_base;
1467
1468 debug("PPC64: ");
1469
1470 res = m->cpus[0]->memory_rw(m->cpus[0], mem, eentry, b,
1471 sizeof(b), MEM_READ, NO_EXCEPTIONS);
1472 if (!res)
1473 debug(" [WARNING: could not read memory?] ");
1474
1475 /* PPC are always big-endian: */
1476 *entrypointp = ((uint64_t)b[0] << 56) +
1477 ((uint64_t)b[1] << 48) + ((uint64_t)b[2] << 40) +
1478 ((uint64_t)b[3] << 32) + ((uint64_t)b[4] << 24) +
1479 ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
1480 (uint64_t)b[7];
1481
1482 res = m->cpus[0]->memory_rw(m->cpus[0], mem, eentry + 8,
1483 b, sizeof(b), MEM_READ, NO_EXCEPTIONS);
1484 if (!res)
1485 fatal(" [WARNING: could not read memory?] ");
1486
1487 toc_base = ((uint64_t)b[0] << 56) +
1488 ((uint64_t)b[1] << 48) + ((uint64_t)b[2] << 40) +
1489 ((uint64_t)b[3] << 32) + ((uint64_t)b[4] << 24) +
1490 ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
1491 (uint64_t)b[7];
1492
1493 debug("entrypoint 0x%016llx, toc_base 0x%016llx\n",
1494 (long long)*entrypointp, (long long)toc_base);
1495 if (tocp != NULL)
1496 *tocp = toc_base;
1497 }
1498
1499 n_executables_loaded ++;
1500 }
1501
1502
1503 /*
1504 * file_n_executables_loaded():
1505 *
1506 * Returns the number of executable files loaded into emulated memory.
1507 */
1508 int file_n_executables_loaded(void)
1509 {
1510 return n_executables_loaded;
1511 }
1512
1513
1514 /*
1515 * file_load():
1516 *
1517 * Sense the file format of a file (ELF, a.out, ecoff), and call the
1518 * right file_load_XXX() function. If the file isn't of a recognized
1519 * binary format, assume that it contains symbol definitions.
1520 *
1521 * If the filename doesn't exist, try to treat the name as
1522 * "address:filename" and load the file as a raw binary.
1523 */
1524 void file_load(struct machine *machine, struct memory *mem,
1525 char *filename, uint64_t *entrypointp,
1526 int arch, uint64_t *gpp, int *byte_orderp, uint64_t *tocp)
1527 {
1528 int iadd = 4;
1529 FILE *f;
1530 unsigned char buf[12];
1531 int len, i;
1532 off_t size;
1533
1534 if (byte_orderp == NULL) {
1535 fprintf(stderr, "file_load(): byte_order == NULL\n");
1536 exit(1);
1537 }
1538
1539 if (arch == ARCH_NOARCH) {
1540 fprintf(stderr, "file_load(): FATAL ERROR: no arch?\n");
1541 exit(1);
1542 }
1543
1544 if (mem == NULL || filename == NULL) {
1545 fprintf(stderr, "file_load(): mem or filename is NULL\n");
1546 exit(1);
1547 }
1548
1549 /* Skip configuration files: */
1550 if (filename[0] == '@')
1551 return;
1552
1553 debug("loading %s:\n", filename);
1554 debug_indentation(iadd);
1555
1556 f = fopen(filename, "r");
1557 if (f == NULL) {
1558 file_load_raw(machine, mem, filename, entrypointp);
1559 goto ret;
1560 }
1561
1562 fseek(f, 0, SEEK_END);
1563 size = ftell(f);
1564 fseek(f, 0, SEEK_SET);
1565
1566 memset(buf, 0, sizeof(buf));
1567 len = fread(buf, 1, sizeof(buf), f);
1568 fclose(f);
1569
1570 if (len < (signed int)sizeof(buf)) {
1571 fprintf(stderr, "\nThis file is too small to contain "
1572 "anything useful\n");
1573 exit(1);
1574 }
1575
1576 /* Is it an ELF? */
1577 if (buf[0] == 0x7f && buf[1]=='E' && buf[2]=='L' && buf[3]=='F') {
1578 file_load_elf(machine, mem, filename,
1579 entrypointp, arch, gpp, byte_orderp, tocp);
1580 goto ret;
1581 }
1582
1583 /* Is it an a.out? (Special case for DEC OSF1 kernels.) */
1584 if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) {
1585 file_load_aout(machine, mem, filename, 0,
1586 entrypointp, arch, byte_orderp);
1587 goto ret;
1588 }
1589 if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) {
1590 file_load_aout(machine, mem, filename, 1,
1591 entrypointp, arch, byte_orderp);
1592 goto ret;
1593 }
1594
1595 /*
1596 * Is it an ecoff?
1597 *
1598 * TODO: What's the deal with the magic value's byte order? Sometimes
1599 * it seems to be reversed for BE when compared to LE, but not always?
1600 */
1601 if (buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB ||
1602 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL ||
1603 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB2 ||
1604 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL2 ||
1605 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB3 ||
1606 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL3 ||
1607 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB ||
1608 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL ||
1609 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB2 ||
1610 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL2 ||
1611 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB3 ||
1612 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL3) {
1613 file_load_ecoff(machine, mem, filename, entrypointp,
1614 arch, gpp, byte_orderp);
1615 goto ret;
1616 }
1617
1618 /* Is it a Motorola SREC file? */
1619 if ((buf[0]=='S' && buf[1]>='0' && buf[1]<='9')) {
1620 file_load_srec(machine, mem, filename, entrypointp);
1621 goto ret;
1622 }
1623
1624 /* gzipped files are not supported: */
1625 if (buf[0]==0x1f && buf[1]==0x8b) {
1626 fprintf(stderr, "\nYou need to gunzip the file before you"
1627 " try to use it.\n");
1628 exit(1);
1629 }
1630
1631 if (size > 24000000) {
1632 fprintf(stderr, "\nThis file is very large (%lli bytes)\n",
1633 (long long)size);
1634 fprintf(stderr, "Are you sure it is a kernel and not a disk "
1635 "image?\n");
1636 exit(1);
1637 }
1638
1639 if (size == 1474560)
1640 fprintf(stderr, "Hm... this file is the size of a 1.44 MB "
1641 "floppy image. Maybe you forgot the\n-d switch?\n");
1642
1643 /*
1644 * Last resort: symbol definitions from nm (or nm -S):
1645 *
1646 * If the buf contains typical 'binary' characters, then print
1647 * an error message and quit instead of assuming that it is a
1648 * symbol file.
1649 */
1650 for (i=0; i<(signed)sizeof(buf); i++)
1651 if (buf[i] < 32 && buf[i] != '\t' &&
1652 buf[i] != '\n' && buf[i] != '\r' &&
1653 buf[i] != '\f') {
1654 fprintf(stderr, "\nThe file format of '%s' is "
1655 "unknown.\n\n ", filename);
1656 for (i=0; i<(signed)sizeof(buf); i++)
1657 fprintf(stderr, " %02x", buf[i]);
1658 fprintf(stderr, "\n\nPossible explanations:\n\n"
1659 " o) If this is a disk image, you forgot '-d' "
1660 "on the command line.\n"
1661 " o) This is an unsupported binary format.\n\n");
1662 exit(1);
1663 }
1664
1665 symbol_readfile(&machine->symbol_context, filename);
1666
1667 ret:
1668 debug_indentation(-iadd);
1669 }
1670

  ViewVC Help
Powered by ViewVC 1.1.26