/[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 32 - (show annotations)
Mon Oct 8 16:20:58 2007 UTC (16 years, 5 months ago) by dpavlin
File MIME type: text/plain
File size: 58111 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.1421 2006/11/06 05:32:37 debug Exp $
20060816	Adding a framework for emulated/virtual timers (src/timer.c),
		using only setitimer().
		Rewriting the mc146818 to use the new timer framework.
20060817	Adding a call to gettimeofday() every now and then (once every
		second, at the moment) to resynch the timer if it drifts.
		Beginning to convert the ISA timer interrupt mechanism (8253
		and 8259) to use the new timer framework.
		Removing the -I command line option.
20060819	Adding the -I command line option again, with new semantics.
		Working on Footbridge timer interrupts; NetBSD/NetWinder and
		NetBSD/CATS now run at correct speed, but unfortunately with
		HUGE delays during bootup.
20060821	Some minor m68k updates. Adding the first instruction: nop. :)
		Minor Alpha emulation updates.
20060822	Adding a FreeBSD development specific YAMON environment
		variable ("khz") (as suggested by Bruce M. Simpson).
		Moving YAMON environment variable initialization from
		machine_evbmips.c into promemul/yamon.c, and adding some more
		variables.
		Continuing on the LCA PCI bus controller (for Alpha machines).
20060823	Continuing on the timer stuff: experimenting with MIPS count/
		compare interrupts connected to the timer framework.
20060825	Adding bogus SCSI commands 0x51 (SCSICDROM_READ_DISCINFO) and
		0x52 (SCSICDROM_READ_TRACKINFO) to the SCSI emulation layer,
		to allow NetBSD/pmax 4.0_BETA to be installed from CDROM.
		Minor updates to the LCA PCI controller.
20060827	Implementing a CHIP8 cpu mode, and a corresponding CHIP8
		machine, for fun. Disassembly support for all instructions,
		and most of the common instructions have been implemented: mvi,
		mov_imm, add_imm, jmp, rand, cls, sprite, skeq_imm, jsr,
		skne_imm, bcd, rts, ldr, str, mov, or, and, xor, add, sub,
		font, ssound, sdelay, gdelay, bogus skup/skpr, skeq, skne.
20060828	Beginning to convert the CHIP8 cpu in the CHIP8 machine to a
		(more correct) RCA 180x cpu. (Disassembly for all 1802
		instructions has been implemented, but no execution yet, and
		no 1805 extended instructions.)
20060829	Minor Alpha emulation updates.
20060830	Beginning to experiment a little with PCI IDE for SGI O2.
		Fixing the cursor key mappings for MobilePro 770 emulation.
		Fixing the LK201 warning caused by recent NetBSD/pmax.
		The MIPS R41xx standby, suspend, and hibernate instructions now
		behave like the RM52xx/MIPS32/MIPS64 wait instruction.
		Fixing dev_wdc so it calculates correct (64-bit) offsets before
		giving them to diskimage_access().
20060831	Continuing on Alpha emulation (OSF1 PALcode).
20060901	Minor Alpha updates; beginning on virtual memory pagetables.
		Removed the limit for max nr of devices (in preparation for
		allowing devices' base addresses to be changed during runtime).
		Adding a hack for MIPS [d]mfc0 select 0 (except the count
		register), so that the coproc register is simply copied.
		The MIPS suspend instruction now exits the emulator, instead
		of being treated as a wait instruction (this causes NetBSD/
		hpcmips to get correct 'halt' behavior).
		The VR41xx RTC now returns correct time.
		Connecting the VR41xx timer to the timer framework (fixed at
		128 Hz, for now).
		Continuing on SPARC emulation, adding more instructions:
		restore, ba_xcc, ble. The rectangle drawing demo works :)
		Removing the last traces of the old ENABLE_CACHE_EMULATION
		MIPS stuff (not usable with dyntrans anyway).
20060902	Splitting up src/net.c into several smaller files in its own
		subdirectory (src/net/).
20060903	Cleanup of the files in src/net/, to make them less ugly.
20060904	Continuing on the 'settings' subsystem.
		Minor progress on the SPARC emulation mode.
20060905	Cleanup of various things, and connecting the settings
		infrastructure to various subsystems (emul, machine, cpu, etc).
		Changing the lk201 mouse update routine to not rely on any
		emulated hardware framebuffer cursor coordinates, but instead
		always do (semi-usable) relative movements.
20060906	Continuing on the lk201 mouse stuff. Mouse behaviour with
		multiple framebuffers (which was working in Ultrix) is now
		semi-broken (but it still works, in a way).
		Moving the documentation about networking into its own file
		(networking.html), and refreshing it a bit. Adding an example
		of how to use ethernet frame direct-access (udp_snoop).
20060907	Continuing on the settings infrastructure.
20060908	Minor updates to SH emulation: for 32-bit emulation: delay
		slots and the 'jsr @Rn' instruction. I'm putting 64-bit SH5 on
		ice, for now.
20060909-10	Implementing some more 32-bit SH instructions. Removing the
		64-bit mode completely. Enough has now been implemented to run
		the rectangle drawing demo. :-)
20060912	Adding more SH instructions.
20060916	Continuing on SH emulation (some more instructions: div0u,
		div1, rotcl/rotcr, more mov instructions, dt, braf, sets, sett,
		tst_imm, dmuls.l, subc, ldc_rm_vbr, movt, clrt, clrs, clrmac).
		Continuing on the settings subsystem (beginning on reading/
		writing settings, removing bugs, and connecting more cpus to
		the framework).
20060919	More work on SH emulation; adding an ldc banked instruction,
		and attaching a 640x480 framebuffer to the Dreamcast machine
		mode (NetBSD/dreamcast prints the NetBSD copyright banner :-),
		and then panics).
20060920	Continuing on the settings subsystem.
20060921	Fixing the Footbridge timer stuff so that NetBSD/cats and
		NetBSD/netwinder boot up without the delays.
20060922	Temporarily hardcoding MIPS timer interrupt to 100 Hz. With
		'wait' support disabled, NetBSD/malta and Linux/malta run at
		correct speed.
20060923	Connecting dev_gt to the timer framework, so that NetBSD/cobalt
		runs at correct speed.
		Moving SH4-specific memory mapped registers into its own
		device (dev_sh4.c).
		Running with -N now prints "idling" instead of bogus nr of
		instrs/second (which isn't valid anyway) while idling.
20060924	Algor emulation should now run at correct speed.
		Adding disassembly support for some MIPS64 revision 2
		instructions: ext, dext, dextm, dextu.
20060926	The timer framework now works also when the MIPS wait
		instruction is used.
20060928	Re-implementing checks for coprocessor availability for MIPS
		cop0 instructions. (Thanks to Carl van Schaik for noticing the
		lack of cop0 availability checks.)
20060929	Implementing an instruction combination hack which treats
		NetBSD/pmax' idle loop as a wait-like instruction.
20060930	The ENTRYHI_R_MASK was missing in (at least) memory_mips_v2p.c,
		causing TLB lookups to sometimes succeed when they should have
		failed. (A big thank you to Juli Mallett for noticing the
		problem.)
		Adding disassembly support for more MIPS64 revision 2 opcodes
		(seb, seh, wsbh, jalr.hb, jr.hb, synci, ins, dins, dinsu,
		dinsm, dsbh, dshd, ror, dror, rorv, drorv, dror32). Also
		implementing seb, seh, dsbh, dshd, and wsbh.
		Implementing an instruction combination hack for Linux/pmax'
		idle loop, similar to the NetBSD/pmax case.
20061001	Changing the NetBSD/sgimips install instructions to extract
		files from an iso image, instead of downloading them via ftp.
20061002	More-than-31-bit userland addresses in memory_mips_v2p.c were
		not actually working; applying a fix from Carl van Schaik to
		enable them to work + making some other updates (adding kuseg
		support).
		Fixing hpcmips (vr41xx) timer initialization.
		Experimenting with O(n)->O(1) reduction in the MIPS TLB lookup
		loop. Seems to work both for R3000 and non-R3000.
20061003	Continuing a little on SH emulation (adding more control
		registers; mini-cleanup of memory_sh.c).
20061004	Beginning on a dev_rtc, a clock/timer device for the test
		machines; also adding a demo, and some documentation.
		Fixing a bug in SH "mov.w @(disp,pc),Rn" (the result wasn't
		sign-extended), and adding the addc and ldtlb instructions.
20061005	Contining on SH emulation: virtual to physical address
		translation, and a skeleton exception mechanism.
20061006	Adding more SH instructions (various loads and stores, rte,
		negc, muls.w, various privileged register-move instructions).
20061007	More SH instructions: various move instructions, trapa, div0s,
		float, fdiv, ftrc.
		Continuing on dev_rtc; removing the rtc demo.
20061008	Adding a dummy Dreamcast PROM module. (Homebrew Dreamcast
		programs using KOS libs need this.)
		Adding more SH instructions: "stc vbr,rn", rotl, rotr, fsca,
		fmul, fadd, various floating-point moves, etc. A 256-byte
		demo for Dreamcast runs :-)
20061012	Adding the SH "lds Rm,pr" and bsr instructions.
20061013	More SH instructions: "sts fpscr,rn", tas.b, and some more
		floating point instructions, cmp/str, and more moves.
		Adding a dummy dev_pvr (Dreamcast graphics controller).
20061014	Generalizing the expression evaluator (used in the built-in
		debugger) to support parentheses and +-*/%^&|.
20061015	Removing the experimental tlb index hint code in
		mips_memory_v2p.c, since it didn't really have any effect.
20061017	Minor SH updates; adding the "sts pr,Rn", fcmp/gt, fneg,
		frchg, and some other instructions. Fixing missing sign-
		extension in an 8-bit load instruction.
20061019	Adding a simple dev_dreamcast_rtc.
		Implementing memory-mapped access to the SH ITLB/UTLB arrays.
20061021	Continuing on various SH and Dreamcast things: sh4 timers,
		debug messages for dev_pvr, fixing some virtual address
		translation bugs, adding the bsrf instruction.
		The NetBSD/dreamcast GENERIC_MD kernel now reaches userland :)
		Adding a dummy dev_dreamcast_asic.c (not really useful yet).
		Implementing simple support for Store Queues.
		Beginning on the PVR Tile Accelerator.
20061022	Generalizing the PVR framebuffer to support off-screen drawing,
		multiple bit-depths, etc. (A small speed penalty, but most
		likely worth it.)
		Adding more SH instructions (mulu.w, fcmp/eq, fsub, fmac,
		fschg, and some more); correcting bugs in "fsca" and "float".
20061024	Adding the SH ftrv (matrix * vector) instruction. Marcus
		Comstedt's "tatest" example runs :) (wireframe only).
		Correcting disassembly for SH floating point instructions that
		use the xd* registers.
		Adding the SH fsts instruction.
		In memory_device_dyntrans_access(), only the currently used
		range is now invalidated, and not the entire device range.
20061025	Adding a dummy AVR32 cpu mode skeleton.
20061026	Various Dreamcast updates; beginning on a Maple bus controller.
20061027	Continuing on the Maple bus. A bogus Controller, Keyboard, and
		Mouse can now be detected by NetBSD and KOS homebrew programs.
		Cleaning up the SH4 Timer Management Unit, and beginning on
		SH4 interrupts.
		Implementing the Dreamcast SYSASIC.
20061028	Continuing on the SYSASIC.
		Adding the SH fsqrt instruction.
		memory_sh.c now actually scans the ITLB.
		Fixing a bug in dev_sh4.c, related to associative writes into
		the memory-mapped UTLB array. NetBSD/dreamcast now reaches
		userland stably, and prints the "Terminal type?" message :-]
		Implementing enough of the Dreamcast keyboard to make NetBSD
		accept it for input.
		Enabling SuperH for stable (non-development) builds.
		Adding NetBSD/dreamcast to the documentation, although it
		doesn't support root-on-nfs yet.
20061029	Changing usleep(1) calls in the debugger to to usleep(10000)
		(according to Brian Foley, this makes GXemul run better on
		MacOS X).
		Making the Maple "Controller" do something (enough to barely
		interact with dcircus.elf).
20061030-31	Some progress on the PVR. More test programs start running (but
		with strange output).
		Various other SH4-related updates.
20061102	Various Dreamcast and SH4 updates; more KOS demos run now.
20061104	Adding a skeleton dev_mb8696x.c (the Dreamcast's LAN adapter).
20061105	Continuing on the MB8696x; NetBSD/dreamcast detects it as mbe0.
		Testing for the release.

==============  RELEASE 0.4.3  ==============


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

  ViewVC Help
Powered by ViewVC 1.1.26