/[gxemul]/upstream/0.3.5/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

Annotation of /upstream/0.3.5/src/file.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26