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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26