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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26