/[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 22 - (show annotations)
Mon Oct 8 16:19:37 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 57702 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1121 2006/02/18 21:03:08 debug Exp $
20051126	Cobalt and PReP now work with the 21143 NIC.
		Continuing on Alpha dyntrans things.
		Fixing some more left-shift-by-24 to unsigned.
20051127	Working on OpenFirmware emulation; major cleanup/redesign.
		Progress on MacPPC emulation: NetBSD detects two CPUs (when
		running with -n 2), framebuffer output (for text) works.
		Adding quick-hack Bandit PCI controller and "gc" interrupt
		controller for MacPPC.
20051128	Changing from a Bandit to a Uni-North controller for macppc.
		Continuing on OpenFirmware and MacPPC emulation in general
		(obio controller, and wdc attached to the obio seems to work).
20051129	More work on MacPPC emulation (adding a dummy ADB controller).
		Continuing the PCI bus cleanup (endianness and tag composition)
		and rewriting all PCI controllers' access functions.
20051130	Various minor PPC dyntrans optimizations.
		Manually inlining some parts of the framebuffer redraw routine.
		Slowly beginning the conversion of the old MIPS emulation into
		dyntrans (but this will take quite some time to get right).
		Generalizing quick_pc_to_pointers.
20051201	Documentation update (David Muse has made available a kernel
		which simplifies Debian/DECstation installation).
		Continuing on the ADB bus controller.
20051202	Beginning a rewrite of the Zilog serial controller (dev_zs).
20051203	Continuing on the zs rewrite (now called dev_z8530); conversion
		to devinit style.
		Reworking some of the input-only vs output-only vs input-output
		details of src/console.c, better warning messages, and adding
		a debug dump.
		Removing the concept of "device state"; it wasn't really used.
		Changing some debug output (-vv should now be used to show all
		details about devices and busses; not shown during normal
		startup anymore).
		Beginning on some SPARC instruction disassembly support.
20051204	Minor PPC updates (WALNUT skeleton stuff).
		Continuing on the MIPS dyntrans rewrite.
		More progress on the ADB controller (a keyboard is "detected"
		by NetBSD and OpenBSD).
		Downgrading OpenBSD/arc as a guest OS from "working" to
		"almost working" in the documentation.
		Progress on Algor emulation ("v3" PCI controller).
20051205	Minor updates.
20051207	Sorting devices according to address; this reduces complexity
		of device lookups from O(n) to O(log n) in memory_rw (but no
		real performance increase (yet) in experiments).
20051210	Beginning the work on native dyntrans backends (by making a
		simple skeleton; so far only for Alpha hosts).
20051211	Some very minor SPARC updates.
20051215	Fixing a bug in the MIPS mul (note: not mult) instruction,
		so it also works with non-64-bit emulation. (Thanks to Alec
		Voropay for noticing the problem.)
20051216	More work on the fake/empty/simple/skeleton/whatever backend;
		performance doesn't increase, so this isn't really worth it,
		but it was probably worth it to prepare for a real backend
		later.
20051219	More instr call statistics gathering and analysis stuff.
20051220	Another fix for MIPS 'mul'. Also converting mul and {d,}cl{o,z}
		to dyntrans.
		memory_ppc.c syntax error fix (noticed by Peter Valchev).
		Beginning to move out machines from src/machine.c into
		individual files in src/machines (in a way similar to the
		autodev system for devices).
20051222	Updating the documentation regarding NetBSD/pmax 3.0.
20051223	- " - NetBSD/cats 3.0.
20051225	- " - NetBSD/hpcmips 3.0.
20051226	Continuing on the machine registry redesign.
		Adding support for ARM rrx (33-bit rotate).
		Fixing some signed/unsigned issues (exposed by gcc -W).
20051227	Fixing the bug which prevented a NetBSD/prep 3.0 install kernel
		from starting (triggered when an mtmsr was the last instruction
		on a page). Unfortunately not enough to get the kernel to run
		as well as the 2.1 kernels did.
20051230	Some dyntrans refactoring.
20051231	Continuing on the machine registry redesign.
20060101-10	Continuing... moving more machines. Moving MD interrupt stuff
		from machine.c into a new src/machines/interrupts.c.
20060114	Adding various mvmeppc machine skeletons.
20060115	Continuing on mvme* stuff. NetBSD/mvmeppc prints boot messages
		(for MVME1600) and reaches the root device prompt, but no
		specific hardware devices are emulated yet.
20060116	Minor updates to the mvme1600 emulation mode; the Eagle PCI bus
		seems to work without much modification, and a 21143 can be
		detected, interrupts might work (but untested so far).
		Adding a fake MK48Txx (mkclock) device, for NetBSD/mvmeppc.
20060121	Adding an aux control register for ARM. (A BIG thank you to
		Olivier Houchard for tracking down this bug.)
20060122	Adding more ARM instructions (smulXY), and dev_iq80321_7seg.
20060124	Adding disassembly of more ARM instructions (mia*, mra/mar),
		and some semi-bogus XScale and i80321 registers.
20060201-02	Various minor updates. Moving the last machines out of
		machine.c.
20060204	Adding a -c command line option, for running debugger commands
		before the simulation starts, but after all files have been
		loaded.
		Minor iq80321-related updates.
20060209	Minor hacks (DEVINIT macro, etc).
		Preparing for the generalization of the 64-bit dyntrans address
		translation subsystem.
20060216	Adding ARM ldrd (double-register load).
20060217	Continuing on various ARM-related stuff.
20060218	More progress on the ATA/wdc emulation for NetBSD/iq80321.
		NetBSD/evbarm can now be installed :-)  Updating the docs, etc.
		Continuing on Algor emulation.

==============  RELEASE 0.3.8  ==============


1 /*
2 * Copyright (C) 2003-2006 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.127 2006/01/22 23:20:33 debug Exp $
29 *
30 * This file contains functions which load executable images into (emulated)
31 * memory. File formats recognized so far are:
32 *
33 * a.out old format used by OpenBSD 2.x pmax kernels
34 * Mach-O MacOS X format, etc.
35 * ecoff old format used by Ultrix, Windows NT, etc
36 * srec Motorola SREC format
37 * raw raw binaries, "address:[skiplen:[entrypoint:]]filename"
38 * ELF 32-bit and 64-bit ELFs
39 *
40 * If a file is not of one of the above mentioned formats, it is assumed
41 * to be symbol data generated by 'nm' or 'nm -S'.
42 */
43
44 #include <stdio.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include <sys/types.h>
48
49 #include "cpu.h"
50 #include "exec_aout.h"
51 #include "exec_ecoff.h"
52 #include "exec_elf.h"
53 #include "machine.h"
54 #include "memory.h"
55 #include "misc.h"
56 #include "symbol.h"
57
58
59 extern int quiet_mode;
60 extern int verbose;
61
62
63 /* ELF machine types as strings: (same as exec_elf.h) */
64 #define N_ELF_MACHINE_TYPES 64
65 static char *elf_machine_type[N_ELF_MACHINE_TYPES] = {
66 "NONE", "M32", "SPARC", "386", /* 0..3 */
67 "68K", "88K", "486", "860", /* 4..7 */
68 "MIPS", "S370", "MIPS_RS3_LE", "RS6000", /* 8..11 */
69 "unknown12", "unknown13", "unknown14", "PARISC", /* 12..15 */
70 "NCUBE", "VPP500", "SPARC32PLUS", "960", /* 16..19 */
71 "PPC", "PPC64", "unknown22", "unknown23", /* 20..23 */
72 "unknown24", "unknown25", "unknown26", "unknown27", /* 24..27 */
73 "unknown28", "unknown29", "unknown30", "unknown31", /* 28..31 */
74 "unknown32", "unknown33", "unknown34", "unknown35", /* 32..35 */
75 "V800", "FR20", "RH32", "RCE", /* 36..39 */
76 "ARM", "ALPHA", "SH", "SPARCV9", /* 40..43 */
77 "TRICORE", "ARC", "H8_300", "H8_300H", /* 44..47 */
78 "H8S", "H8_500", "IA_64", "MIPS_X", /* 48..51 */
79 "COLDFIRE", "68HC12", "unknown54", "unknown55", /* 52..55 */
80 "unknown56", "unknown57", "unknown58", "unknown59", /* 56..59 */
81 "unknown60", "unknown61", "AMD64", "unknown63" /* 60..63 */
82 };
83
84
85 /*
86 * This should be increased by every routine here that actually loads an
87 * executable file into memory. (For example, loading a symbol file should
88 * NOT increase this.)
89 */
90 static int n_executables_loaded = 0;
91
92
93 struct aout_symbol {
94 uint32_t strindex;
95 uint32_t type;
96 uint32_t addr;
97 };
98
99 /* Special symbol format used by Microsoft-ish COFF files: */
100 struct ms_sym {
101 unsigned char name[8];
102 unsigned char value[4];
103 unsigned char section[2];
104 unsigned char type[2];
105 unsigned char storage_class;
106 unsigned char n_aux_syms;
107 };
108
109
110 #define unencode(var,dataptr,typ) { \
111 int Wi; unsigned char Wb; \
112 unsigned char *Wp = (unsigned char *) dataptr; \
113 int Wlen = sizeof(typ); \
114 var = 0; \
115 for (Wi=0; Wi<Wlen; Wi++) { \
116 if (encoding == ELFDATA2LSB) \
117 Wb = Wp[Wlen-1 - Wi]; \
118 else \
119 Wb = Wp[Wi]; \
120 if (Wi == 0 && (Wb & 0x80)) { \
121 var --; /* set var to -1 :-) */ \
122 var <<= 8; \
123 } \
124 var |= Wb; \
125 if (Wi < Wlen-1) \
126 var <<= 8; \
127 } \
128 }
129
130
131 #define AOUT_FLAG_DECOSF1 1
132 #define AOUT_FLAG_FROM_BEGINNING 2
133 #define AOUT_FLAG_VADDR_ZERO_HACK 4
134 #define AOUT_FLAG_NO_SIZES 8
135 /*
136 * file_load_aout():
137 *
138 * Loads an a.out binary image into the emulated memory. The entry point
139 * (read from the a.out header) is stored in the specified CPU's registers.
140 *
141 * TODO: This has to be rewritten / corrected to support multiple a.out
142 * formats, where text/data are aligned differently.
143 */
144 static void file_load_aout(struct machine *m, struct memory *mem,
145 char *filename, int flags,
146 uint64_t *entrypointp, int arch, int *byte_orderp)
147 {
148 struct exec aout_header;
149 FILE *f;
150 int len;
151 int encoding = ELFDATA2LSB;
152 uint32_t entry, datasize, textsize;
153 int32_t symbsize = 0;
154 uint32_t vaddr, total_len;
155 unsigned char buf[65536];
156 unsigned char *syms;
157
158 if (m->cpus[0]->byte_order == EMUL_BIG_ENDIAN)
159 encoding = ELFDATA2MSB;
160
161 f = fopen(filename, "r");
162 if (f == NULL) {
163 perror(filename);
164 exit(1);
165 }
166
167 if (flags & AOUT_FLAG_DECOSF1) {
168 fread(&buf, 1, 32, f);
169 vaddr = buf[16] + (buf[17] << 8) +
170 (buf[18] << 16) + ((uint64_t)buf[19] << 24);
171 entry = buf[20] + (buf[21] << 8) +
172 (buf[22] << 16) + ((uint64_t)buf[23] << 24);
173 debug("OSF1 a.out, load address 0x%08lx, "
174 "entry point 0x%08x\n", (long)vaddr, (long)entry);
175 symbsize = 0;
176 fseek(f, 0, SEEK_END);
177 /* This is of course wrong, but should work anyway: */
178 textsize = ftello(f) - 512;
179 datasize = 0;
180 fseek(f, 512, SEEK_SET);
181 } else if (flags & AOUT_FLAG_NO_SIZES) {
182 fseek(f, 0, SEEK_END);
183 textsize = ftello(f) - 32;
184 datasize = 0;
185 vaddr = entry = 0;
186 fseek(f, 32, SEEK_SET);
187 } else {
188 len = fread(&aout_header, 1, sizeof(aout_header), f);
189 if (len != sizeof(aout_header)) {
190 fprintf(stderr, "%s: not a complete a.out image\n",
191 filename);
192 exit(1);
193 }
194
195 unencode(entry, &aout_header.a_entry, uint32_t);
196 debug("a.out, entry point 0x%08lx\n", (long)entry);
197 vaddr = entry;
198
199 if (flags & AOUT_FLAG_VADDR_ZERO_HACK)
200 vaddr = 0;
201
202 unencode(textsize, &aout_header.a_text, uint32_t);
203 unencode(datasize, &aout_header.a_data, uint32_t);
204 debug("text + data = %i + %i bytes\n", textsize, datasize);
205
206 unencode(symbsize, &aout_header.a_syms, uint32_t);
207 }
208
209 if (flags & AOUT_FLAG_FROM_BEGINNING) {
210 fseek(f, 0, SEEK_SET);
211 vaddr &= ~0xfff;
212 }
213
214 /* Load text and data: */
215 total_len = textsize + datasize;
216 while (total_len != 0) {
217 len = total_len > sizeof(buf) ? sizeof(buf) : total_len;
218 len = fread(buf, 1, len, f);
219
220 /* printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",
221 (int)len, (int)vaddr, buf[0], buf[1], buf[2]); */
222
223 if (len > 0) {
224 int len2 = 0;
225 uint64_t vaddr1 = vaddr &
226 ((1 << BITS_PER_MEMBLOCK) - 1);
227 uint64_t vaddr2 = (vaddr +
228 len) & ((1 << BITS_PER_MEMBLOCK) - 1);
229 if (vaddr2 < vaddr1) {
230 len2 = len - vaddr2;
231 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
232 &buf[0], len2, MEM_WRITE, NO_EXCEPTIONS);
233 }
234 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr + len2,
235 &buf[len2], len-len2, MEM_WRITE, NO_EXCEPTIONS);
236 } else {
237 if (flags & AOUT_FLAG_DECOSF1)
238 break;
239 else {
240 fprintf(stderr, "could not read from %s\n",
241 filename);
242 exit(1);
243 }
244 }
245
246 vaddr += len;
247 total_len -= len;
248 }
249
250 if (symbsize != 0) {
251 struct aout_symbol *aout_symbol_ptr;
252 int i, n_symbols;
253 uint32_t type, addr, str_index;
254 uint32_t strings_len;
255 char *string_symbols;
256 off_t oldpos;
257
258 debug("symbols: %i bytes @ 0x%x\n", symbsize, (int)ftello(f));
259 syms = malloc(symbsize);
260 if (syms == NULL) {
261 fprintf(stderr, "out of memory\n");
262 exit(1);
263 }
264 len = fread(syms, 1, symbsize, f);
265 if (len != symbsize) {
266 fprintf(stderr, "error reading symbols from %s\n",
267 filename);
268 exit(1);
269 }
270
271 oldpos = ftello(f);
272 fseek(f, 0, SEEK_END);
273 strings_len = ftello(f) - oldpos;
274 fseek(f, oldpos, SEEK_SET);
275 debug("strings: %i bytes @ 0x%x\n", strings_len,(int)ftello(f));
276 string_symbols = malloc(strings_len);
277 if (string_symbols == NULL) {
278 fprintf(stderr, "out of memory\n");
279 exit(1);
280 }
281 fread(string_symbols, 1, strings_len, f);
282
283 aout_symbol_ptr = (struct aout_symbol *) syms;
284 n_symbols = symbsize / sizeof(struct aout_symbol);
285 i = 0;
286 while (i < n_symbols) {
287 unencode(str_index, &aout_symbol_ptr[i].strindex,
288 uint32_t);
289 unencode(type, &aout_symbol_ptr[i].type, uint32_t);
290 unencode(addr, &aout_symbol_ptr[i].addr, uint32_t);
291
292 /* debug("symbol type 0x%04x @ 0x%08x: %s\n",
293 type, addr, string_symbols + str_index); */
294
295 if (type != 0 && addr != 0)
296 add_symbol_name(&m->symbol_context,
297 addr, 0, string_symbols + str_index, 0, -1);
298 i++;
299 }
300
301 free(string_symbols);
302 free(syms);
303 }
304
305 fclose(f);
306
307 *entrypointp = (int32_t)entry;
308
309 if (encoding == ELFDATA2LSB)
310 *byte_orderp = EMUL_LITTLE_ENDIAN;
311 else
312 *byte_orderp = EMUL_BIG_ENDIAN;
313
314 n_executables_loaded ++;
315 }
316
317
318 /*
319 * file_load_macho():
320 *
321 * Loads a Mach-O binary image into the emulated memory. The entry point
322 * is stored in the specified CPU's registers.
323 *
324 * TODO:
325 *
326 * o) Almost everything.
327 *
328 * o) I haven't had time to look into whether Apple's open source
329 * license is BSD-compatible or not. Perhaps it would be possible
330 * to use a header file containing symbolic names, and not use
331 * hardcoded values.
332 */
333 static void file_load_macho(struct machine *m, struct memory *mem,
334 char *filename, uint64_t *entrypointp, int arch, int *byte_orderp,
335 int is_64bit, int is_reversed)
336 {
337 FILE *f;
338 uint64_t entry = 0;
339 int entry_set = 0;
340 int encoding = ELFDATA2MSB;
341 unsigned char buf[65536];
342 char *symbols, *strings;
343 uint32_t cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags;
344 uint64_t vmaddr, vmsize, fileoff, filesize;
345 int cmd_type, cmd_len, i, flavor;
346 int32_t symoff, nsyms, stroff, strsize;
347 size_t len, pos;
348
349 if (m->cpus[0]->byte_order == EMUL_BIG_ENDIAN)
350 encoding = ELFDATA2MSB;
351
352 f = fopen(filename, "r");
353 if (f == NULL) {
354 perror(filename);
355 exit(1);
356 }
357
358 if (is_64bit) {
359 fatal("TODO: 64-bit Mach-O. Not supported yet.\n");
360 exit(1);
361 }
362 if (is_reversed) {
363 fatal("TODO: Reversed-endianness. Not supported yet.\n");
364 exit(1);
365 }
366
367 len = fread(buf, 1, sizeof(buf), f);
368 if (len < 100) {
369 fatal("Bad Mach-O file?\n");
370 exit(1);
371 }
372
373 unencode(cputype, &buf[4], uint32_t);
374 unencode(cpusubtype, &buf[8], uint32_t);
375 unencode(filetype, &buf[12], uint32_t);
376 unencode(ncmds, &buf[16], uint32_t);
377 unencode(sizeofcmds, &buf[20], uint32_t);
378 unencode(flags, &buf[24], uint32_t);
379
380 /* debug("cputype=0x%x cpusubtype=0x%x filetype=0x%x\n",
381 cputype, cpusubtype, filetype);
382 debug("ncmds=%i sizeofcmds=0x%08x flags=0x%08x\n",
383 ncmds, sizeofcmds, flags); */
384
385 /*
386 * Compare to "normal" values.
387 * NOTE/TODO: These were for a Darwin (Macintosh PPC) kernel.
388 */
389 if (cputype != 0x12) {
390 fatal("Error: Unimplemented cputype 0x%x\n", cputype);
391 exit(1);
392 }
393 if (cpusubtype != 0) {
394 fatal("Error: Unimplemented cpusubtype 0x%x\n", cpusubtype);
395 exit(1);
396 }
397 /* Filetype 2 means an executable image. */
398 if (filetype != 2) {
399 fatal("Error: Unimplemented filetype 0x%x\n", filetype);
400 exit(1);
401 }
402 if (!(flags & 1)) {
403 fatal("Error: File has 'undefined references'. Cannot"
404 " be executed.\n", flags);
405 exit(1);
406 }
407
408 /* I've only encountered flags == 1 so far. */
409 if (flags != 1) {
410 fatal("Error: Unimplemented flags 0x%x\n", flags);
411 exit(1);
412 }
413
414 /*
415 * Read all load commands:
416 */
417 pos = is_64bit? 32 : 28;
418 cmd_type = 0;
419 do {
420 /* Read command type and length: */
421 unencode(cmd_type, &buf[pos], uint32_t);
422 unencode(cmd_len, &buf[pos+4], uint32_t);
423
424 #if 0
425 debug("cmd %i, len=%i\n", cmd_type, cmd_len);
426 for (i=8; i<cmd_len; i++) {
427 unsigned char ch = buf[pos+i];
428 if (ch >= ' ' && ch < 127)
429 debug("%c", ch);
430 else
431 debug(".");
432 }
433 #endif
434 switch (cmd_type) {
435 case 1: /* LC_SEGMENT */
436 debug("seg ");
437 for (i=0; i<16; i++) {
438 if (buf[pos + 8 + i] == 0)
439 break;
440 debug("%c", buf[pos + 8 + i]);
441 }
442 unencode(vmaddr, &buf[pos+8+16+0], uint32_t);
443 unencode(vmsize, &buf[pos+8+16+4], uint32_t);
444 unencode(fileoff, &buf[pos+8+16+8], uint32_t);
445 unencode(filesize, &buf[pos+8+16+12], uint32_t);
446 debug(": vmaddr=0x%x size=0x%x fileoff=0x%x",
447 (int)vmaddr, (int)vmsize, (int)fileoff);
448
449 if (filesize == 0) {
450 debug("\n");
451 break;
452 }
453
454 fseek(f, fileoff, SEEK_SET);
455
456 /* Load data from the file: */
457 while (filesize != 0) {
458 unsigned char buf[32768];
459 ssize_t len = filesize > sizeof(buf) ?
460 sizeof(buf) : filesize;
461 len = fread(buf, 1, len, f);
462
463 /* printf("fread len=%i vmaddr=%x buf[0..]="
464 "%02x %02x %02x\n", (int)len, (int)vmaddr,
465 buf[0], buf[1], buf[2]); */
466
467 if (len > 0) {
468 int len2 = 0;
469 uint64_t vaddr1 = vmaddr &
470 ((1 << BITS_PER_MEMBLOCK) - 1);
471 uint64_t vaddr2 = (vmaddr +
472 len) & ((1 << BITS_PER_MEMBLOCK)-1);
473 if (vaddr2 < vaddr1) {
474 len2 = len - vaddr2;
475 m->cpus[0]->memory_rw(m->cpus[
476 0], mem, vmaddr, &buf[0],
477 len2, MEM_WRITE,
478 NO_EXCEPTIONS);
479 }
480 m->cpus[0]->memory_rw(m->cpus[0], mem,
481 vmaddr + len2, &buf[len2], len-len2,
482 MEM_WRITE, NO_EXCEPTIONS);
483 } else {
484 fprintf(stderr, "error reading\n");
485 exit(1);
486 }
487
488 vmaddr += len;
489 filesize -= len;
490 }
491
492 debug("\n");
493 break;
494
495 case 2: /* LC_SYMTAB */
496 unencode(symoff, &buf[pos+8], uint32_t);
497 unencode(nsyms, &buf[pos+12], uint32_t);
498 unencode(stroff, &buf[pos+16], uint32_t);
499 unencode(strsize, &buf[pos+20], uint32_t);
500 debug("symtable: %i symbols @ 0x%x (strings at "
501 "0x%x)\n", nsyms, symoff, stroff);
502
503 symbols = malloc(12 * nsyms);
504 if (symbols == NULL) {
505 fprintf(stderr, "out of memory\n");
506 exit(1);
507 }
508 fseek(f, symoff, SEEK_SET);
509 fread(symbols, 1, 12 * nsyms, f);
510
511 strings = malloc(strsize);
512 if (strings == NULL) {
513 fprintf(stderr, "out of memory\n");
514 exit(1);
515 }
516 fseek(f, stroff, SEEK_SET);
517 fread(strings, 1, strsize, f);
518
519 for (i=0; i<nsyms; i++) {
520 int n_strx, n_type, n_sect, n_desc;
521 uint32_t n_value;
522 unencode(n_strx, &symbols[i*12+0], int32_t);
523 unencode(n_type, &symbols[i*12+4], uint8_t);
524 unencode(n_sect, &symbols[i*12+5], uint8_t);
525 unencode(n_desc, &symbols[i*12+6], int16_t);
526 unencode(n_value, &symbols[i*12+8], uint32_t);
527 /* debug("%i: strx=%i type=%i sect=%i desc=%i"
528 " value=0x%x\n", i, n_strx, n_type,
529 n_sect, n_desc, n_value); */
530 add_symbol_name(&m->symbol_context,
531 n_value, 0, strings + n_strx, 0, -1);
532 }
533
534 free(symbols);
535 free(strings);
536 break;
537
538 case 5: debug("unix thread context: ");
539 /* See http://cvs.sf.net/viewcvs.py/hte/
540 HT%20Editor/machostruc.h or similar for details
541 on the thread struct. */
542 unencode(flavor, &buf[pos+8], uint32_t);
543 if (flavor != 1) {
544 fatal("unimplemented flavor %i\n", flavor);
545 exit(1);
546 }
547
548 if (arch != ARCH_PPC) {
549 fatal("non-PPC arch? TODO\n");
550 exit(1);
551 }
552
553 unencode(entry, &buf[pos+16], uint32_t);
554 entry_set = 1;
555 debug("pc=0x%x\n", (int)entry);
556
557 for (i=1; i<40; i++) {
558 uint32_t x;
559 unencode(x, &buf[pos+16+i*4], uint32_t);
560 if (x != 0) {
561 fatal("Entry nr %i in the Mach-O"
562 " thread struct is non-zero"
563 " (0x%x). This is not supported"
564 " yet. TODO\n", i, x);
565 exit(1);
566 }
567 }
568 break;
569
570 default:fatal("WARNING! Unimplemented load command %i!\n",
571 cmd_type);
572 }
573
574 pos += cmd_len;
575 } while (pos < sizeofcmds && cmd_type != 0);
576
577 fclose(f);
578
579 if (!entry_set) {
580 fatal("No entry point? Aborting.\n");
581 exit(1);
582 }
583
584 *entrypointp = entry;
585
586 if (encoding == ELFDATA2LSB)
587 *byte_orderp = EMUL_LITTLE_ENDIAN;
588 else
589 *byte_orderp = EMUL_BIG_ENDIAN;
590
591 n_executables_loaded ++;
592 }
593
594
595 /*
596 * file_load_ecoff():
597 *
598 * Loads an ecoff binary image into the emulated memory. The entry point
599 * (read from the ecoff header) is stored in the specified CPU's registers.
600 */
601 static void file_load_ecoff(struct machine *m, struct memory *mem,
602 char *filename, uint64_t *entrypointp,
603 int arch, uint64_t *gpp, int *byte_orderp)
604 {
605 struct ecoff_exechdr exechdr;
606 int f_magic, f_nscns, f_nsyms;
607 int a_magic;
608 off_t f_symptr, a_tsize, a_dsize, a_bsize;
609 uint64_t a_entry, a_tstart, a_dstart, a_bstart, a_gp, end_addr=0;
610 char *format_name;
611 struct ecoff_scnhdr scnhdr;
612 FILE *f;
613 int len, secn, total_len, chunk_size;
614 int encoding = ELFDATA2LSB; /* Assume little-endian. See below */
615 int program_byte_order = -1;
616 unsigned char buf[8192];
617
618 f = fopen(filename, "r");
619 if (f == NULL) {
620 perror(filename);
621 exit(1);
622 }
623
624 len = fread(&exechdr, 1, sizeof(exechdr), f);
625 if (len != sizeof(exechdr)) {
626 fprintf(stderr, " not a complete ecoff image\n");
627 exit(1);
628 }
629
630 /*
631 * The following code looks a bit ugly, but it should work. The ECOFF
632 * 16-bit magic value seems to be stored in MSB byte order for
633 * big-endian binaries, and LSB byte order for little-endian binaries.
634 *
635 * The unencode() assumes little-endianness by default.
636 */
637 unencode(f_magic, &exechdr.f.f_magic, uint16_t);
638 switch (f_magic) {
639 case ((ECOFF_MAGIC_MIPSEB & 0xff) << 8) +
640 ((ECOFF_MAGIC_MIPSEB >> 8) & 0xff):
641 format_name = "MIPS1 BE";
642 encoding = ELFDATA2MSB;
643 break;
644 case ECOFF_MAGIC_MIPSEB:
645 /* NOTE: Big-endian header, little-endian code! */
646 format_name = "MIPS1 BE-LE";
647 encoding = ELFDATA2MSB;
648 program_byte_order = ELFDATA2LSB;
649 break;
650 case ECOFF_MAGIC_MIPSEL:
651 format_name = "MIPS1 LE";
652 encoding = ELFDATA2LSB;
653 break;
654 case ((ECOFF_MAGIC_MIPSEB2 & 0xff) << 8) +
655 ((ECOFF_MAGIC_MIPSEB2 >> 8) & 0xff):
656 format_name = "MIPS2 BE";
657 encoding = ELFDATA2MSB;
658 break;
659 case ECOFF_MAGIC_MIPSEL2:
660 format_name = "MIPS2 LE";
661 encoding = ELFDATA2LSB;
662 break;
663 case ((ECOFF_MAGIC_MIPSEB3 & 0xff) << 8) +
664 ((ECOFF_MAGIC_MIPSEB3 >> 8) & 0xff):
665 format_name = "MIPS3 BE";
666 encoding = ELFDATA2MSB;
667 break;
668 case ECOFF_MAGIC_MIPSEL3:
669 format_name = "MIPS3 LE";
670 encoding = ELFDATA2LSB;
671 break;
672 default:
673 fprintf(stderr, "%s: unimplemented ECOFF format, magic = "
674 "0x%04x\n", filename, (int)f_magic);
675 exit(1);
676 }
677
678 /* Read various header information: */
679 unencode(f_nscns, &exechdr.f.f_nscns, uint16_t);
680 unencode(f_symptr, &exechdr.f.f_symptr, uint32_t);
681 unencode(f_nsyms, &exechdr.f.f_nsyms, uint32_t);
682 debug("ECOFF, %s, %i sections, %i symbols @ 0x%lx\n",
683 format_name, f_nscns, f_nsyms, (long)f_symptr);
684
685 unencode(a_magic, &exechdr.a.magic, uint16_t);
686 unencode(a_tsize, &exechdr.a.tsize, uint32_t);
687 unencode(a_dsize, &exechdr.a.dsize, uint32_t);
688 unencode(a_bsize, &exechdr.a.bsize, uint32_t);
689 debug("magic 0x%04x, tsize 0x%x, dsize 0x%x, bsize 0x%x\n",
690 a_magic, (int)a_tsize, (int)a_dsize, (int)a_bsize);
691
692 unencode(a_tstart, &exechdr.a.text_start, uint32_t);
693 unencode(a_dstart, &exechdr.a.data_start, uint32_t);
694 unencode(a_bstart, &exechdr.a.bss_start, uint32_t);
695 debug("text @ 0x%08x, data @ 0x%08x, bss @ 0x%08x\n",
696 (int)a_tstart, (int)a_dstart, (int)a_bstart);
697
698 unencode(a_entry, &exechdr.a.entry, uint32_t);
699 unencode(a_gp, &exechdr.a.gp_value, uint32_t);
700 debug("entrypoint 0x%08x, gp = 0x%08x\n",
701 (int)a_entry, (int)a_gp);
702
703 /*
704 * Special hack for a MACH/pmax kernel, I don't know how applicable
705 * this is for other files:
706 * there are no sections (!), and a_magic = 0x0108 instead of
707 * 0x0107 as it is on most other (E)COFF files I've seen.
708 *
709 * Then load everything after the header to the text start address.
710 */
711 if (f_nscns == 0 && a_magic == 0x108) {
712 uint64_t where = a_tstart;
713 total_len = 0;
714 fseek(f, 0x50, SEEK_SET);
715 while (!feof(f)) {
716 chunk_size = 256;
717 len = fread(buf, 1, chunk_size, f);
718
719 if (len > 0)
720 m->cpus[0]->memory_rw(m->cpus[0], mem, where,
721 &buf[0], len, MEM_WRITE, NO_EXCEPTIONS);
722 where += len;
723 total_len += len;
724 }
725 debug("MACH/pmax hack (!), read 0x%x bytes\n", total_len);
726 }
727
728 /* Go through all the section headers: */
729 for (secn=0; secn<f_nscns; secn++) {
730 off_t s_scnptr, s_relptr, s_lnnoptr, oldpos;
731 int s_nreloc, s_nlnno, s_flags;
732 int s_size;
733 unsigned int i;
734 uint64_t s_paddr, s_vaddr;
735
736 /* Read a section header: */
737 len = fread(&scnhdr, 1, sizeof(scnhdr), f);
738 if (len != sizeof(scnhdr)) {
739 fprintf(stderr, "%s: incomplete section "
740 "header %i\n", filename, secn);
741 exit(1);
742 }
743
744 /* Show the section name: */
745 debug("section ");
746 for (i=0; i<sizeof(scnhdr.s_name); i++)
747 if (scnhdr.s_name[i] >= 32 && scnhdr.s_name[i] < 127)
748 debug("%c", scnhdr.s_name[i]);
749 else
750 break;
751 debug(" (");
752
753 unencode(s_paddr, &scnhdr.s_paddr, uint32_t);
754 unencode(s_vaddr, &scnhdr.s_vaddr, uint32_t);
755 unencode(s_size, &scnhdr.s_size, uint32_t);
756 unencode(s_scnptr, &scnhdr.s_scnptr, uint32_t);
757 unencode(s_relptr, &scnhdr.s_relptr, uint32_t);
758 unencode(s_lnnoptr, &scnhdr.s_lnnoptr, uint32_t);
759 unencode(s_nreloc, &scnhdr.s_nreloc, uint16_t);
760 unencode(s_nlnno, &scnhdr.s_nlnno, uint16_t);
761 unencode(s_flags, &scnhdr.s_flags, uint32_t);
762
763 debug("0x%x @ 0x%08x, offset 0x%lx, flags 0x%x)\n",
764 (int)s_size, (int)s_vaddr, (long)s_scnptr, (int)s_flags);
765
766 end_addr = s_vaddr + s_size;
767
768 if (s_relptr != 0) {
769 /*
770 * TODO: Read this url, or similar:
771 * http://www.iecc.com/linker/linker07.html
772 */
773 fprintf(stderr, "%s: relocatable code/data in "
774 "section nr %i: not yet implemented\n",
775 filename, secn);
776 exit(1);
777 }
778
779 /* Loadable? Then load the section: */
780 if (s_scnptr != 0 && s_size != 0 &&
781 s_vaddr != 0 && !(s_flags & 0x02)) {
782 /* Remember the current file offset: */
783 oldpos = ftello(f);
784
785 /* Load the section into emulated memory: */
786 fseek(f, s_scnptr, SEEK_SET);
787 total_len = 0;
788 chunk_size = 1;
789 if ((s_vaddr & 0xf) == 0) chunk_size = 0x10;
790 if ((s_vaddr & 0xff) == 0) chunk_size = 0x100;
791 if ((s_vaddr & 0xfff) == 0) chunk_size = 0x1000;
792 while (total_len < s_size) {
793 len = chunk_size;
794 if (total_len + len > s_size)
795 len = s_size - total_len;
796 len = fread(buf, 1, chunk_size, f);
797 if (len == 0) {
798 debug("!!! total_len = %i, "
799 "chunk_size = %i, len = %i\n",
800 total_len, chunk_size, len);
801 break;
802 }
803
804 m->cpus[0]->memory_rw(m->cpus[0], mem, s_vaddr,
805 &buf[0], len, MEM_WRITE, NO_EXCEPTIONS);
806 s_vaddr += len;
807 total_len += len;
808 }
809
810 /* Return to position inside the section headers: */
811 fseek(f, oldpos, SEEK_SET);
812 }
813 }
814
815 if (f_symptr != 0 && f_nsyms != 0) {
816 struct ecoff_symhdr symhdr;
817 int sym_magic, iextMax, issExtMax, issMax, crfd;
818 off_t cbRfdOffset, cbExtOffset, cbSsExtOffset, cbSsOffset;
819 char *symbol_data;
820 struct ecoff_extsym *extsyms;
821 int nsymbols, sym_nr;
822
823 fseek(f, f_symptr, SEEK_SET);
824
825 len = fread(&symhdr, 1, sizeof(symhdr), f);
826 if (len != sizeof(symhdr)) {
827 fprintf(stderr, "%s: not a complete "
828 "ecoff image: symhdr broken\n", filename);
829 exit(1);
830 }
831
832 unencode(sym_magic, &symhdr.magic, uint16_t);
833 unencode(crfd, &symhdr.crfd, uint32_t);
834 unencode(cbRfdOffset, &symhdr.cbRfdOffset, uint32_t);
835 unencode(issMax, &symhdr.issMax, uint32_t);
836 unencode(cbSsOffset, &symhdr.cbSsOffset, uint32_t);
837 unencode(issExtMax, &symhdr.issExtMax, uint32_t);
838 unencode(cbSsExtOffset, &symhdr.cbSsExtOffset, uint32_t);
839 unencode(iextMax, &symhdr.iextMax, uint32_t);
840 unencode(cbExtOffset, &symhdr.cbExtOffset, uint32_t);
841
842 if (sym_magic != MIPS_MAGIC_SYM) {
843 unsigned char *ms_sym_buf;
844 struct ms_sym *sym;
845 int n_real_symbols = 0;
846
847 debug("bad symbol magic, assuming Microsoft format: ");
848
849 /*
850 * See http://www.lisoleg.net/lisoleg/elfandlib/
851 * Microsoft%20Portable%20Executable%20COFF%20For
852 * mat%20Specification.txt
853 * for more details.
854 */
855 ms_sym_buf = malloc(sizeof(struct ms_sym) * f_nsyms);
856 if (ms_sym_buf == NULL) {
857 fprintf(stderr, "out of memory\n");
858 exit(1);
859 }
860 fseek(f, f_symptr, SEEK_SET);
861 len = fread(ms_sym_buf, 1,
862 sizeof(struct ms_sym) * f_nsyms, f);
863 sym = (struct ms_sym *) ms_sym_buf;
864 for (sym_nr=0; sym_nr<f_nsyms; sym_nr++) {
865 char name[300];
866 uint32_t v, t, altname;
867 /* debug("sym %5i: '", sym_nr);
868 for (i=0; i<8 && sym->name[i]; i++)
869 debug("%c", sym->name[i]); */
870 v = sym->value[0] + (sym->value[1] << 8)
871 + (sym->value[2] << 16)
872 + ((uint64_t)sym->value[3] << 24);
873 altname = sym->name[4] + (sym->name[5] << 8)
874 + (sym->name[6] << 16)
875 + ((uint64_t)sym->name[3] << 24);
876 t = (sym->type[1] << 8) + sym->type[0];
877 /* TODO: big endian COFF? */
878 /* debug("' value=0x%x type=0x%04x", v, t); */
879
880 if (t == 0x20 && sym->name[0]) {
881 memcpy(name, sym->name, 8);
882 name[8] = '\0';
883 add_symbol_name(&m->symbol_context,
884 v, 0, name, 0, -1);
885 n_real_symbols ++;
886 } else if (t == 0x20 && !sym->name[0]) {
887 off_t ofs;
888 ofs = f_symptr + altname +
889 sizeof(struct ms_sym) * f_nsyms;
890 fseek(f, ofs, SEEK_SET);
891 fread(name, 1, sizeof(name), f);
892 name[sizeof(name)-1] = '\0';
893 /* debug(" [altname=0x%x '%s']",
894 altname, name); */
895 add_symbol_name(&m->symbol_context,
896 v, 0, name, 0, -1);
897 n_real_symbols ++;
898 }
899
900
901 if (sym->n_aux_syms) {
902 int n = sym->n_aux_syms;
903 /* debug(" aux='"); */
904 while (n-- > 0) {
905 sym ++; sym_nr ++;
906 /* for (i=0; i<8 &&
907 sym->name[i]; i++)
908 debug("%c",
909 sym->name[i]); */
910 }
911 /* debug("'"); */
912 }
913 /* debug("\n"); */
914 sym ++;
915 }
916
917 debug("%i symbols\n", n_real_symbols);
918 free(ms_sym_buf);
919
920 goto skip_normal_coff_symbols;
921 }
922
923 debug("symbol header: magic = 0x%x\n", sym_magic);
924
925 debug("%i symbols @ 0x%08x (strings @ 0x%08x)\n",
926 iextMax, cbExtOffset, cbSsExtOffset);
927
928 symbol_data = malloc(issExtMax + 2);
929 if (symbol_data == NULL) {
930 fprintf(stderr, "out of memory\n");
931 exit(1);
932 }
933 memset(symbol_data, 0, issExtMax + 2);
934 fseek(f, cbSsExtOffset, SEEK_SET);
935 fread(symbol_data, 1, issExtMax + 1, f);
936
937 nsymbols = iextMax;
938
939 extsyms = malloc(iextMax * sizeof(struct ecoff_extsym));
940 if (extsyms == NULL) {
941 fprintf(stderr, "out of memory\n");
942 exit(1);
943 }
944 memset(extsyms, 0, iextMax * sizeof(struct ecoff_extsym));
945 fseek(f, cbExtOffset, SEEK_SET);
946 fread(extsyms, 1, iextMax * sizeof(struct ecoff_extsym), f);
947
948 /* Unencode the strindex and value first: */
949 for (sym_nr=0; sym_nr<nsymbols; sym_nr++) {
950 uint64_t value, strindex;
951
952 unencode(strindex, &extsyms[sym_nr].es_strindex,
953 uint32_t);
954 unencode(value, &extsyms[sym_nr].es_value, uint32_t);
955
956 extsyms[sym_nr].es_strindex = strindex;
957 extsyms[sym_nr].es_value = value;
958 }
959
960 for (sym_nr=0; sym_nr<nsymbols; sym_nr++) {
961 /* debug("symbol%6i: 0x%08x = %s\n",
962 sym_nr, (int)extsyms[sym_nr].es_value,
963 symbol_data + extsyms[sym_nr].es_strindex); */
964
965 add_symbol_name(&m->symbol_context,
966 extsyms[sym_nr].es_value, 0,
967 symbol_data + extsyms[sym_nr].es_strindex, 0, -1);
968 }
969
970 free(extsyms);
971 free(symbol_data);
972
973 skip_normal_coff_symbols:
974 ;
975 }
976
977 fclose(f);
978
979 *entrypointp = a_entry;
980 *gpp = a_gp;
981 m->file_loaded_end_addr = end_addr;
982
983 if (program_byte_order != -1)
984 encoding = program_byte_order;
985
986 if (encoding == ELFDATA2LSB)
987 *byte_orderp = EMUL_LITTLE_ENDIAN;
988 else
989 *byte_orderp = EMUL_BIG_ENDIAN;
990
991 n_executables_loaded ++;
992 }
993
994
995 /*
996 * file_load_srec():
997 *
998 * Loads a Motorola SREC file into emulated memory. Description of the SREC
999 * file format can be found at here:
1000 *
1001 * http://www.ndsu.nodak.edu/instruct/tareski/373f98/notes/srecord.htm
1002 * or http://www.amelek.gda.pl/avr/uisp/srecord.htm
1003 */
1004 static void file_load_srec(struct machine *m, struct memory *mem,
1005 char *filename, uint64_t *entrypointp)
1006 {
1007 FILE *f;
1008 unsigned char buf[516];
1009 unsigned char bytes[270];
1010 uint64_t entry = 0, vaddr = 0;
1011 int i, j, count;
1012 char ch;
1013 int buf_len, data_start = 0;
1014 int entry_set = 0;
1015 int warning = 0;
1016 int warning_len = 0;
1017 int total_bytes_loaded = 0;
1018
1019 f = fopen(filename, "r");
1020 if (f == NULL) {
1021 perror(filename);
1022 exit(1);
1023 }
1024
1025 /* Load file contents: */
1026 while (!feof(f)) {
1027 memset(buf, 0, sizeof(buf));
1028 fgets((char *)buf, sizeof(buf)-1, f);
1029
1030 if (buf[0] == 0 || buf[0]=='\r' || buf[0]=='\n')
1031 continue;
1032
1033 if (buf[0] != 'S') {
1034 if (!warning)
1035 debug("WARNING! non-S-record found\n");
1036 warning = 1;
1037 continue;
1038 }
1039
1040 buf_len = strlen((char *)buf);
1041
1042 if (buf_len < 10) {
1043 if (!warning_len)
1044 debug("WARNING! invalid S-record found\n");
1045 warning_len = 1;
1046 continue;
1047 }
1048
1049 /*
1050 * Stype count address data checksum
1051 * 01 23 4.. .. (last 2 bytes)
1052 *
1053 * TODO: actually check the checksum
1054 */
1055
1056 j = 0;
1057 for (i=1; i<buf_len; i++) {
1058 if (buf[i]>='a' && buf[i]<='f')
1059 buf[i] += 10 - 'a';
1060 else if (buf[i] >= 'A' && buf[i] <= 'F')
1061 buf[i] += 10 - 'A';
1062 else if (buf[i] >= '0' && buf[i] <= '9')
1063 buf[i] -= '0';
1064 else if (buf[i] == '\r' || buf[i] == '\n') {
1065 } else
1066 fatal("invalid characters '%c' in S-record\n",
1067 buf[i]);
1068
1069 if (i >= 4) {
1070 if (i & 1)
1071 bytes[j++] += buf[i];
1072 else
1073 bytes[j] = buf[i] * 16;
1074 }
1075 }
1076
1077 count = buf[2] * 16 + buf[3];
1078 /* debug("count=%i j=%i\n", count, j); */
1079 /* count is j - 1. */
1080
1081 switch (buf[1]) {
1082 case 0:
1083 debug("SREC \"");
1084 for (i=2; i<count-1; i++) {
1085 ch = bytes[i];
1086 if (ch >= ' ' && ch < 127)
1087 debug("%c", ch);
1088 else
1089 debug("?");
1090 }
1091 debug("\"\n");
1092 break;
1093 case 1:
1094 case 2:
1095 case 3:
1096 /* switch again, to get the load address: */
1097 switch (buf[1]) {
1098 case 1: data_start = 2;
1099 vaddr = (bytes[0] << 8) + bytes[1];
1100 break;
1101 case 2: data_start = 3;
1102 vaddr = (bytes[0] << 16) + (bytes[1] << 8) +
1103 bytes[2];
1104 break;
1105 case 3: data_start = 4;
1106 vaddr = ((uint64_t)bytes[0] << 24) +
1107 (bytes[1] << 16) + (bytes[2]<<8) + bytes[3];
1108 }
1109 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
1110 &bytes[data_start], count - 1 - data_start,
1111 MEM_WRITE, NO_EXCEPTIONS);
1112 total_bytes_loaded += count - 1 - data_start;
1113 break;
1114 case 7:
1115 case 8:
1116 case 9:
1117 /* switch again, to get the entry point: */
1118 switch (buf[1]) {
1119 case 7: entry = ((uint64_t)bytes[0] << 24) +
1120 (bytes[1] << 16) + (bytes[2]<<8) + bytes[3];
1121 break;
1122 case 8: entry = (bytes[0] << 16) + (bytes[1] << 8) +
1123 bytes[2];
1124 break;
1125 case 9: entry = (bytes[0] << 8) + bytes[1];
1126 break;
1127 }
1128 entry_set = 1;
1129 debug("entry point 0x%08x\n", (unsigned int)entry);
1130 break;
1131 default:
1132 debug("unimplemented S-record type %i\n", buf[1]);
1133 }
1134 }
1135
1136 debug("0x%x bytes loaded\n", total_bytes_loaded);
1137
1138 fclose(f);
1139
1140 if (!entry_set)
1141 debug("WARNING! no entrypoint found!\n");
1142 else
1143 *entrypointp = entry;
1144
1145 n_executables_loaded ++;
1146 }
1147
1148
1149 /*
1150 * file_load_raw():
1151 *
1152 * Loads a raw binary into emulated memory. The filename should be
1153 * of the following form: loadaddress:filename
1154 * or loadaddress:skiplen:filename
1155 * or loadaddress:skiplen:pc:filename
1156 */
1157 static void file_load_raw(struct machine *m, struct memory *mem,
1158 char *filename, uint64_t *entrypointp)
1159 {
1160 FILE *f;
1161 int len;
1162 unsigned char buf[4096];
1163 uint64_t entry, loadaddr, vaddr, skip = 0;
1164 char *p, *p2;
1165
1166 p = strchr(filename, ':');
1167 if (p == NULL) {
1168 fprintf(stderr, "\n");
1169 perror(filename);
1170 exit(1);
1171 }
1172
1173 loadaddr = vaddr = entry = strtoull(filename, NULL, 0);
1174 p2 = p+1;
1175
1176 /* A second value? That's the optional skip value */
1177 p = strchr(p2, ':');
1178 if (p != NULL) {
1179 skip = strtoull(p2, NULL, 0);
1180 p = p+1;
1181 /* A third value? That's the initial pc: */
1182 if (strchr(p, ':') != NULL) {
1183 entry = strtoull(p, NULL, 0);
1184 p = strchr(p, ':') + 1;
1185 }
1186 } else
1187 p = p2;
1188
1189 f = fopen(strrchr(filename, ':')+1, "r");
1190 if (f == NULL) {
1191 perror(p);
1192 exit(1);
1193 }
1194
1195 fseek(f, skip, SEEK_SET);
1196
1197 /* Load file contents: */
1198 while (!feof(f)) {
1199 len = fread(buf, 1, sizeof(buf), f);
1200
1201 if (len > 0)
1202 m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr, &buf[0],
1203 len, MEM_WRITE, NO_EXCEPTIONS);
1204
1205 vaddr += len;
1206 }
1207
1208 debug("RAW: 0x%llx bytes @ 0x%08llx",
1209 (long long) (ftello(f) - skip), (long long)loadaddr);
1210 if (skip != 0)
1211 debug(" (0x%llx bytes of header skipped)", (long long)skip);
1212 debug("\n");
1213
1214 fclose(f);
1215
1216 *entrypointp = entry;
1217
1218 n_executables_loaded ++;
1219 }
1220
1221
1222 /*
1223 * file_load_elf():
1224 *
1225 * Loads an ELF image into the emulated memory. The entry point (read from
1226 * the ELF header) and the initial value of the gp register (read from the
1227 * ELF symbol table) are stored in the specified CPU's registers.
1228 *
1229 * This is pretty heavy stuff, but is needed because of the heaviness of
1230 * ELF files. :-/ Hopefully it will be able to recognize most valid ELFs.
1231 */
1232 static void file_load_elf(struct machine *m, struct memory *mem,
1233 char *filename, uint64_t *entrypointp, int arch, uint64_t *gpp,
1234 int *byte_order, uint64_t *tocp)
1235 {
1236 Elf32_Ehdr hdr32;
1237 Elf64_Ehdr hdr64;
1238 FILE *f;
1239 uint64_t eentry;
1240 int len, i, ok;
1241 int elf64, encoding, eflags;
1242 int etype, emachine;
1243 int ephnum, ephentsize, eshnum, eshentsize;
1244 off_t ephoff, eshoff;
1245 Elf32_Phdr phdr32;
1246 Elf64_Phdr phdr64;
1247 Elf32_Shdr shdr32;
1248 Elf64_Shdr shdr64;
1249 Elf32_Sym sym32;
1250 Elf64_Sym sym64;
1251 int ofs;
1252 int chunk_len = 1024, align_len;
1253 char *symbol_strings = NULL; size_t symbol_length = 0;
1254 char *s;
1255 Elf32_Sym *symbols_sym32 = NULL; int n_symbols = 0;
1256 Elf64_Sym *symbols_sym64 = NULL;
1257
1258 f = fopen(filename, "r");
1259 if (f == NULL) {
1260 perror(filename);
1261 exit(1);
1262 }
1263
1264 len = fread(&hdr32, 1, sizeof(Elf32_Ehdr), f);
1265 if (len < (signed int)sizeof(Elf32_Ehdr)) {
1266 fprintf(stderr, "%s: not an ELF file image\n", filename);
1267 exit(1);
1268 }
1269
1270 if (memcmp(&hdr32.e_ident[EI_MAG0], ELFMAG, SELFMAG) != 0) {
1271 fprintf(stderr, "%s: not an ELF file image\n", filename);
1272 exit(1);
1273 }
1274
1275 switch (hdr32.e_ident[EI_CLASS]) {
1276 case ELFCLASS32:
1277 elf64 = 0;
1278 break;
1279 case ELFCLASS64:
1280 elf64 = 1;
1281 fseek(f, 0, SEEK_SET);
1282 len = fread(&hdr64, 1, sizeof(Elf64_Ehdr), f);
1283 if (len < (signed int)sizeof(Elf64_Ehdr)) {
1284 fprintf(stderr, "%s: not an ELF64 file image\n",
1285 filename);
1286 exit(1);
1287 }
1288 break;
1289 default:
1290 fprintf(stderr, "%s: unknown ELF class '%i'\n",
1291 filename, hdr32.e_ident[EI_CLASS]);
1292 exit(1);
1293 }
1294
1295 encoding = hdr32.e_ident[EI_DATA];
1296 if (encoding != ELFDATA2LSB && encoding != ELFDATA2MSB) {
1297 fprintf(stderr, "%s: unknown data encoding '%i'\n",
1298 filename, hdr32.e_ident[EI_DATA]);
1299 exit(1);
1300 }
1301
1302 if (elf64) {
1303 unencode(etype, &hdr64.e_type, Elf64_Quarter);
1304 unencode(eflags, &hdr64.e_flags, Elf64_Half);
1305 unencode(emachine, &hdr64.e_machine, Elf64_Quarter);
1306 unencode(eentry, &hdr64.e_entry, Elf64_Addr);
1307 unencode(ephnum, &hdr64.e_phnum, Elf64_Quarter);
1308 unencode(ephentsize, &hdr64.e_phentsize, Elf64_Quarter);
1309 unencode(ephoff, &hdr64.e_phoff, Elf64_Off);
1310 unencode(eshnum, &hdr64.e_shnum, Elf64_Quarter);
1311 unencode(eshentsize, &hdr64.e_shentsize, Elf64_Quarter);
1312 unencode(eshoff, &hdr64.e_shoff, Elf64_Off);
1313 if (ephentsize != sizeof(Elf64_Phdr)) {
1314 fprintf(stderr, "%s: incorrect phentsize? %i, should "
1315 "be %i\nPerhaps this is a dynamically linked "
1316 "binary (which isn't supported yet).\n", filename,
1317 (int)ephentsize, (int)sizeof(Elf64_Phdr));
1318 exit(1);
1319 }
1320 if (eshentsize != sizeof(Elf64_Shdr)) {
1321 fprintf(stderr, "%s: incorrect shentsize? %i, should "
1322 "be %i\nPerhaps this is a dynamically linked "
1323 "binary (which isn't supported yet).\n", filename,
1324 (int)eshentsize, (int)sizeof(Elf64_Shdr));
1325 exit(1);
1326 }
1327 } else {
1328 unencode(etype, &hdr32.e_type, Elf32_Half);
1329 unencode(eflags, &hdr32.e_flags, Elf32_Word);
1330 unencode(emachine, &hdr32.e_machine, Elf32_Half);
1331 unencode(eentry, &hdr32.e_entry, Elf32_Addr);
1332 unencode(ephnum, &hdr32.e_phnum, Elf32_Half);
1333 unencode(ephentsize, &hdr32.e_phentsize, Elf32_Half);
1334 unencode(ephoff, &hdr32.e_phoff, Elf32_Off);
1335 unencode(eshnum, &hdr32.e_shnum, Elf32_Half);
1336 unencode(eshentsize, &hdr32.e_shentsize, Elf32_Half);
1337 unencode(eshoff, &hdr32.e_shoff, Elf32_Off);
1338 if (ephentsize != sizeof(Elf32_Phdr)) {
1339 fprintf(stderr, "%s: incorrect phentsize? %i, should "
1340 "be %i\nPerhaps this is a dynamically linked "
1341 "binary (which isn't supported yet).\n", filename,
1342 (int)ephentsize, (int)sizeof(Elf32_Phdr));
1343 exit(1);
1344 }
1345 if (eshentsize != sizeof(Elf32_Shdr)) {
1346 fprintf(stderr, "%s: incorrect shentsize? %i, should "
1347 "be %i\nPerhaps this is a dynamically linked "
1348 "binary (which isn't supported yet).\n", filename,
1349 (int)eshentsize, (int)sizeof(Elf32_Shdr));
1350 exit(1);
1351 }
1352 }
1353
1354 if ( etype != ET_EXEC ) {
1355 fprintf(stderr, "%s is not an ELF Executable file, type = %i\n",
1356 filename, etype);
1357 exit(1);
1358 }
1359
1360 ok = 0;
1361 switch (arch) {
1362 case ARCH_ALPHA:
1363 switch (emachine) {
1364 case EM_ALPHA:
1365 case -28634:
1366 ok = 1;
1367 }
1368 break;
1369 case ARCH_ARM:
1370 switch (emachine) {
1371 case EM_ARM:
1372 ok = 1;
1373 }
1374 break;
1375 case ARCH_AVR:
1376 switch (emachine) {
1377 case EM_AVR:
1378 ok = 1;
1379 }
1380 break;
1381 case ARCH_HPPA:
1382 switch (emachine) {
1383 case EM_PARISC:
1384 ok = 1;
1385 }
1386 break;
1387 case ARCH_I960:
1388 switch (emachine) {
1389 case EM_960:
1390 ok = 1;
1391 }
1392 break;
1393 case ARCH_IA64:
1394 switch (emachine) {
1395 case EM_IA_64:
1396 ok = 1;
1397 }
1398 break;
1399 case ARCH_M68K:
1400 switch (emachine) {
1401 case EM_68K:
1402 ok = 1;
1403 }
1404 break;
1405 case ARCH_MIPS:
1406 switch (emachine) {
1407 case EM_MIPS:
1408 case EM_MIPS_RS3_LE:
1409 ok = 1;
1410 }
1411 break;
1412 case ARCH_PPC:
1413 switch (emachine) {
1414 case EM_PPC:
1415 case EM_PPC64:
1416 ok = 1;
1417 }
1418 break;
1419 case ARCH_SH:
1420 switch (emachine) {
1421 case EM_SH:
1422 ok = 1;
1423 }
1424 break;
1425 case ARCH_SPARC:
1426 switch (emachine) {
1427 case EM_SPARC:
1428 case EM_SPARCV9:
1429 ok = 1;
1430 }
1431 break;
1432 case ARCH_X86:
1433 switch (emachine) {
1434 case EM_386:
1435 case EM_486:
1436 *tocp = 1;
1437 ok = 1;
1438 break;
1439 case EM_AMD64:
1440 *tocp = 2;
1441 ok = 1;
1442 break;
1443 }
1444 break;
1445 default:
1446 fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n");
1447 }
1448 if (!ok) {
1449 fprintf(stderr, "%s: this is a ", filename);
1450 if (emachine >= 0 && emachine < N_ELF_MACHINE_TYPES)
1451 fprintf(stderr, elf_machine_type[emachine]);
1452 else
1453 fprintf(stderr, "machine type '%i'", emachine);
1454 fprintf(stderr, " ELF binary!\n");
1455 exit(1);
1456 }
1457
1458 s = "entry point";
1459 if (elf64 && arch == ARCH_PPC)
1460 s = "function descriptor at";
1461
1462 debug("ELF%i %s, %s 0x", elf64? 64 : 32,
1463 encoding == ELFDATA2LSB? "LSB (LE)" : "MSB (BE)", s);
1464
1465 if (elf64)
1466 debug("%016llx\n", (long long)eentry);
1467 else
1468 debug("%08x\n", (int)eentry);
1469
1470 /*
1471 * MIPS16 encoding?
1472 *
1473 * TODO: Find out what e_flag actually contains.
1474 * TODO 2: This only sets mips16 for cpu 0. Yuck. Fix this!
1475 */
1476 if (arch == ARCH_MIPS && ((eflags >> 24) & 0xff) == 0x24) {
1477 debug("MIPS16 encoding (e_flags = 0x%08x)\n", eflags);
1478 #ifdef ENABLE_MIPS16
1479 m->cpus[0]->cd.mips.mips16 = 1;
1480 #else
1481 fatal("ENABLE_MIPS16 must be defined in misc.h.\n"
1482 "(or use the --mips16 configure option)\n");
1483 exit(1);
1484 #endif
1485 } else if (arch == ARCH_MIPS && (eentry & 0x3)) {
1486 debug("MIPS16 encoding (eentry not 32-bit aligned)\n");
1487 #ifdef ENABLE_MIPS16
1488 m->cpus[0]->cd.mips.mips16 = 1;
1489 #else
1490 fatal("ENABLE_MIPS16 must be defined in misc.h.\n"
1491 "(or use the --mips16 configure option)\n");
1492 exit(1);
1493 #endif
1494 }
1495
1496 /*
1497 * SH64: 32-bit instruction encoding? TODO
1498 */
1499 if (arch == ARCH_SH && (eentry & 1)) {
1500 debug("SH64: 32-bit instruction encoding\n");
1501 m->cpus[0]->cd.sh.compact = 0;
1502 m->cpus[0]->cd.sh.bits = 64;
1503 }
1504
1505 /* Read the program headers: */
1506
1507 for (i=0; i<ephnum; i++) {
1508 int p_type;
1509 uint64_t p_offset;
1510 uint64_t p_vaddr;
1511 uint64_t p_paddr;
1512 uint64_t p_filesz;
1513 uint64_t p_memsz;
1514 int p_flags;
1515 int p_align;
1516
1517 fseek(f, ephoff + i * ephentsize, SEEK_SET);
1518
1519 if (elf64) {
1520 fread(&phdr64, 1, sizeof(Elf64_Phdr), f);
1521 unencode(p_type, &phdr64.p_type, Elf64_Half);
1522 unencode(p_flags, &phdr64.p_flags, Elf64_Half);
1523 unencode(p_offset, &phdr64.p_offset, Elf64_Off);
1524 unencode(p_vaddr, &phdr64.p_vaddr, Elf64_Addr);
1525 unencode(p_paddr, &phdr64.p_paddr, Elf64_Addr);
1526 unencode(p_filesz, &phdr64.p_filesz, Elf64_Xword);
1527 unencode(p_memsz, &phdr64.p_memsz, Elf64_Xword);
1528 unencode(p_align, &phdr64.p_align, Elf64_Xword);
1529 } else {
1530 fread(&phdr32, 1, sizeof(Elf32_Phdr), f);
1531 unencode(p_type, &phdr32.p_type, Elf32_Word);
1532 unencode(p_offset, &phdr32.p_offset, Elf32_Off);
1533 unencode(p_vaddr, &phdr32.p_vaddr, Elf32_Addr);
1534 unencode(p_paddr, &phdr32.p_paddr, Elf32_Addr);
1535 unencode(p_filesz, &phdr32.p_filesz, Elf32_Word);
1536 unencode(p_memsz, &phdr32.p_memsz, Elf32_Word);
1537 unencode(p_flags, &phdr32.p_flags, Elf32_Word);
1538 unencode(p_align, &phdr32.p_align, Elf32_Word);
1539 }
1540
1541 /*
1542 * Hack for loading Linux/PPC kernels, linked to high
1543 * addresses, at low addresses.
1544 */
1545 if (arch == ARCH_PPC) {
1546 if (elf64) {
1547 p_vaddr &= 0x0fffffffffffffffULL;
1548 p_paddr &= 0x0fffffffffffffffULL;
1549 } else {
1550 p_vaddr &= 0x0fffffff;
1551 p_paddr &= 0x0fffffff;
1552 }
1553 }
1554
1555 if (p_memsz != 0 && (p_type == PT_LOAD ||
1556 (p_type & PF_MASKPROC) == PT_MIPS_REGINFO)) {
1557 debug("chunk %i (", i);
1558 if (p_type == PT_LOAD)
1559 debug("load");
1560 else
1561 debug("0x%08x", (int)p_type);
1562
1563 debug(") @ 0x%llx, vaddr 0x", (long long)p_offset);
1564
1565 if (elf64)
1566 debug("%016llx", (long long)p_vaddr);
1567 else
1568 debug("%08x", (int)p_vaddr);
1569
1570 debug(" len=0x%llx\n", (long long)p_memsz);
1571
1572 if (p_vaddr != p_paddr) {
1573 if (elf64)
1574 fatal("NOTE: vaddr (0x%llx) and "
1575 "paddr (0x%llx) differ; using "
1576 "vaddr\n", (long long)p_vaddr,
1577 (long long)p_paddr);
1578 else
1579 fatal("NOTE: vaddr (0x%08x) and "
1580 "paddr (0x%08x) differ; using vaddr"
1581 "\n", (int)p_vaddr, (int)p_paddr);
1582 }
1583
1584 if (p_memsz < p_filesz) {
1585 fprintf(stderr, "%s: memsz < filesz. TODO: how"
1586 " to handle this? memsz=%016llx filesz="
1587 "%016llx\n", filename, (long long)p_memsz,
1588 (long long)p_filesz);
1589 exit(1);
1590 }
1591
1592 fseek(f, p_offset, SEEK_SET);
1593 align_len = 1;
1594 if ((p_vaddr & 0xf)==0) align_len = 0x10;
1595 if ((p_vaddr & 0x3f)==0) align_len = 0x40;
1596 if ((p_vaddr & 0xff)==0) align_len = 0x100;
1597 if ((p_vaddr & 0xfff)==0) align_len = 0x1000;
1598 if ((p_vaddr & 0x3fff)==0) align_len = 0x4000;
1599 if ((p_vaddr & 0xffff)==0) align_len = 0x10000;
1600 ofs = 0; len = chunk_len = align_len;
1601 while (ofs < (int64_t)p_filesz && len==chunk_len) {
1602 unsigned char *ch = malloc(chunk_len);
1603 int i = 0;
1604
1605 /* Switch to larger size, if possible: */
1606 if (align_len < 0x10000 &&
1607 ((p_vaddr + ofs) & 0xffff)==0) {
1608 align_len = 0x10000;
1609 len = chunk_len = align_len;
1610 free(ch);
1611 ch = malloc(chunk_len);
1612 } else if (align_len < 0x1000 &&
1613 ((p_vaddr + ofs) & 0xfff)==0) {
1614 align_len = 0x1000;
1615 len = chunk_len = align_len;
1616 free(ch);
1617 ch = malloc(chunk_len);
1618 }
1619
1620 if (ch == NULL) {
1621 fprintf(stderr, "out of memory\n");
1622 exit(1);
1623 }
1624
1625 len = fread(&ch[0], 1, chunk_len, f);
1626 if (ofs + len > (int64_t)p_filesz)
1627 len = p_filesz - ofs;
1628
1629 while (i < len) {
1630 size_t len_to_copy;
1631 len_to_copy = (i + align_len) <= len?
1632 align_len : len - i;
1633 m->cpus[0]->memory_rw(m->cpus[0], mem,
1634 p_vaddr + ofs, &ch[i], len_to_copy,
1635 MEM_WRITE, NO_EXCEPTIONS);
1636 ofs += align_len;
1637 i += align_len;
1638 }
1639
1640 free(ch);
1641 }
1642 }
1643 }
1644
1645 /*
1646 * Read the section headers to find the address of the _gp
1647 * symbol (for MIPS):
1648 */
1649
1650 for (i=0; i<eshnum; i++) {
1651 int sh_name, sh_type, sh_flags, sh_link, sh_info, sh_entsize;
1652 uint64_t sh_addr, sh_size, sh_addralign;
1653 off_t sh_offset;
1654 int n_entries; /* for reading the symbol / string tables */
1655
1656 /* debug("section header %i at %016llx\n", i,
1657 (long long) eshoff+i*eshentsize); */
1658
1659 fseek(f, eshoff + i * eshentsize, SEEK_SET);
1660
1661 if (elf64) {
1662 len = fread(&shdr64, 1, sizeof(Elf64_Shdr), f);
1663 if (len != sizeof(Elf64_Shdr)) {
1664 fprintf(stderr, "couldn't read header\n");
1665 exit(1);
1666 }
1667 unencode(sh_name, &shdr64.sh_name, Elf64_Half);
1668 unencode(sh_type, &shdr64.sh_type, Elf64_Half);
1669 unencode(sh_flags, &shdr64.sh_flags, Elf64_Xword);
1670 unencode(sh_addr, &shdr64.sh_addr, Elf64_Addr);
1671 unencode(sh_offset, &shdr64.sh_offset, Elf64_Off);
1672 unencode(sh_size, &shdr64.sh_size, Elf64_Xword);
1673 unencode(sh_link, &shdr64.sh_link, Elf64_Half);
1674 unencode(sh_info, &shdr64.sh_info, Elf64_Half);
1675 unencode(sh_addralign, &shdr64.sh_addralign,
1676 Elf64_Xword);
1677 unencode(sh_entsize, &shdr64.sh_entsize, Elf64_Xword);
1678 } else {
1679 len = fread(&shdr32, 1, sizeof(Elf32_Shdr), f);
1680 if (len != sizeof(Elf32_Shdr)) {
1681 fprintf(stderr, "couldn't read header\n");
1682 exit(1);
1683 }
1684 unencode(sh_name, &shdr32.sh_name, Elf32_Word);
1685 unencode(sh_type, &shdr32.sh_type, Elf32_Word);
1686 unencode(sh_flags, &shdr32.sh_flags, Elf32_Word);
1687 unencode(sh_addr, &shdr32.sh_addr, Elf32_Addr);
1688 unencode(sh_offset, &shdr32.sh_offset, Elf32_Off);
1689 unencode(sh_size, &shdr32.sh_size, Elf32_Word);
1690 unencode(sh_link, &shdr32.sh_link, Elf32_Word);
1691 unencode(sh_info, &shdr32.sh_info, Elf32_Word);
1692 unencode(sh_addralign, &shdr32.sh_addralign,Elf32_Word);
1693 unencode(sh_entsize, &shdr32.sh_entsize, Elf32_Word);
1694 }
1695
1696 /* debug("sh_name=%04lx, sh_type=%08lx, sh_flags=%08lx"
1697 " sh_size=%06lx sh_entsize=%03lx\n",
1698 (long)sh_name, (long)sh_type, (long)sh_flags,
1699 (long)sh_size, (long)sh_entsize); */
1700
1701 /* Perhaps it is bad to reuse sh_entsize like this? TODO */
1702 if (elf64)
1703 sh_entsize = sizeof(Elf64_Sym);
1704 else
1705 sh_entsize = sizeof(Elf32_Sym);
1706
1707 if (sh_type == SHT_SYMTAB) {
1708 size_t len;
1709 n_entries = sh_size / sh_entsize;
1710
1711 fseek(f, sh_offset, SEEK_SET);
1712
1713 if (elf64) {
1714 if (symbols_sym64 != NULL)
1715 free(symbols_sym64);
1716 symbols_sym64 = malloc(sh_size);
1717 if (symbols_sym64 == NULL) {
1718 fprintf(stderr, "out of memory\n");
1719 exit(1);
1720 }
1721
1722 len = fread(symbols_sym64, 1, sh_entsize *
1723 n_entries, f);
1724 } else {
1725 if (symbols_sym32 != NULL)
1726 free(symbols_sym32);
1727 symbols_sym32 = malloc(sh_size);
1728 if (symbols_sym32 == NULL) {
1729 fprintf(stderr, "out of memory\n");
1730 exit(1);
1731 }
1732
1733 len = fread(symbols_sym32, 1,
1734 sh_entsize * n_entries, f);
1735 }
1736
1737 if (len != sh_size) {
1738 fprintf(stderr, "could not read symbols from "
1739 "%s\n", filename);
1740 exit(1);
1741 }
1742
1743 debug("%i symbol entries at 0x%llx\n",
1744 (int)n_entries, (long long)sh_offset);
1745
1746 n_symbols = n_entries;
1747 }
1748
1749 /*
1750 * TODO: This is incorrect, there may be several strtab
1751 * sections.
1752 *
1753 * For now, the simple/stupid guess that the largest string
1754 * table is the one to use seems to be good enough.
1755 */
1756
1757 if (sh_type == SHT_STRTAB && sh_size > symbol_length) {
1758 size_t len;
1759
1760 if (symbol_strings != NULL)
1761 free(symbol_strings);
1762
1763 symbol_strings = malloc(sh_size + 1);
1764 if (symbol_strings == NULL) {
1765 fprintf(stderr, "out of memory\n");
1766 exit(1);
1767 }
1768
1769 fseek(f, sh_offset, SEEK_SET);
1770 len = fread(symbol_strings, 1, sh_size, f);
1771 if (len != sh_size) {
1772 fprintf(stderr, "could not read symbols from "
1773 "%s\n", filename);
1774 exit(1);
1775 }
1776
1777 debug("%i bytes of symbol strings at 0x%llx\n",
1778 (int)sh_size, (long long)sh_offset);
1779
1780 symbol_strings[sh_size] = '\0';
1781 symbol_length = sh_size;
1782 }
1783 }
1784
1785 fclose(f);
1786
1787 /* Decode symbols: */
1788 if (symbol_strings != NULL) {
1789 for (i=0; i<n_symbols; i++) {
1790 uint64_t st_name, addr, size;
1791 int st_info;
1792
1793 if (elf64) {
1794 sym64 = symbols_sym64[i];
1795 unencode(st_name, &sym64.st_name, Elf64_Half);
1796 unencode(st_info, &sym64.st_info, Elf_Byte);
1797 unencode(addr, &sym64.st_value, Elf64_Addr);
1798 unencode(size, &sym64.st_size, Elf64_Xword);
1799 } else {
1800 sym32 = symbols_sym32[i];
1801 unencode(st_name, &sym32.st_name, Elf32_Word);
1802 unencode(st_info, &sym32.st_info, Elf_Byte);
1803 unencode(addr, &sym32.st_value, Elf32_Word);
1804 unencode(size, &sym32.st_size, Elf32_Word);
1805 }
1806
1807 /* debug("symbol info=0x%02x addr=0x%016llx"
1808 " (%i) '%s'\n", st_info, (long long)addr,
1809 st_name, symbol_strings + st_name); */
1810
1811 if (size == 0)
1812 size ++;
1813
1814 if (addr != 0) /* && ((st_info >> 4) & 0xf)
1815 >= STB_GLOBAL) */ {
1816 /* debug("symbol info=0x%02x addr=0x%016llx"
1817 " '%s'\n", st_info, (long long)addr,
1818 symbol_strings + st_name); */
1819 add_symbol_name(&m->symbol_context,
1820 addr, size, symbol_strings + st_name,
1821 0, -1);
1822 }
1823
1824 if (strcmp(symbol_strings + st_name, "_gp") == 0) {
1825 debug("found _gp address: 0x");
1826 if (elf64)
1827 debug("%016llx\n", (long long)addr);
1828 else
1829 debug("%08x\n", (int)addr);
1830 *gpp = addr;
1831 }
1832 }
1833 }
1834
1835 *entrypointp = eentry;
1836
1837 if (encoding == ELFDATA2LSB)
1838 *byte_order = EMUL_LITTLE_ENDIAN;
1839 else
1840 *byte_order = EMUL_BIG_ENDIAN;
1841
1842 if (elf64 && arch == ARCH_PPC) {
1843 /*
1844 * Special case for 64-bit PPC ELFs:
1845 *
1846 * The ELF starting symbol points to a ".opd" section
1847 * which contains a function descriptor:
1848 *
1849 * uint64_t start;
1850 * uint64_t toc_base;
1851 * uint64_t something_else; (?)
1852 */
1853 int res;
1854 unsigned char b[sizeof(uint64_t)];
1855 uint64_t toc_base;
1856
1857 debug("PPC64: ");
1858
1859 res = m->cpus[0]->memory_rw(m->cpus[0], mem, eentry, b,
1860 sizeof(b), MEM_READ, NO_EXCEPTIONS);
1861 if (!res)
1862 debug(" [WARNING: could not read memory?] ");
1863
1864 /* PPC are always big-endian: */
1865 *entrypointp = ((uint64_t)b[0] << 56) +
1866 ((uint64_t)b[1] << 48) + ((uint64_t)b[2] << 40) +
1867 ((uint64_t)b[3] << 32) + ((uint64_t)b[4] << 24) +
1868 ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
1869 (uint64_t)b[7];
1870
1871 res = m->cpus[0]->memory_rw(m->cpus[0], mem, eentry + 8,
1872 b, sizeof(b), MEM_READ, NO_EXCEPTIONS);
1873 if (!res)
1874 fatal(" [WARNING: could not read memory?] ");
1875
1876 toc_base = ((uint64_t)b[0] << 56) +
1877 ((uint64_t)b[1] << 48) + ((uint64_t)b[2] << 40) +
1878 ((uint64_t)b[3] << 32) + ((uint64_t)b[4] << 24) +
1879 ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
1880 (uint64_t)b[7];
1881
1882 debug("entrypoint 0x%016llx, toc_base 0x%016llx\n",
1883 (long long)*entrypointp, (long long)toc_base);
1884 if (tocp != NULL)
1885 *tocp = toc_base;
1886 }
1887
1888 n_executables_loaded ++;
1889 }
1890
1891
1892 /*
1893 * file_n_executables_loaded():
1894 *
1895 * Returns the number of executable files loaded into emulated memory.
1896 */
1897 int file_n_executables_loaded(void)
1898 {
1899 return n_executables_loaded;
1900 }
1901
1902
1903 /*
1904 * file_load():
1905 *
1906 * Sense the file format of a file (ELF, a.out, ecoff), and call the
1907 * right file_load_XXX() function. If the file isn't of a recognized
1908 * binary format, assume that it contains symbol definitions.
1909 *
1910 * If the filename doesn't exist, try to treat the name as
1911 * "address:filename" and load the file as a raw binary.
1912 */
1913 void file_load(struct machine *machine, struct memory *mem,
1914 char *filename, uint64_t *entrypointp,
1915 int arch, uint64_t *gpp, int *byte_orderp, uint64_t *tocp)
1916 {
1917 int iadd = DEBUG_INDENTATION, old_quiet_mode;
1918 FILE *f;
1919 unsigned char buf[12];
1920 unsigned char buf2[2];
1921 size_t len, len2, i;
1922 off_t size;
1923
1924 if (byte_orderp == NULL) {
1925 fprintf(stderr, "file_load(): byte_order == NULL\n");
1926 exit(1);
1927 }
1928
1929 if (arch == ARCH_NOARCH) {
1930 fprintf(stderr, "file_load(): FATAL ERROR: no arch?\n");
1931 exit(1);
1932 }
1933
1934 if (mem == NULL || filename == NULL) {
1935 fprintf(stderr, "file_load(): mem or filename is NULL\n");
1936 exit(1);
1937 }
1938
1939 /* Skip configuration files: */
1940 if (filename[0] == '@')
1941 return;
1942
1943 debug("loading %s%s\n", filename, verbose >= 2? ":" : "");
1944 debug_indentation(iadd);
1945
1946 old_quiet_mode = quiet_mode;
1947 if (verbose < 2)
1948 quiet_mode = 1;
1949
1950 f = fopen(filename, "r");
1951 if (f == NULL) {
1952 file_load_raw(machine, mem, filename, entrypointp);
1953 goto ret;
1954 }
1955
1956 fseek(f, 0, SEEK_END);
1957 size = ftello(f);
1958 fseek(f, 0, SEEK_SET);
1959
1960 memset(buf, 0, sizeof(buf));
1961 len = fread(buf, 1, sizeof(buf), f);
1962 fseek(f, 510, SEEK_SET);
1963 len2 = fread(buf2, 1, sizeof(buf2), f);
1964 fclose(f);
1965
1966 if (len < (signed int)sizeof(buf)) {
1967 fprintf(stderr, "\nThis file is too small to contain "
1968 "anything useful\n");
1969 exit(1);
1970 }
1971
1972 /* Is it an ELF? */
1973 if (buf[0] == 0x7f && buf[1]=='E' && buf[2]=='L' && buf[3]=='F') {
1974 file_load_elf(machine, mem, filename,
1975 entrypointp, arch, gpp, byte_orderp, tocp);
1976 goto ret;
1977 }
1978
1979 /* Is it an a.out? */
1980 if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) {
1981 /* MIPS a.out */
1982 file_load_aout(machine, mem, filename, 0,
1983 entrypointp, arch, byte_orderp);
1984 goto ret;
1985 }
1986 if (buf[0]==0x00 && buf[1]==0x87 && buf[2]==0x01 && buf[3]==0x08) {
1987 /* M68K a.out */
1988 file_load_aout(machine, mem, filename,
1989 AOUT_FLAG_VADDR_ZERO_HACK /* for OpenBSD/mac68k */,
1990 entrypointp, arch, byte_orderp);
1991 goto ret;
1992 }
1993 if (buf[0]==0x00 && buf[1]==0x8f && buf[2]==0x01 && buf[3]==0x0b) {
1994 /* ARM a.out */
1995 file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING,
1996 entrypointp, arch, byte_orderp);
1997 goto ret;
1998 }
1999 if (buf[0]==0x00 && buf[1]==0x86 && buf[2]==0x01 && buf[3]==0x0b) {
2000 /* i386 a.out (old OpenBSD and NetBSD etc) */
2001 file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING,
2002 entrypointp, arch, byte_orderp);
2003 goto ret;
2004 }
2005 if (buf[0]==0x01 && buf[1]==0x03 && buf[2]==0x01 && buf[3]==0x07) {
2006 /* SPARC a.out (old 32-bit NetBSD etc) */
2007 file_load_aout(machine, mem, filename, AOUT_FLAG_NO_SIZES,
2008 entrypointp, arch, byte_orderp);
2009 goto ret;
2010 }
2011 if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) {
2012 /* DEC OSF1 on MIPS: */
2013 file_load_aout(machine, mem, filename, AOUT_FLAG_DECOSF1,
2014 entrypointp, arch, byte_orderp);
2015 goto ret;
2016 }
2017
2018 /*
2019 * Is it a Mach-O file?
2020 */
2021 if (buf[0] == 0xfe && buf[1] == 0xed && buf[2] == 0xfa &&
2022 (buf[3] == 0xce || buf[3] == 0xcf)) {
2023 file_load_macho(machine, mem, filename, entrypointp,
2024 arch, byte_orderp, buf[3] == 0xcf, 0);
2025 goto ret;
2026 }
2027 if ((buf[0] == 0xce || buf[0] == 0xcf) && buf[1] == 0xfa &&
2028 buf[2] == 0xed && buf[3] == 0xfe) {
2029 file_load_macho(machine, mem, filename, entrypointp,
2030 arch, byte_orderp, buf[0] == 0xcf, 1);
2031 goto ret;
2032 }
2033
2034 /*
2035 * Is it an ecoff?
2036 *
2037 * TODO: What's the deal with the magic value's byte order? Sometimes
2038 * it seems to be reversed for BE when compared to LE, but not always?
2039 */
2040 if (buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB ||
2041 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL ||
2042 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB2 ||
2043 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL2 ||
2044 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEB3 ||
2045 buf[0]+256*buf[1] == ECOFF_MAGIC_MIPSEL3 ||
2046 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB ||
2047 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL ||
2048 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB2 ||
2049 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL2 ||
2050 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEB3 ||
2051 buf[1]+256*buf[0] == ECOFF_MAGIC_MIPSEL3) {
2052 file_load_ecoff(machine, mem, filename, entrypointp,
2053 arch, gpp, byte_orderp);
2054 goto ret;
2055 }
2056
2057 /* Is it a Motorola SREC file? */
2058 if ((buf[0]=='S' && buf[1]>='0' && buf[1]<='9')) {
2059 file_load_srec(machine, mem, filename, entrypointp);
2060 goto ret;
2061 }
2062
2063 /* gzipped files are not supported: */
2064 if (buf[0]==0x1f && buf[1]==0x8b) {
2065 fprintf(stderr, "\nYou need to gunzip the file before you"
2066 " try to use it.\n");
2067 exit(1);
2068 }
2069
2070 if (size > 24000000) {
2071 fprintf(stderr, "\nThis file is very large (%lli bytes)\n",
2072 (long long)size);
2073 fprintf(stderr, "Are you sure it is a kernel and not a disk "
2074 "image? (Use the -d option.)\n");
2075 exit(1);
2076 }
2077
2078 if (size == 1474560)
2079 fprintf(stderr, "Hm... this file is the size of a 1.44 MB "
2080 "floppy image. Maybe you forgot the\n-d switch?\n");
2081
2082 /*
2083 * Last resort: symbol definitions from nm (or nm -S):
2084 *
2085 * If the buf contains typical 'binary' characters, then print
2086 * an error message and quit instead of assuming that it is a
2087 * symbol file.
2088 */
2089 for (i=0; i<(signed)sizeof(buf); i++)
2090 if (buf[i] < 32 && buf[i] != '\t' &&
2091 buf[i] != '\n' && buf[i] != '\r' &&
2092 buf[i] != '\f') {
2093 fprintf(stderr, "\nThe file format of '%s' is "
2094 "unknown.\n\n ", filename);
2095 for (i=0; i<(signed)sizeof(buf); i++)
2096 fprintf(stderr, " %02x", buf[i]);
2097
2098 if (len2 == 2 && buf2[0] == 0x55 && buf2[1] == 0xaa)
2099 fprintf(stderr, "\n\nIt has a PC-style "
2100 "bootsector marker.");
2101
2102 fprintf(stderr, "\n\nPossible explanations:\n\n"
2103 " o) If this is a disk image, you forgot '-d' "
2104 "on the command line.\n"
2105 " o) This is an unsupported binary format.\n\n");
2106 exit(1);
2107 }
2108
2109 symbol_readfile(&machine->symbol_context, filename);
2110
2111 ret:
2112 debug_indentation(-iadd);
2113 quiet_mode = old_quiet_mode;
2114 }
2115

  ViewVC Help
Powered by ViewVC 1.1.26