/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (hide 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 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 10 * $Id: file.c,v 1.99 2005/06/26 09:21:28 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 2 /*
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 dpavlin 6 char *filename, int flags,
139 dpavlin 2 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 dpavlin 6 if (flags & AOUT_FLAG_DECOSF1) {
158 dpavlin 2 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 dpavlin 10 textsize = ftello(f) - 512;
169 dpavlin 2 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 dpavlin 6 if (flags & AOUT_FLAG_FROM_BEGINNING) {
191     fseek(f, 0, SEEK_SET);
192     vaddr &= ~0xfff;
193     }
194    
195 dpavlin 2 /* 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 dpavlin 6 if (flags & AOUT_FLAG_DECOSF1)
209 dpavlin 2 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 dpavlin 10 debug("symbols: %i bytes @ 0x%x\n", symbsize, (int)ftello(f));
230 dpavlin 2 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 dpavlin 10 oldpos = ftello(f);
243 dpavlin 2 fseek(f, 0, SEEK_END);
244 dpavlin 10 strings_len = ftello(f) - oldpos;
245 dpavlin 2 fseek(f, oldpos, SEEK_SET);
246 dpavlin 10 debug("strings: %i bytes @ 0x%x\n", strings_len,(int)ftello(f));
247 dpavlin 2 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 dpavlin 6 *entrypointp = (int32_t)entry;
279 dpavlin 2
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 dpavlin 10 oldpos = ftello(f);
478 dpavlin 2
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 dpavlin 10 (long long) (ftello(f) - skip), (long long)loadaddr);
904 dpavlin 2 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 dpavlin 6 "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 dpavlin 2 exit(1);
1013     }
1014     if (eshentsize != sizeof(Elf64_Shdr)) {
1015 dpavlin 6 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 dpavlin 2 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 dpavlin 6 "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 dpavlin 2 exit(1);
1038     }
1039     if (eshentsize != sizeof(Elf32_Shdr)) {
1040 dpavlin 6 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 dpavlin 2 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 dpavlin 4 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 dpavlin 2 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 dpavlin 4 case ARCH_X86:
1091 dpavlin 2 switch (emachine) {
1092 dpavlin 4 case EM_386:
1093     case EM_486:
1094 dpavlin 6 *tocp = 1;
1095 dpavlin 2 ok = 1;
1096 dpavlin 4 break;
1097     case EM_AMD64:
1098 dpavlin 6 *tocp = 2;
1099 dpavlin 2 ok = 1;
1100 dpavlin 4 break;
1101 dpavlin 2 }
1102     break;
1103 dpavlin 6 case ARCH_ARM:
1104     switch (emachine) {
1105     case EM_ARM:
1106     ok = 1;
1107     }
1108     break;
1109 dpavlin 2 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 dpavlin 10 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 dpavlin 2
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 dpavlin 6 if (addr != 0) /* && ((st_info >> 4) & 0xf)
1443     >= STB_GLOBAL) */ {
1444 dpavlin 2 /* 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 dpavlin 6 unsigned char buf2[2];
1548     size_t len, len2, i;
1549 dpavlin 2 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 dpavlin 10 size = ftello(f);
1581 dpavlin 2 fseek(f, 0, SEEK_SET);
1582    
1583     memset(buf, 0, sizeof(buf));
1584     len = fread(buf, 1, sizeof(buf), f);
1585 dpavlin 6 fseek(f, 510, SEEK_SET);
1586     len2 = fread(buf2, 1, sizeof(buf2), f);
1587 dpavlin 2 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 dpavlin 6 /* Is it an a.out? */
1603 dpavlin 2 if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) {
1604 dpavlin 6 /* MIPS a.out */
1605 dpavlin 2 file_load_aout(machine, mem, filename, 0,
1606     entrypointp, arch, byte_orderp);
1607     goto ret;
1608     }
1609 dpavlin 6 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 dpavlin 2 if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) {
1616 dpavlin 6 /* DEC OSF1 on MIPS: */
1617     file_load_aout(machine, mem, filename, AOUT_FLAG_DECOSF1,
1618 dpavlin 2 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 dpavlin 6 "image? (Use the -d option.)\n");
1663 dpavlin 2 exit(1);
1664     }
1665    
1666 dpavlin 4 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 dpavlin 2 /*
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 dpavlin 6
1686     if (len2 == 2 && buf2[0] == 0x55 && buf2[1] == 0xaa)
1687     fprintf(stderr, "\n\nIt has a PC-style "
1688     "bootsector marker.");
1689    
1690 dpavlin 2 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