/[gxemul]/upstream/0.3.1/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 /upstream/0.3.1/src/file.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26