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

Diff of /upstream/0.4.4/src/file.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/src/file.c revision 4 by dpavlin, Mon Oct 8 16:18:00 2007 UTC upstream/0.4.4/src/file.c revision 35 by dpavlin, Mon Oct 8 16:21:26 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: file.c,v 1.88 2005/04/17 00:15:24 debug Exp $   *  $Id: file.c,v 1.140 2007/02/10 14:29:54 debug Exp $
29   *   *
30   *  This file contains functions which load executable images into (emulated)   *  This file contains functions which load executable images into (emulated)
31   *  memory.  File formats recognized so far:   *  memory. File formats recognized so far are:
32   *   *
  *      ELF             32-bit and 64-bit ELFs  
33   *      a.out           old format used by OpenBSD 2.x pmax kernels   *      a.out           old format used by OpenBSD 2.x pmax kernels
34     *      Mach-O          MacOS X format, etc.
35   *      ecoff           old format used by Ultrix, Windows NT, etc   *      ecoff           old format used by Ultrix, Windows NT, etc
36   *      srec            Motorola SREC format   *      srec            Motorola SREC format
37   *      raw             raw binaries, "address:[skiplen:[entrypoint:]]filename"   *      raw             raw binaries, "address:[skiplen:[entrypoint:]]filename"
38     *      ELF             32-bit and 64-bit ELFs
39   *   *
40   *  If a file is not of one of the above mentioned formats, it is assumed   *  If a file is not of one of the above mentioned formats, it is assumed
41   *  to be symbol data generated by 'nm' or 'nm -S'.   *  to be symbol data generated by 'nm' or 'nm -S'.
# Line 55  Line 56 
56  #include "symbol.h"  #include "symbol.h"
57    
58    
59    extern int quiet_mode;
60    extern int verbose;
61    
62    
63  /*  ELF machine types as strings: (same as exec_elf.h)  */  /*  ELF machine types as strings: (same as exec_elf.h)  */
64  #define N_ELF_MACHINE_TYPES     64  #define N_ELF_MACHINE_TYPES     84
65  static char *elf_machine_type[N_ELF_MACHINE_TYPES] = {  static char *elf_machine_type[N_ELF_MACHINE_TYPES] = {
66          "NONE", "M32", "SPARC", "386",                          /*  0..3  */          "NONE", "M32", "SPARC", "386",                          /*  0..3  */
67          "68K", "88K", "486", "860",                             /*  4..7  */          "68K", "88K", "486", "860",                             /*  4..7  */
# Line 73  static char *elf_machine_type[N_ELF_MACH Line 78  static char *elf_machine_type[N_ELF_MACH
78          "H8S", "H8_500", "IA_64", "MIPS_X",                     /*  48..51  */          "H8S", "H8_500", "IA_64", "MIPS_X",                     /*  48..51  */
79          "COLDFIRE", "68HC12", "unknown54", "unknown55",         /*  52..55  */          "COLDFIRE", "68HC12", "unknown54", "unknown55",         /*  52..55  */
80          "unknown56", "unknown57", "unknown58", "unknown59",     /*  56..59  */          "unknown56", "unknown57", "unknown58", "unknown59",     /*  56..59  */
81          "unknown60", "unknown61", "AMD64", "unknown63"          /*  60..63  */          "unknown60", "unknown61", "AMD64", "unknown63",         /*  60..63  */
82            "unknown64", "unknown65", "unknown66", "unknown67",     /*  64..67  */
83            "unknown68", "unknown69", "unknown70", "unknown71",     /*  68..71  */
84            "unknown72", "unknown73", "unknown74", "unknown75",     /*  72..75  */
85            "unknown76", "unknown77", "unknown78", "unknown79",     /*  76..79  */
86            "unknown80", "unknown81", "unknown82", "AVR"            /*  80..83  */
87  };  };
88    
89    
# Line 123  struct ms_sym { Line 133  struct ms_sym {
133          }          }
134    
135    
136    #define AOUT_FLAG_DECOSF1               1
137    #define AOUT_FLAG_FROM_BEGINNING        2
138    #define AOUT_FLAG_VADDR_ZERO_HACK       4
139    #define AOUT_FLAG_NO_SIZES              8
140  /*  /*
141   *  file_load_aout():   *  file_load_aout():
142   *   *
# Line 133  struct ms_sym { Line 147  struct ms_sym {
147   *         formats, where text/data are aligned differently.   *         formats, where text/data are aligned differently.
148   */   */
149  static void file_load_aout(struct machine *m, struct memory *mem,  static void file_load_aout(struct machine *m, struct memory *mem,
150          char *filename, int osf1_hack,          char *filename, int flags,
151          uint64_t *entrypointp, int arch, int *byte_orderp)          uint64_t *entrypointp, int arch, int *byte_orderp)
152  {  {
153          struct exec aout_header;          struct exec aout_header;
# Line 143  static void file_load_aout(struct machin Line 157  static void file_load_aout(struct machin
157          uint32_t entry, datasize, textsize;          uint32_t entry, datasize, textsize;
158          int32_t symbsize = 0;          int32_t symbsize = 0;
159          uint32_t vaddr, total_len;          uint32_t vaddr, total_len;
160          unsigned char buf[4096];          unsigned char buf[65536];
161          unsigned char *syms;          unsigned char *syms;
162    
163            if (m->cpus[0]->byte_order == EMUL_BIG_ENDIAN)
164                    encoding = ELFDATA2MSB;
165    
166          f = fopen(filename, "r");          f = fopen(filename, "r");
167          if (f == NULL) {          if (f == NULL) {
168                  perror(filename);                  perror(filename);
169                  exit(1);                  exit(1);
170          }          }
171    
172          if (osf1_hack) {          if (flags & AOUT_FLAG_DECOSF1) {
173                  fread(&buf, 1, 32, f);                  fread(&buf, 1, 32, f);
174                  vaddr = buf[16] + (buf[17] << 8) +                  vaddr = buf[16] + (buf[17] << 8) +
175                      (buf[18] << 16) + (buf[19] << 24);                      (buf[18] << 16) + ((uint64_t)buf[19] << 24);
176                  entry = buf[20] + (buf[21] << 8) +                  entry = buf[20] + (buf[21] << 8) +
177                      (buf[22] << 16) + (buf[23] << 24);                      (buf[22] << 16) + ((uint64_t)buf[23] << 24);
178                  debug("OSF1 a.out, load address 0x%08lx, "                  debug("OSF1 a.out, load address 0x%08lx, "
179                      "entry point 0x%08x\n", (long)vaddr, (long)entry);                      "entry point 0x%08x\n", (long)vaddr, (long)entry);
180                  symbsize = 0;                  symbsize = 0;
181                  fseek(f, 0, SEEK_END);                  fseek(f, 0, SEEK_END);
182                  /*  This is of course wrong, but should work anyway:  */                  /*  This is of course wrong, but should work anyway:  */
183                  textsize = ftell(f) - 512;                  textsize = ftello(f) - 512;
184                  datasize = 0;                  datasize = 0;
185                  fseek(f, 512, SEEK_SET);                  fseek(f, 512, SEEK_SET);
186            } else if (flags & AOUT_FLAG_NO_SIZES) {
187                    fseek(f, 0, SEEK_END);
188                    textsize = ftello(f) - 32;
189                    datasize = 0;
190                    vaddr = entry = 0;
191                    fseek(f, 32, SEEK_SET);
192          } else {          } else {
193                  len = fread(&aout_header, 1, sizeof(aout_header), f);                  len = fread(&aout_header, 1, sizeof(aout_header), f);
194                  if (len != sizeof(aout_header)) {                  if (len != sizeof(aout_header)) {
# Line 175  static void file_load_aout(struct machin Line 198  static void file_load_aout(struct machin
198                  }                  }
199    
200                  unencode(entry, &aout_header.a_entry, uint32_t);                  unencode(entry, &aout_header.a_entry, uint32_t);
                 vaddr = entry;  
201                  debug("a.out, entry point 0x%08lx\n", (long)entry);                  debug("a.out, entry point 0x%08lx\n", (long)entry);
202                    vaddr = entry;
203    
204                    if (flags & AOUT_FLAG_VADDR_ZERO_HACK)
205                            vaddr = 0;
206    
207                  unencode(textsize, &aout_header.a_text, uint32_t);                  unencode(textsize, &aout_header.a_text, uint32_t);
208                  unencode(datasize, &aout_header.a_data, uint32_t);                  unencode(datasize, &aout_header.a_data, uint32_t);
# Line 185  static void file_load_aout(struct machin Line 211  static void file_load_aout(struct machin
211                  unencode(symbsize, &aout_header.a_syms, uint32_t);                  unencode(symbsize, &aout_header.a_syms, uint32_t);
212          }          }
213    
214            if (flags & AOUT_FLAG_FROM_BEGINNING) {
215                    fseek(f, 0, SEEK_SET);
216                    vaddr &= ~0xfff;
217            }
218    
219          /*  Load text and data:  */          /*  Load text and data:  */
220          total_len = textsize + datasize;          total_len = textsize + datasize;
221          while (total_len != 0) {          while (total_len != 0) {
# Line 192  static void file_load_aout(struct machin Line 223  static void file_load_aout(struct machin
223                  len = fread(buf, 1, len, f);                  len = fread(buf, 1, len, f);
224    
225                  /*  printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",                  /*  printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",
226                      len, (int)vaddr, buf[0], buf[1], buf[2]);  */                      (int)len, (int)vaddr, buf[0], buf[1], buf[2]);  */
227    
228                  if (len > 0)                  if (len > 0) {
229                          m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,                          int len2 = 0;
230                              &buf[0], len, MEM_WRITE, NO_EXCEPTIONS);                          uint64_t vaddr1 = vaddr &
231                  else {                              ((1 << BITS_PER_MEMBLOCK) - 1);
232                          if (osf1_hack)                          uint64_t vaddr2 = (vaddr +
233                                len) & ((1 << BITS_PER_MEMBLOCK) - 1);
234                            if (vaddr2 < vaddr1) {
235                                    len2 = len - vaddr2;
236                                    m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
237                                        &buf[0], len2, MEM_WRITE, NO_EXCEPTIONS);
238                            }
239                            m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr + len2,
240                                &buf[len2], len-len2, MEM_WRITE, NO_EXCEPTIONS);
241                    } else {
242                            if (flags & AOUT_FLAG_DECOSF1)
243                                  break;                                  break;
244                          else {                          else {
245                                  fprintf(stderr, "could not read from %s\n",                                  fprintf(stderr, "could not read from %s\n",
# Line 219  static void file_load_aout(struct machin Line 260  static void file_load_aout(struct machin
260                  char *string_symbols;                  char *string_symbols;
261                  off_t oldpos;                  off_t oldpos;
262    
263                  debug("symbols: %i bytes @ 0x%x\n", symbsize, (int)ftell(f));                  debug("symbols: %i bytes @ 0x%x\n", symbsize, (int)ftello(f));
264                  syms = malloc(symbsize);                  syms = malloc(symbsize);
265                  if (syms == NULL) {                  if (syms == NULL) {
266                          fprintf(stderr, "out of memory\n");                          fprintf(stderr, "out of memory\n");
# Line 232  static void file_load_aout(struct machin Line 273  static void file_load_aout(struct machin
273                          exit(1);                          exit(1);
274                  }                  }
275    
276                  oldpos = ftell(f);                  oldpos = ftello(f);
277                  fseek(f, 0, SEEK_END);                  fseek(f, 0, SEEK_END);
278                  strings_len = ftell(f) - oldpos;                  strings_len = ftello(f) - oldpos;
279                  fseek(f, oldpos, SEEK_SET);                  fseek(f, oldpos, SEEK_SET);
280                  debug("strings: %i bytes @ 0x%x\n", strings_len, (int)ftell(f));                  debug("strings: %i bytes @ 0x%x\n", strings_len,(int)ftello(f));
281                  string_symbols = malloc(strings_len);                  string_symbols = malloc(strings_len);
282                  if (string_symbols == NULL) {                  if (string_symbols == NULL) {
283                          fprintf(stderr, "out of memory\n");                          fprintf(stderr, "out of memory\n");
# Line 258  static void file_load_aout(struct machin Line 299  static void file_load_aout(struct machin
299    
300                          if (type != 0 && addr != 0)                          if (type != 0 && addr != 0)
301                                  add_symbol_name(&m->symbol_context,                                  add_symbol_name(&m->symbol_context,
302                                      addr, 0, string_symbols + str_index, 0);                                      addr, 0, string_symbols + str_index, 0, -1);
303                          i++;                          i++;
304                  }                  }
305    
# Line 268  static void file_load_aout(struct machin Line 309  static void file_load_aout(struct machin
309    
310          fclose(f);          fclose(f);
311    
312            *entrypointp = (int32_t)entry;
313    
314            if (encoding == ELFDATA2LSB)
315                    *byte_orderp = EMUL_LITTLE_ENDIAN;
316            else
317                    *byte_orderp = EMUL_BIG_ENDIAN;
318    
319            n_executables_loaded ++;
320    }
321    
322    
323    /*
324     *  file_load_macho():
325     *
326     *  Loads a Mach-O binary image into the emulated memory. The entry point
327     *  is stored in the specified CPU's registers.
328     *
329     *  TODO:
330     *
331     *      o)  Almost everything.
332     *
333     *      o)  I haven't had time to look into whether Apple's open source
334     *          license is BSD-compatible or not. Perhaps it would be possible
335     *          to use a header file containing symbolic names, and not use
336     *          hardcoded values.
337     */
338    static void file_load_macho(struct machine *m, struct memory *mem,
339            char *filename, uint64_t *entrypointp, int arch, int *byte_orderp,
340            int is_64bit, int is_reversed)
341    {
342            FILE *f;
343            uint64_t entry = 0;
344            int entry_set = 0;
345            int encoding = ELFDATA2MSB;
346            unsigned char buf[65536];
347            char *symbols, *strings;
348            uint32_t cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags;
349            uint64_t vmaddr, vmsize, fileoff, filesize;
350            int cmd_type, cmd_len, i, flavor;
351            int32_t symoff, nsyms, stroff, strsize;
352            size_t len, pos;
353    
354            if (m->cpus[0]->byte_order == EMUL_BIG_ENDIAN)
355                    encoding = ELFDATA2MSB;
356    
357            f = fopen(filename, "r");
358            if (f == NULL) {
359                    perror(filename);
360                    exit(1);
361            }
362    
363            if (is_64bit) {
364                    fatal("TODO: 64-bit Mach-O. Not supported yet.\n");
365                    exit(1);
366            }
367            if (is_reversed) {
368                    fatal("TODO: Reversed-endianness. Not supported yet.\n");
369                    exit(1);
370            }
371    
372            len = fread(buf, 1, sizeof(buf), f);
373            if (len < 100) {
374                    fatal("Bad Mach-O file?\n");
375                    exit(1);
376            }
377    
378            unencode(cputype,    &buf[4], uint32_t);
379            unencode(cpusubtype, &buf[8], uint32_t);
380            unencode(filetype,   &buf[12], uint32_t);
381            unencode(ncmds,      &buf[16], uint32_t);
382            unencode(sizeofcmds, &buf[20], uint32_t);
383            unencode(flags,      &buf[24], uint32_t);
384    
385            /*  debug("cputype=0x%x cpusubtype=0x%x filetype=0x%x\n",
386                cputype, cpusubtype, filetype);
387                debug("ncmds=%i sizeofcmds=0x%08x flags=0x%08x\n",
388                ncmds, sizeofcmds, flags);  */
389    
390            /*
391             *  Compare to "normal" values.
392             *  NOTE/TODO: These were for a Darwin (Macintosh PPC) kernel.
393             */
394            if (cputype != 0x12) {
395                    fatal("Error: Unimplemented cputype 0x%x\n", cputype);
396                    exit(1);
397            }
398            if (cpusubtype != 0) {
399                    fatal("Error: Unimplemented cpusubtype 0x%x\n", cpusubtype);
400                    exit(1);
401            }
402            /*  Filetype 2 means an executable image.  */
403            if (filetype != 2) {
404                    fatal("Error: Unimplemented filetype 0x%x\n", filetype);
405                    exit(1);
406            }
407            if (!(flags & 1)) {
408                    fatal("Error: File has 'undefined references'. Cannot"
409                        " be executed.\n", flags);
410                    exit(1);
411            }
412    
413            /*  I've only encountered flags == 1 so far.  */
414            if (flags != 1) {
415                    fatal("Error: Unimplemented flags 0x%x\n", flags);
416                    exit(1);
417            }
418    
419            /*
420             *  Read all load commands:
421             */
422            pos = is_64bit? 32 : 28;
423            cmd_type = 0;
424            do {
425                    /*  Read command type and length:  */
426                    unencode(cmd_type, &buf[pos], uint32_t);
427                    unencode(cmd_len,  &buf[pos+4], uint32_t);
428    
429    #if 0
430                    debug("cmd %i, len=%i\n", cmd_type, cmd_len);
431                    for (i=8; i<cmd_len; i++) {
432                            unsigned char ch = buf[pos+i];
433                            if (ch >= ' ' && ch < 127)
434                                    debug("%c", ch);
435                            else
436                                    debug(".");
437                    }
438    #endif
439                    switch (cmd_type) {
440                    case 1: /*  LC_SEGMENT  */
441                            debug("seg ");
442                            for (i=0; i<16; i++) {
443                                    if (buf[pos + 8 + i] == 0)
444                                            break;
445                                    debug("%c", buf[pos + 8 + i]);
446                            }
447                            unencode(vmaddr,   &buf[pos+8+16+0], uint32_t);
448                            unencode(vmsize,   &buf[pos+8+16+4], uint32_t);
449                            unencode(fileoff,  &buf[pos+8+16+8], uint32_t);
450                            unencode(filesize, &buf[pos+8+16+12], uint32_t);
451                            debug(": vmaddr=0x%x size=0x%x fileoff=0x%x",
452                                (int)vmaddr, (int)vmsize, (int)fileoff);
453    
454                            if (filesize == 0) {
455                                    debug("\n");
456                                    break;
457                            }
458    
459                            fseek(f, fileoff, SEEK_SET);
460    
461                            /*  Load data from the file:  */
462                            while (filesize != 0) {
463                                    unsigned char buf[32768];
464                                    ssize_t len = filesize > sizeof(buf) ?
465                                        sizeof(buf) : filesize;
466                                    len = fread(buf, 1, len, f);
467    
468                                    /*  printf("fread len=%i vmaddr=%x buf[0..]="
469                                        "%02x %02x %02x\n", (int)len, (int)vmaddr,
470                                        buf[0], buf[1], buf[2]);  */
471    
472                                    if (len > 0) {
473                                            int len2 = 0;
474                                            uint64_t vaddr1 = vmaddr &
475                                                ((1 << BITS_PER_MEMBLOCK) - 1);
476                                            uint64_t vaddr2 = (vmaddr +
477                                                len) & ((1 << BITS_PER_MEMBLOCK)-1);
478                                            if (vaddr2 < vaddr1) {
479                                                    len2 = len - vaddr2;
480                                                    m->cpus[0]->memory_rw(m->cpus[
481                                                        0], mem, vmaddr, &buf[0],
482                                                        len2, MEM_WRITE,
483                                                        NO_EXCEPTIONS);
484                                            }
485                                            m->cpus[0]->memory_rw(m->cpus[0], mem,
486                                                vmaddr + len2, &buf[len2], len-len2,
487                                                MEM_WRITE, NO_EXCEPTIONS);
488                                    } else {
489                                            fprintf(stderr, "error reading\n");
490                                            exit(1);
491                                    }
492    
493                                    vmaddr += len;
494                                    filesize -= len;
495                            }
496    
497                            debug("\n");
498                            break;
499    
500                    case 2: /*  LC_SYMTAB  */
501                            unencode(symoff,  &buf[pos+8], uint32_t);
502                            unencode(nsyms,   &buf[pos+12], uint32_t);
503                            unencode(stroff,  &buf[pos+16], uint32_t);
504                            unencode(strsize, &buf[pos+20], uint32_t);
505                            debug("symtable: %i symbols @ 0x%x (strings at "
506                                "0x%x)\n", nsyms, symoff, stroff);
507    
508                            symbols = malloc(12 * nsyms);
509                            if (symbols == NULL) {
510                                    fprintf(stderr, "out of memory\n");
511                                    exit(1);
512                            }
513                            fseek(f, symoff, SEEK_SET);
514                            fread(symbols, 1, 12 * nsyms, f);
515    
516                            strings = malloc(strsize);
517                            if (strings == NULL) {
518                                    fprintf(stderr, "out of memory\n");
519                                    exit(1);
520                            }
521                            fseek(f, stroff, SEEK_SET);
522                            fread(strings, 1, strsize, f);
523    
524                            for (i=0; i<nsyms; i++) {
525                                    int n_strx, n_type, n_sect, n_desc;
526                                    uint32_t n_value;
527                                    unencode(n_strx,  &symbols[i*12+0], int32_t);
528                                    unencode(n_type,  &symbols[i*12+4], uint8_t);
529                                    unencode(n_sect,  &symbols[i*12+5], uint8_t);
530                                    unencode(n_desc,  &symbols[i*12+6], int16_t);
531                                    unencode(n_value, &symbols[i*12+8], uint32_t);
532                                    /*  debug("%i: strx=%i type=%i sect=%i desc=%i"
533                                        " value=0x%x\n", i, n_strx, n_type,
534                                        n_sect, n_desc, n_value);  */
535                                    add_symbol_name(&m->symbol_context,
536                                        n_value, 0, strings + n_strx, 0, -1);
537                            }
538    
539                            free(symbols);
540                            free(strings);
541                            break;
542    
543                    case 5: debug("unix thread context: ");
544                            /*  See http://cvs.sf.net/viewcvs.py/hte/
545                                HT%20Editor/machostruc.h or similar for details
546                                on the thread struct.  */
547                            unencode(flavor, &buf[pos+8], uint32_t);
548                            if (flavor != 1) {
549                                    fatal("unimplemented flavor %i\n", flavor);
550                                    exit(1);
551                            }
552    
553                            if (arch != ARCH_PPC) {
554                                    fatal("non-PPC arch? TODO\n");
555                                    exit(1);
556                            }
557    
558                            unencode(entry, &buf[pos+16], uint32_t);
559                            entry_set = 1;
560                            debug("pc=0x%x\n", (int)entry);
561    
562                            for (i=1; i<40; i++) {
563                                    uint32_t x;
564                                    unencode(x, &buf[pos+16+i*4], uint32_t);
565                                    if (x != 0) {
566                                            fatal("Entry nr %i in the Mach-O"
567                                                " thread struct is non-zero"
568                                                " (0x%x). This is not supported"
569                                                " yet. TODO\n", i, x);
570                                            exit(1);
571                                    }
572                            }
573                            break;
574    
575                    default:fatal("WARNING! Unimplemented load command %i!\n",
576                                cmd_type);
577                    }
578    
579                    pos += cmd_len;
580            } while (pos < sizeofcmds && cmd_type != 0);
581    
582            fclose(f);
583    
584            if (!entry_set) {
585                    fatal("No entry point? Aborting.\n");
586                    exit(1);
587            }
588    
589          *entrypointp = entry;          *entrypointp = entry;
590    
591          if (encoding == ELFDATA2LSB)          if (encoding == ELFDATA2LSB)
# Line 467  static void file_load_ecoff(struct machi Line 785  static void file_load_ecoff(struct machi
785                  if (s_scnptr != 0 && s_size != 0 &&                  if (s_scnptr != 0 && s_size != 0 &&
786                      s_vaddr != 0 && !(s_flags & 0x02)) {                      s_vaddr != 0 && !(s_flags & 0x02)) {
787                          /*  Remember the current file offset:  */                          /*  Remember the current file offset:  */
788                          oldpos = ftell(f);                          oldpos = ftello(f);
789    
790                          /*  Load the section into emulated memory:  */                          /*  Load the section into emulated memory:  */
791                          fseek(f, s_scnptr, SEEK_SET);                          fseek(f, s_scnptr, SEEK_SET);
# Line 556  static void file_load_ecoff(struct machi Line 874  static void file_load_ecoff(struct machi
874                                          debug("%c", sym->name[i]);  */                                          debug("%c", sym->name[i]);  */
875                                  v = sym->value[0] + (sym->value[1] << 8)                                  v = sym->value[0] + (sym->value[1] << 8)
876                                      + (sym->value[2] << 16)                                      + (sym->value[2] << 16)
877                                      + (sym->value[3] << 24);                                      + ((uint64_t)sym->value[3] << 24);
878                                  altname = sym->name[4] + (sym->name[5] << 8)                                  altname = sym->name[4] + (sym->name[5] << 8)
879                                      + (sym->name[6] << 16)                                      + (sym->name[6] << 16)
880                                      + (sym->name[3] << 24);                                      + ((uint64_t)sym->name[3] << 24);
881                                  t = (sym->type[1] << 8) + sym->type[0];                                  t = (sym->type[1] << 8) + sym->type[0];
882                                  /*  TODO: big endian COFF?  */                                  /*  TODO: big endian COFF?  */
883                                  /*  debug("' value=0x%x type=0x%04x", v, t);  */                                  /*  debug("' value=0x%x type=0x%04x", v, t);  */
# Line 568  static void file_load_ecoff(struct machi Line 886  static void file_load_ecoff(struct machi
886                                          memcpy(name, sym->name, 8);                                          memcpy(name, sym->name, 8);
887                                          name[8] = '\0';                                          name[8] = '\0';
888                                          add_symbol_name(&m->symbol_context,                                          add_symbol_name(&m->symbol_context,
889                                              v, 0, name, 0);                                              v, 0, name, 0, -1);
890                                          n_real_symbols ++;                                          n_real_symbols ++;
891                                  } else if (t == 0x20 && !sym->name[0]) {                                  } else if (t == 0x20 && !sym->name[0]) {
892                                          off_t ofs;                                          off_t ofs;
# Line 580  static void file_load_ecoff(struct machi Line 898  static void file_load_ecoff(struct machi
898                                          /*  debug(" [altname=0x%x '%s']",                                          /*  debug(" [altname=0x%x '%s']",
899                                              altname, name);  */                                              altname, name);  */
900                                          add_symbol_name(&m->symbol_context,                                          add_symbol_name(&m->symbol_context,
901                                              v, 0, name, 0);                                              v, 0, name, 0, -1);
902                                          n_real_symbols ++;                                          n_real_symbols ++;
903                                  }                                  }
904    
# Line 651  static void file_load_ecoff(struct machi Line 969  static void file_load_ecoff(struct machi
969    
970                          add_symbol_name(&m->symbol_context,                          add_symbol_name(&m->symbol_context,
971                              extsyms[sym_nr].es_value, 0,                              extsyms[sym_nr].es_value, 0,
972                              symbol_data + extsyms[sym_nr].es_strindex, 0);                              symbol_data + extsyms[sym_nr].es_strindex, 0, -1);
973                  }                  }
974    
975                  free(extsyms);                  free(extsyms);
# Line 790  static void file_load_srec(struct machin Line 1108  static void file_load_srec(struct machin
1108                                      bytes[2];                                      bytes[2];
1109                                  break;                                  break;
1110                          case 3: data_start = 4;                          case 3: data_start = 4;
1111                                  vaddr = (bytes[0] << 24) + (bytes[1] << 16) +                                  vaddr = ((uint64_t)bytes[0] << 24) +
1112                                      (bytes[2] << 8) + bytes[3];                                      (bytes[1] << 16) + (bytes[2]<<8) + bytes[3];
1113                          }                          }
1114                          m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,                          m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
1115                              &bytes[data_start], count - 1 - data_start,                              &bytes[data_start], count - 1 - data_start,
# Line 803  static void file_load_srec(struct machin Line 1121  static void file_load_srec(struct machin
1121                  case 9:                  case 9:
1122                          /*  switch again, to get the entry point:  */                          /*  switch again, to get the entry point:  */
1123                          switch (buf[1]) {                          switch (buf[1]) {
1124                          case 7: entry = (bytes[0] << 24) + (bytes[1] << 16) +                          case 7: entry = ((uint64_t)bytes[0] << 24) +
1125                                      (bytes[2] << 8) + bytes[3];                                      (bytes[1] << 16) + (bytes[2]<<8) + bytes[3];
1126                                  break;                                  break;
1127                          case 8: entry = (bytes[0] << 16) + (bytes[1] << 8) +                          case 8: entry = (bytes[0] << 16) + (bytes[1] << 8) +
1128                                      bytes[2];                                      bytes[2];
# Line 845  static void file_load_raw(struct machine Line 1163  static void file_load_raw(struct machine
1163          char *filename, uint64_t *entrypointp)          char *filename, uint64_t *entrypointp)
1164  {  {
1165          FILE *f;          FILE *f;
1166          int len;          int len, sign3264;
1167          unsigned char buf[4096];          unsigned char buf[16384];
1168          uint64_t entry, loadaddr, vaddr, skip = 0;          uint64_t entry, loadaddr, vaddr, skip = 0;
1169          char *p, *p2;          char *p, *p2;
1170    
1171            /*  Special case for 32-bit MIPS:  */
1172            sign3264 = 0;
1173            if (m->arch == ARCH_MIPS && m->cpus[0]->is_32bit)
1174                    sign3264 = 1;
1175    
1176          p = strchr(filename, ':');          p = strchr(filename, ':');
1177          if (p == NULL) {          if (p == NULL) {
1178                  fprintf(stderr, "\n");                  fprintf(stderr, "\n");
# Line 873  static void file_load_raw(struct machine Line 1196  static void file_load_raw(struct machine
1196          } else          } else
1197                  p = p2;                  p = p2;
1198    
1199            if (sign3264) {
1200                    loadaddr = (int64_t)(int32_t)loadaddr;
1201                    entry = (int64_t)(int32_t)entry;
1202                    vaddr = (int64_t)(int32_t)vaddr;
1203                    skip = (int64_t)(int32_t)skip;
1204            }
1205    
1206          f = fopen(strrchr(filename, ':')+1, "r");          f = fopen(strrchr(filename, ':')+1, "r");
1207          if (f == NULL) {          if (f == NULL) {
1208                  perror(p);                  perror(p);
# Line 883  static void file_load_raw(struct machine Line 1213  static void file_load_raw(struct machine
1213    
1214          /*  Load file contents:  */          /*  Load file contents:  */
1215          while (!feof(f)) {          while (!feof(f)) {
1216                  len = fread(buf, 1, sizeof(buf), f);                  size_t to_read = sizeof(buf);
1217    
1218                    /*  If vaddr isn't buf-size aligned, then start with a
1219                        smaller buffer:  */
1220                    if (vaddr & (sizeof(buf) - 1))
1221                            to_read = sizeof(buf) - (vaddr & (sizeof(buf)-1));
1222    
1223                    len = fread(buf, 1, to_read, f);
1224    
1225                  if (len > 0)                  if (len > 0)
1226                          m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr, &buf[0],                          m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr, &buf[0],
# Line 892  static void file_load_raw(struct machine Line 1229  static void file_load_raw(struct machine
1229                  vaddr += len;                  vaddr += len;
1230          }          }
1231    
1232          debug("RAW: 0x%llx bytes @ 0x%08llx",          debug("RAW: 0x%"PRIx64" bytes @ 0x%08"PRIx64,
1233              (long long) (ftell(f) - skip), (long long)loadaddr);              (uint64_t) (ftello(f) - skip), (uint64_t) loadaddr);
1234    
1235          if (skip != 0)          if (skip != 0)
1236                  debug(" (0x%llx bytes of header skipped)", (long long)skip);                  debug(" (0x%"PRIx64" bytes of header skipped)",
1237                        (uint64_t) skip);
1238    
1239          debug("\n");          debug("\n");
1240    
1241          fclose(f);          fclose(f);
# Line 999  static void file_load_elf(struct machine Line 1339  static void file_load_elf(struct machine
1339                  unencode(eshoff,     &hdr64.e_shoff,     Elf64_Off);                  unencode(eshoff,     &hdr64.e_shoff,     Elf64_Off);
1340                  if (ephentsize != sizeof(Elf64_Phdr)) {                  if (ephentsize != sizeof(Elf64_Phdr)) {
1341                          fprintf(stderr, "%s: incorrect phentsize? %i, should "                          fprintf(stderr, "%s: incorrect phentsize? %i, should "
1342                              "be %i\n", filename, (int)ephentsize,                              "be %i\nPerhaps this is a dynamically linked "
1343                              (int)sizeof(Elf64_Phdr));                              "binary (which isn't supported yet).\n", filename,
1344                                (int)ephentsize, (int)sizeof(Elf64_Phdr));
1345                          exit(1);                          exit(1);
1346                  }                  }
1347                  if (eshentsize != sizeof(Elf64_Shdr)) {                  if (eshentsize != sizeof(Elf64_Shdr)) {
1348                          fprintf(stderr, "%s: incorrect phentsize? %i, should "                          fprintf(stderr, "%s: incorrect shentsize? %i, should "
1349                              "be %i\n", filename, (int)ephentsize,                              "be %i\nPerhaps this is a dynamically linked "
1350                              (int)sizeof(Elf64_Shdr));                              "binary (which isn't supported yet).\n", filename,
1351                                (int)eshentsize, (int)sizeof(Elf64_Shdr));
1352                          exit(1);                          exit(1);
1353                  }                  }
1354          } else {          } else {
# Line 1022  static void file_load_elf(struct machine Line 1364  static void file_load_elf(struct machine
1364                  unencode(eshoff,     &hdr32.e_shoff,     Elf32_Off);                  unencode(eshoff,     &hdr32.e_shoff,     Elf32_Off);
1365                  if (ephentsize != sizeof(Elf32_Phdr)) {                  if (ephentsize != sizeof(Elf32_Phdr)) {
1366                          fprintf(stderr, "%s: incorrect phentsize? %i, should "                          fprintf(stderr, "%s: incorrect phentsize? %i, should "
1367                              "be %i\n", filename, (int)ephentsize,                              "be %i\nPerhaps this is a dynamically linked "
1368                              (int)sizeof(Elf32_Phdr));                              "binary (which isn't supported yet).\n", filename,
1369                                (int)ephentsize, (int)sizeof(Elf32_Phdr));
1370                          exit(1);                          exit(1);
1371                  }                  }
1372                  if (eshentsize != sizeof(Elf32_Shdr)) {                  if (eshentsize != sizeof(Elf32_Shdr)) {
1373                          fprintf(stderr, "%s: incorrect phentsize? %i, should "                          fprintf(stderr, "%s: incorrect shentsize? %i, should "
1374                              "be %i\n", filename, (int)ephentsize,                              "be %i\nPerhaps this is a dynamically linked "
1375                              (int)sizeof(Elf32_Shdr));                              "binary (which isn't supported yet).\n", filename,
1376                                (int)eshentsize, (int)sizeof(Elf32_Shdr));
1377                          exit(1);                          exit(1);
1378                  }                  }
1379          }          }
# Line 1049  static void file_load_elf(struct machine Line 1393  static void file_load_elf(struct machine
1393                          ok = 1;                          ok = 1;
1394                  }                  }
1395                  break;                  break;
1396            case ARCH_ARM:
1397                    switch (emachine) {
1398                    case EM_ARM:
1399                            ok = 1;
1400                    }
1401                    break;
1402            case ARCH_AVR:
1403                    switch (emachine) {
1404                    case EM_AVR:
1405                            ok = 1;
1406                    }
1407                    break;
1408            /*  case ARCH_AVR32:
1409                    switch (emachine) {
1410                    case 6317:
1411                            ok = 1;
1412                    }
1413                    break;
1414          case ARCH_HPPA:          case ARCH_HPPA:
1415                  switch (emachine) {                  switch (emachine) {
1416                  case EM_PARISC:                  case EM_PARISC:
1417                          ok = 1;                          ok = 1;
1418                  }                  }
1419                  break;                  break;
1420            case ARCH_I960:
1421                    switch (emachine) {
1422                    case EM_960:
1423                            ok = 1;
1424                    }
1425                    break;
1426            case ARCH_IA64:
1427                    switch (emachine) {
1428                    case EM_IA_64:
1429                            ok = 1;
1430                    }
1431                    break;  */
1432            case ARCH_M68K:
1433                    switch (emachine) {
1434                    case EM_68K:
1435                            ok = 1;
1436                    }
1437                    break;
1438          case ARCH_MIPS:          case ARCH_MIPS:
1439                  switch (emachine) {                  switch (emachine) {
1440                  case EM_MIPS:                  case EM_MIPS:
# Line 1069  static void file_load_elf(struct machine Line 1449  static void file_load_elf(struct machine
1449                          ok = 1;                          ok = 1;
1450                  }                  }
1451                  break;                  break;
1452            case ARCH_SH:
1453                    switch (emachine) {
1454                    case EM_SH:
1455                            ok = 1;
1456                    }
1457                    break;
1458          case ARCH_SPARC:          case ARCH_SPARC:
1459                  switch (emachine) {                  switch (emachine) {
1460                  case EM_SPARC:                  case EM_SPARC:
# Line 1076  static void file_load_elf(struct machine Line 1462  static void file_load_elf(struct machine
1462                          ok = 1;                          ok = 1;
1463                  }                  }
1464                  break;                  break;
1465          case ARCH_X86:          /*  case ARCH_X86:
1466                  switch (emachine) {                  switch (emachine) {
1467                  case EM_386:                  case EM_386:
1468                  case EM_486:                  case EM_486:
1469                            *tocp = 1;
1470                          ok = 1;                          ok = 1;
1471                          break;                          break;
1472                  case EM_AMD64:                  case EM_AMD64:
1473                          *tocp = 1;                          *tocp = 2;
1474                          ok = 1;                          ok = 1;
1475                          break;                          break;
1476                  }                  }
1477                  break;                  break;  */
1478          default:          default:
1479                  fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n");                  fatal("file.c: INTERNAL ERROR: Unimplemented arch!\n");
1480          }          }
# Line 1109  static void file_load_elf(struct machine Line 1496  static void file_load_elf(struct machine
1496              encoding == ELFDATA2LSB? "LSB (LE)" : "MSB (BE)", s);              encoding == ELFDATA2LSB? "LSB (LE)" : "MSB (BE)", s);
1497    
1498          if (elf64)          if (elf64)
1499                  debug("%016llx\n", (long long)eentry);                  debug("%016"PRIx64"\n", (uint64_t) eentry);
1500          else          else
1501                  debug("%08x\n", (int)eentry);                  debug("%08"PRIx32"\n", (uint32_t) eentry);
1502    
1503          /*          /*
1504           *  MIPS16 encoding?           *  SH64: 32-bit instruction encoding?
          *  
          *  TODO:  Find out what e_flag actually contains.  
          *  TODO 2: This only sets mips16 for cpu 0. Yuck. Fix this!  
1505           */           */
1506            if (arch == ARCH_SH && (eentry & 1)) {
1507          if (((eflags >> 24) & 0xff) == 0x24) {                  debug("SH64: 32-bit instruction encoding\n");
1508                  debug("MIPS16 encoding (e_flags = 0x%08x)\n", eflags);                  m->cpus[0]->cd.sh.compact = 0;
1509  #ifdef ENABLE_MIPS16                  m->cpus[0]->cd.sh.cpu_type.bits = 64;
                 m->cpus[0]->cd.mips.mips16 = 1;  
 #else  
                 fatal("ENABLE_MIPS16 must be defined in misc.h.\n"  
                     "(or use the --mips16 configure option)\n");  
                 exit(1);  
 #endif  
         } else if (eentry & 0x3) {  
                 debug("MIPS16 encoding (eentry not 32-bit aligned)\n");  
 #ifdef ENABLE_MIPS16  
                 m->cpus[0]->cd.mips.mips16 = 1;  
 #else  
                 fatal("ENABLE_MIPS16 must be defined in misc.h.\n"  
                     "(or use the --mips16 configure option)\n");  
                 exit(1);  
 #endif  
1510          }          }
1511    
1512          /*  Read the program headers:  */          /*  Read the program headers:  */
# Line 1176  static void file_load_elf(struct machine Line 1545  static void file_load_elf(struct machine
1545                          unencode(p_align,   &phdr32.p_align,   Elf32_Word);                          unencode(p_align,   &phdr32.p_align,   Elf32_Word);
1546                  }                  }
1547    
1548                    /*
1549                     *  Hack for loading PPC kernels that are linked to high
1550                     *  addresses. (This requires enabling of instruction and
1551                     *  data virtual address translation.)
1552                     */
1553                    if (arch == ARCH_PPC) {
1554                            if ( (elf64 && (p_vaddr >> 60) != 0) ||
1555                                (!elf64 && (p_vaddr >> 28) != 0) )
1556                                    m->cpus[m->bootstrap_cpu]->
1557                                        cd.ppc.msr |= PPC_MSR_IR | PPC_MSR_DR;
1558                    }
1559    
1560                  if (p_memsz != 0 && (p_type == PT_LOAD ||                  if (p_memsz != 0 && (p_type == PT_LOAD ||
1561                      (p_type & PF_MASKPROC) == PT_MIPS_REGINFO)) {                      (p_type & PF_MASKPROC) == PT_MIPS_REGINFO)) {
1562                          debug("chunk %i (", i);                          debug("chunk %i (", i);
1563                          if (p_type == PT_LOAD)                          if (p_type == PT_LOAD)
1564                                  debug("load");                                  debug("load");
1565                          else                          else
1566                                  debug("0x%08x", (int)p_type);                                  debug("0x%08"PRIx32, (uint32_t) p_type);
1567    
1568                          debug(") @ 0x%llx, vaddr 0x", (long long)p_offset);                          debug(") @ 0x%"PRIx64", vaddr 0x", (uint64_t) p_offset);
1569    
1570                          if (elf64)                          if (elf64)
1571                                  debug("%016llx", (long long)p_vaddr);                                  debug("%016"PRIx64, (uint64_t) p_vaddr);
1572                          else                          else
1573                                  debug("%08x", (int)p_vaddr);                                  debug("%08"PRIx32, (uint32_t) p_vaddr);
1574    
1575                          debug(" len=0x%llx\n", (long long)p_memsz);                          debug(" len=0x%"PRIx64"\n", (uint64_t) p_memsz);
1576    
1577                          if (p_vaddr != p_paddr) {                          if (p_vaddr != p_paddr) {
1578                                  fprintf(stderr, "%s: vaddr != paddr. TODO: "                                  if (elf64)
1579                                      "how to handle this? vaddr=%016llx paddr"                                          debug("NOTE: vaddr (0x%"PRIx64") and "
1580                                      "=%016llx\n", filename, (long long)p_vaddr,                                              "paddr (0x%"PRIx64") differ; using "
1581                                      (long long)p_paddr);                                              "vaddr\n", (uint64_t) p_vaddr,
1582                                  exit(1);                                              (uint64_t) p_paddr);
1583                                    else
1584                                            debug("NOTE: vaddr (0x%08"PRIx32") and "
1585                                                "paddr (0x%08"PRIx32") differ; usin"
1586                                                "g vaddr\n", (uint32_t) p_vaddr,
1587                                                (uint32_t)p_paddr);
1588                          }                          }
1589    
1590                          if (p_memsz < p_filesz) {                          if (p_memsz < p_filesz) {
1591                                  fprintf(stderr, "%s: memsz < filesz. TODO: how"                                  fprintf(stderr, "%s: memsz < filesz. TODO: how"
1592                                      " to handle this? memsz=%016llx filesz="                                      " to handle this? memsz=%016"PRIx64
1593                                      "%016llx\n", filename, (long long)p_memsz,                                      " filesz=%016"PRIx64"\n", filename,
1594                                      (long long)p_filesz);                                      (uint64_t) p_memsz, (uint64_t) p_filesz);
1595                                  exit(1);                                  exit(1);
1596                          }                          }
1597    
# Line 1262  static void file_load_elf(struct machine Line 1648  static void file_load_elf(struct machine
1648                  }                  }
1649          }          }
1650    
1651          /*  Read the section headers to find the address of the _gp symbol:  */          /*
1652             *  Read the section headers to find the address of the _gp
1653             *  symbol (for MIPS):
1654             */
1655    
1656          for (i=0; i<eshnum; i++) {          for (i=0; i<eshnum; i++) {
1657                  int sh_name, sh_type, sh_flags, sh_link, sh_info, sh_entsize;                  int sh_name, sh_type, sh_flags, sh_link, sh_info, sh_entsize;
# Line 1270  static void file_load_elf(struct machine Line 1659  static void file_load_elf(struct machine
1659                  off_t sh_offset;                  off_t sh_offset;
1660                  int n_entries;  /*  for reading the symbol / string tables  */                  int n_entries;  /*  for reading the symbol / string tables  */
1661    
1662                  /*  debug("section header %i at %016llx\n", i,                  /*  debug("section header %i at %016"PRIx64"\n", i,
1663                      (long long) eshoff+i*eshentsize);  */                      (uint64_t) eshoff+i*eshentsize);  */
1664    
1665                  fseek(f, eshoff + i * eshentsize, SEEK_SET);                  fseek(f, eshoff + i * eshentsize, SEEK_SET);
1666    
# Line 1357  static void file_load_elf(struct machine Line 1746  static void file_load_elf(struct machine
1746                                  exit(1);                                  exit(1);
1747                          }                          }
1748    
1749                          debug("%i symbol entries at 0x%llx\n",                          debug("%i symbol entries at 0x%"PRIx64"\n",
1750                              (int)n_entries, (long long)sh_offset);                              (int) n_entries, (uint64_t) sh_offset);
1751    
1752                          n_symbols = n_entries;                          n_symbols = n_entries;
1753                  }                  }
# Line 1391  static void file_load_elf(struct machine Line 1780  static void file_load_elf(struct machine
1780                                  exit(1);                                  exit(1);
1781                          }                          }
1782    
1783                          debug("%i bytes of symbol strings at 0x%llx\n",                          debug("%i bytes of symbol strings at 0x%"PRIx64"\n",
1784                              (int)sh_size, (long long)sh_offset);                              (int) sh_size, (uint64_t) sh_offset);
1785    
1786                          symbol_strings[sh_size] = '\0';                          symbol_strings[sh_size] = '\0';
1787                          symbol_length = sh_size;                          symbol_length = sh_size;
# Line 1416  static void file_load_elf(struct machine Line 1805  static void file_load_elf(struct machine
1805                          } else {                          } else {
1806                                  sym32 = symbols_sym32[i];                                  sym32 = symbols_sym32[i];
1807                                  unencode(st_name, &sym32.st_name,  Elf32_Word);                                  unencode(st_name, &sym32.st_name,  Elf32_Word);
1808                                  unencode(st_info, &sym64.st_info,  Elf_Byte);                                  unencode(st_info, &sym32.st_info,  Elf_Byte);
1809                                  unencode(addr,    &sym32.st_value, Elf32_Word);                                  unencode(addr,    &sym32.st_value, Elf32_Word);
1810                                  unencode(size,    &sym32.st_size, Elf32_Word);                                  unencode(size,    &sym32.st_size, Elf32_Word);
1811                          }                          }
1812    
1813                            /*  debug("symbol info=0x%02x addr=0x%016"PRIx64
1814                                " (%i) '%s'\n", st_info, (uint64_t) addr,
1815                                st_name, symbol_strings + st_name);  */
1816    
1817                          if (size == 0)                          if (size == 0)
1818                                  size ++;                                  size ++;
1819    
1820                          if (addr != 0) {                          if (addr != 0) /* && ((st_info >> 4) & 0xf)
1821                                  /*  debug("symbol info=0x%02x addr=0x%016llx"                              >= STB_GLOBAL) */ {
1822                                      " '%s'\n", st_info, (long long)addr,                                  /*  debug("symbol info=0x%02x addr=0x%016"PRIx64
1823                                        " '%s'\n", st_info, (uint64_t) addr,
1824                                      symbol_strings + st_name);  */                                      symbol_strings + st_name);  */
1825                                  add_symbol_name(&m->symbol_context,                                  add_symbol_name(&m->symbol_context,
1826                                      addr, size, symbol_strings + st_name, 0);                                      addr, size, symbol_strings + st_name,
1827                                        0, -1);
1828                          }                          }
1829    
1830                          if (strcmp(symbol_strings + st_name, "_gp") == 0) {                          if (strcmp(symbol_strings + st_name, "_gp") == 0) {
1831                                  debug("found _gp address: 0x");                                  debug("found _gp address: 0x");
1832                                  if (elf64)                                  if (elf64)
1833                                          debug("%016llx\n", (long long)addr);                                          debug("%016"PRIx64"\n", (uint64_t)addr);
1834                                  else                                  else
1835                                          debug("%08x\n", (int)addr);                                          debug("%08"PRIx32"\n", (uint32_t)addr);
1836                                  *gpp = addr;                                  *gpp = addr;
1837                          }                          }
1838                  }                  }
# Line 1490  static void file_load_elf(struct machine Line 1885  static void file_load_elf(struct machine
1885                      ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +                      ((uint64_t)b[5] << 16) + ((uint64_t)b[6] << 8) +
1886                      (uint64_t)b[7];                      (uint64_t)b[7];
1887    
1888                  debug("entrypoint 0x%016llx, toc_base 0x%016llx\n",                  debug("entrypoint 0x%016"PRIx64", toc_base 0x%016"PRIx64"\n",
1889                      (long long)*entrypointp, (long long)toc_base);                      (uint64_t) *entrypointp, (uint64_t) toc_base);
1890                  if (tocp != NULL)                  if (tocp != NULL)
1891                          *tocp = toc_base;                          *tocp = toc_base;
1892          }          }
# Line 1525  void file_load(struct machine *machine, Line 1920  void file_load(struct machine *machine,
1920          char *filename, uint64_t *entrypointp,          char *filename, uint64_t *entrypointp,
1921          int arch, uint64_t *gpp, int *byte_orderp, uint64_t *tocp)          int arch, uint64_t *gpp, int *byte_orderp, uint64_t *tocp)
1922  {  {
1923          int iadd = 4;          int iadd = DEBUG_INDENTATION, old_quiet_mode;
1924          FILE *f;          FILE *f;
1925          unsigned char buf[12];          unsigned char buf[12];
1926          int len, i;          unsigned char buf2[2];
1927            size_t len, len2, i;
1928          off_t size;          off_t size;
1929    
1930          if (byte_orderp == NULL) {          if (byte_orderp == NULL) {
# Line 1550  void file_load(struct machine *machine, Line 1946  void file_load(struct machine *machine,
1946          if (filename[0] == '@')          if (filename[0] == '@')
1947                  return;                  return;
1948    
1949          debug("loading %s:\n", filename);          debug("loading %s%s\n", filename, verbose >= 2? ":" : "");
1950          debug_indentation(iadd);          debug_indentation(iadd);
1951    
1952            old_quiet_mode = quiet_mode;
1953            if (verbose < 2)
1954                    quiet_mode = 1;
1955    
1956          f = fopen(filename, "r");          f = fopen(filename, "r");
1957          if (f == NULL) {          if (f == NULL) {
1958                  file_load_raw(machine, mem, filename, entrypointp);                  file_load_raw(machine, mem, filename, entrypointp);
# Line 1560  void file_load(struct machine *machine, Line 1960  void file_load(struct machine *machine,
1960          }          }
1961    
1962          fseek(f, 0, SEEK_END);          fseek(f, 0, SEEK_END);
1963          size = ftell(f);          size = ftello(f);
1964          fseek(f, 0, SEEK_SET);          fseek(f, 0, SEEK_SET);
1965    
1966          memset(buf, 0, sizeof(buf));          memset(buf, 0, sizeof(buf));
1967          len = fread(buf, 1, sizeof(buf), f);          len = fread(buf, 1, sizeof(buf), f);
1968            fseek(f, 510, SEEK_SET);
1969            len2 = fread(buf2, 1, sizeof(buf2), f);
1970          fclose(f);          fclose(f);
1971    
1972          if (len < (signed int)sizeof(buf)) {          if (len < (signed int)sizeof(buf)) {
# Line 1580  void file_load(struct machine *machine, Line 1982  void file_load(struct machine *machine,
1982                  goto ret;                  goto ret;
1983          }          }
1984    
1985          /*  Is it an a.out?  (Special case for DEC OSF1 kernels.)  */          /*  Is it an a.out?  */
1986          if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) {          if (buf[0]==0x00 && buf[1]==0x8b && buf[2]==0x01 && buf[3]==0x07) {
1987                    /*  MIPS a.out  */
1988                  file_load_aout(machine, mem, filename, 0,                  file_load_aout(machine, mem, filename, 0,
1989                      entrypointp, arch, byte_orderp);                      entrypointp, arch, byte_orderp);
1990                  goto ret;                  goto ret;
1991          }          }
1992            if (buf[0]==0x00 && buf[1]==0x87 && buf[2]==0x01 && buf[3]==0x08) {
1993                    /*  M68K a.out  */
1994                    file_load_aout(machine, mem, filename,
1995                        AOUT_FLAG_VADDR_ZERO_HACK  /*  for OpenBSD/mac68k  */,
1996                        entrypointp, arch, byte_orderp);
1997                    goto ret;
1998            }
1999            if (buf[0]==0x00 && buf[1]==0x8f && buf[2]==0x01 && buf[3]==0x0b) {
2000                    /*  ARM a.out  */
2001                    file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING,
2002                        entrypointp, arch, byte_orderp);
2003                    goto ret;
2004            }
2005            if (buf[0]==0x00 && buf[1]==0x86 && buf[2]==0x01 && buf[3]==0x0b) {
2006                    /*  i386 a.out (old OpenBSD and NetBSD etc)  */
2007                    file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING,
2008                        entrypointp, arch, byte_orderp);
2009                    goto ret;
2010            }
2011            if (buf[0]==0x01 && buf[1]==0x03 && buf[2]==0x01 && buf[3]==0x07) {
2012                    /*  SPARC a.out (old 32-bit NetBSD etc)  */
2013                    file_load_aout(machine, mem, filename, AOUT_FLAG_NO_SIZES,
2014                        entrypointp, arch, byte_orderp);
2015                    goto ret;
2016            }
2017          if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) {          if (buf[0]==0x00 && buf[2]==0x00 && buf[8]==0x7a && buf[9]==0x75) {
2018                  file_load_aout(machine, mem, filename, 1,                  /*  DEC OSF1 on MIPS:  */
2019                    file_load_aout(machine, mem, filename, AOUT_FLAG_DECOSF1,
2020                      entrypointp, arch, byte_orderp);                      entrypointp, arch, byte_orderp);
2021                  goto ret;                  goto ret;
2022          }          }
2023    
2024          /*          /*
2025             *  Is it a Mach-O file?
2026             */
2027            if (buf[0] == 0xfe && buf[1] == 0xed && buf[2] == 0xfa &&
2028                (buf[3] == 0xce || buf[3] == 0xcf)) {
2029                    file_load_macho(machine, mem, filename, entrypointp,
2030                        arch, byte_orderp, buf[3] == 0xcf, 0);
2031                    goto ret;
2032            }
2033            if ((buf[0] == 0xce || buf[0] == 0xcf) && buf[1] == 0xfa &&
2034                buf[2] == 0xed && buf[3] == 0xfe) {
2035                    file_load_macho(machine, mem, filename, entrypointp,
2036                        arch, byte_orderp, buf[0] == 0xcf, 1);
2037                    goto ret;
2038            }
2039    
2040            /*
2041           *  Is it an ecoff?           *  Is it an ecoff?
2042           *           *
2043           *  TODO: What's the deal with the magic value's byte order? Sometimes           *  TODO: What's the deal with the magic value's byte order? Sometimes
# Line 1632  void file_load(struct machine *machine, Line 2077  void file_load(struct machine *machine,
2077                  fprintf(stderr, "\nThis file is very large (%lli bytes)\n",                  fprintf(stderr, "\nThis file is very large (%lli bytes)\n",
2078                      (long long)size);                      (long long)size);
2079                  fprintf(stderr, "Are you sure it is a kernel and not a disk "                  fprintf(stderr, "Are you sure it is a kernel and not a disk "
2080                      "image?\n");                      "image? (Use the -d option.)\n");
2081                  exit(1);                  exit(1);
2082          }          }
2083    
# Line 1641  void file_load(struct machine *machine, Line 2086  void file_load(struct machine *machine,
2086                      "floppy image. Maybe you forgot the\n-d switch?\n");                      "floppy image. Maybe you forgot the\n-d switch?\n");
2087    
2088          /*          /*
2089             *  Ugly hack for Dreamcast:  When booting from a Dreamcast CDROM
2090             *  image, a temporary file is extracted into /tmp/gxemul.*, but this
2091             *  is a "scrambled" raw binary. This code unscrambles it, and loads
2092             *  it as a raw binary.
2093             */
2094            if (machine->machine_type == MACHINE_DREAMCAST &&
2095                strncmp(filename, "/tmp/gxemul.", 12) == 0) {
2096                    char *tmp_filename = malloc(strlen(filename) + 100);
2097                    snprintf(tmp_filename, strlen(filename) + 100,
2098                        "%s.descrambled", filename);
2099                    debug("descrambling into %s\n", tmp_filename);
2100                    dreamcast_descramble(filename, tmp_filename);
2101    
2102                    snprintf(tmp_filename, strlen(filename) + 100,
2103                        "0x8c010000:%s.descrambled", filename);
2104                    debug("loading descrambled Dreamcast binary\n");
2105                    file_load_raw(machine, mem, tmp_filename, entrypointp);
2106                    free(tmp_filename);
2107    
2108                    /*  Hack: Start a "boot from CDROM" sequence:  */
2109                    *entrypointp = 0x8c000080;
2110                    goto ret;
2111            }
2112    
2113            /*
2114           *  Last resort:  symbol definitions from nm (or nm -S):           *  Last resort:  symbol definitions from nm (or nm -S):
2115           *           *
2116           *  If the buf contains typical 'binary' characters, then print           *  If the buf contains typical 'binary' characters, then print
# Line 1655  void file_load(struct machine *machine, Line 2125  void file_load(struct machine *machine,
2125                              "unknown.\n\n ", filename);                              "unknown.\n\n ", filename);
2126                          for (i=0; i<(signed)sizeof(buf); i++)                          for (i=0; i<(signed)sizeof(buf); i++)
2127                                  fprintf(stderr, " %02x", buf[i]);                                  fprintf(stderr, " %02x", buf[i]);
2128    
2129                            if (len2 == 2 && buf2[0] == 0x55 && buf2[1] == 0xaa)
2130                                    fprintf(stderr, "\n\nIt has a PC-style "
2131                                        "bootsector marker.");
2132    
2133                          fprintf(stderr, "\n\nPossible explanations:\n\n"                          fprintf(stderr, "\n\nPossible explanations:\n\n"
2134                              "  o)  If this is a disk image, you forgot '-d' "                              "  o)  If this is a disk image, you forgot '-d' "
2135                              "on the command line.\n"                              "on the command line.\n"
# Line 1666  void file_load(struct machine *machine, Line 2141  void file_load(struct machine *machine,
2141    
2142  ret:  ret:
2143          debug_indentation(-iadd);          debug_indentation(-iadd);
2144            quiet_mode = old_quiet_mode;
2145  }  }
2146    

Legend:
Removed from v.4  
changed lines
  Added in v.35

  ViewVC Help
Powered by ViewVC 1.1.26