/[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 6 - (show annotations)
Mon Oct 8 16:18:11 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 47331 byte(s)
++ trunk/HISTORY	(local)
$Id: HISTORY,v 1.772 2005/06/04 12:02:16 debug Exp $
20050428	Disabling the "-fmove-all-movables" option in the configure
		script, because it causes the compile to fail on OpenBSD/sgi.
20050502	Minor updates.
20050503	Removing the WRT54G mode (it was bogus anyway), and adding a
		comment about Windows NT for MIPS in doc/experiments.html.
		Minor updates to the x86 instruction decoding.
20050504	Adding some more x86 instructions.
		Adding support for reading files from ISO9660 CDROMs (including
		gzipped files). It's an ugly hack, but it seems to work.
		Various other minor updates (dev_vga.c, pc_bios.c etc).
20050505	Some more x86-related updates.
		Beginning (what I hope will be) a major code cleanup phase.
		"bootris" (an x86 bootsector) runs :-)
20050506	Adding some more x86 instructions.
20050507	tmpnam => mkstemp.
		Working on a hack to allow VGA charcells to be shown even when
		not running with X11.
		Adding more x86 instructions.
20050508	x86 32-bit SIB addressing fix, and more instructions.
20050509	Adding more x86 instructions.
20050510	Minor documentation updates, and other updates (x86 stuff etc.)
20050511	More x86-related updates.
20050513	Various updates, mostly x86-related. (Trying to fix flag 
		calculation, factoring out the ugly shift/rotate code, and
		some other things.)
20050514	Adding support for loading some old i386 a.out executables.
		Finally beginning the cleanup of machine/PROM/bios dependant
		info.
		Some minor documentation updates.
		Trying to clean up ARCBIOS stuff a little.
20050515	Trying to make it possible to actually use more than one disk
		type per machine (floppy, ide, scsi).
		Trying to clean up the kbd vs PROM console stuff. (For PC and
		ARC emulation modes, mostly.)
		Beginning to add an 8259 interrupt controller, and connecting
		it to the x86 emulation.
20050516	The first x86 interrupts seem to work (keyboard stuff).
		Adding a 8253/8254 programmable interval timer skeleton.
		FreeDOS now reaches a command prompt and can be interacted
		with.
20050517	After some bugfixes, MS-DOS also (sometimes) reaches a
		command prompt now.
		Trying to fix the pckbc to work with MS-DOS' keyb.com, but no
		success yet.
20050518	Adding a simple 32-bit x86 MMU skeleton.
20050519	Some more work on the x86 stuff. (Beginning the work on paging,
		and various other fixes).
20050520	More updates. Working on dev_vga (4-bit graphics modes), adding
		40 columns support to the PC bios emulation.
		Trying to add support for resizing windows when switching
		between graphics modes.
20050521	Many more x86-related updates.
20050522	Correcting the initial stack pointer's sign-extension for
		ARCBIOS emulation (thanks to Alec Voropay for noticing the
		error).
		Continuing on the cleanup (ARCBIOS etc).
		dev_vga updates.
20050523	More x86 updates: trying to add some support for protected mode
		interrupts (via gate descriptors) and many other fixes.
		More ARCBIOS cleanup.
		Adding a device flag which indicates that reads cause no
		side-effects. (Useful for the "dump" command in the debugger,
		and other things.)
		Adding support for directly starting up x86 ELFs, skipping the
		bootloader stage. (Most ELFs, however, are not suitable for
		this.)
20050524	Adding simple 32-bit x86 TSS task switching, but no privilege
		level support yet.
		More work on dev_vga. A small "Copper bars" demo works. :-)
		Adding support for Trap Flag (single-step exceptions), at least
		in real mode, and various other x86-related fixes.
20050525	Adding a new disk image prefix (gH;S;) which can be used to
		override the default nr of heads and sectors per track.
20050527	Various bug fixes, more work on the x86 mode (stack change on
		interrupts between different priv.levels), and some minor
		documentation updates.
20050528	Various fixes (x86 stuff).
20050529	More x86 fixes. An OpenBSD/i386 bootfloppy reaches userland
		and can be interacted with (although there are problems with
		key repetition). NetBSD/i386 triggers a serious CISC-related
		problem: instruction fetches across page boundaries, where
		the later part isn't actually part of the instruction.
20050530	Various minor updates. (Documentation updates, etc.)
20050531	Adding some experimental code (experiments/new_test_*) which
		could be useful for dynamic (but not binary) translation in
		the future.
20050602	Adding a dummy ARM skeleton.
		Fixing the pckbc key repetition problem (by adding release
		scancodes for all keypresses).
20050603	Minor updates for the next release.
20050604	Release testing. Minor updates.

==============  RELEASE 0.3.3  ==============

20050604	There'll probably be a 0.3.3.1 release soon, with some very
		very tiny updates.


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

  ViewVC Help
Powered by ViewVC 1.1.26