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

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

revision 2 by dpavlin, Mon Oct 8 16:17:48 2007 UTC revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: file.c,v 1.85 2005/04/06 21:28:36 debug Exp $   *  $Id: file.c,v 1.119 2005/11/19 21:00:59 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 56  Line 57 
57    
58    
59  /*  ELF machine types as strings: (same as exec_elf.h)  */  /*  ELF machine types as strings: (same as exec_elf.h)  */
60  #define N_ELF_MACHINE_TYPES     54  #define N_ELF_MACHINE_TYPES     64
61  static char *elf_machine_type[N_ELF_MACHINE_TYPES] = {  static char *elf_machine_type[N_ELF_MACHINE_TYPES] = {
62          "NONE", "M32", "SPARC", "386",                          /*  0..3  */          "NONE", "M32", "SPARC", "386",                          /*  0..3  */
63          "68K", "88K", "486", "860",                             /*  4..7  */          "68K", "88K", "486", "860",                             /*  4..7  */
# Line 71  static char *elf_machine_type[N_ELF_MACH Line 72  static char *elf_machine_type[N_ELF_MACH
72          "ARM", "ALPHA", "SH", "SPARCV9",                        /*  40..43  */          "ARM", "ALPHA", "SH", "SPARCV9",                        /*  40..43  */
73          "TRICORE", "ARC", "H8_300", "H8_300H",                  /*  44..47  */          "TRICORE", "ARC", "H8_300", "H8_300H",                  /*  44..47  */
74          "H8S", "H8_500", "IA_64", "MIPS_X",                     /*  48..51  */          "H8S", "H8_500", "IA_64", "MIPS_X",                     /*  48..51  */
75          "COLDFIRE", "68HC12"                                    /*  52..53  */          "COLDFIRE", "68HC12", "unknown54", "unknown55",         /*  52..55  */
76            "unknown56", "unknown57", "unknown58", "unknown59",     /*  56..59  */
77            "unknown60", "unknown61", "AMD64", "unknown63"          /*  60..63  */
78  };  };
79    
80    
# Line 121  struct ms_sym { Line 124  struct ms_sym {
124          }          }
125    
126    
127    #define AOUT_FLAG_DECOSF1               1
128    #define AOUT_FLAG_FROM_BEGINNING        2
129    #define AOUT_FLAG_VADDR_ZERO_HACK       4
130  /*  /*
131   *  file_load_aout():   *  file_load_aout():
132   *   *
# Line 131  struct ms_sym { Line 137  struct ms_sym {
137   *         formats, where text/data are aligned differently.   *         formats, where text/data are aligned differently.
138   */   */
139  static void file_load_aout(struct machine *m, struct memory *mem,  static void file_load_aout(struct machine *m, struct memory *mem,
140          char *filename, int osf1_hack,          char *filename, int flags,
141          uint64_t *entrypointp, int arch, int *byte_orderp)          uint64_t *entrypointp, int arch, int *byte_orderp)
142  {  {
143          struct exec aout_header;          struct exec aout_header;
# Line 141  static void file_load_aout(struct machin Line 147  static void file_load_aout(struct machin
147          uint32_t entry, datasize, textsize;          uint32_t entry, datasize, textsize;
148          int32_t symbsize = 0;          int32_t symbsize = 0;
149          uint32_t vaddr, total_len;          uint32_t vaddr, total_len;
150          unsigned char buf[4096];          unsigned char buf[65536];
151          unsigned char *syms;          unsigned char *syms;
152    
153            if (m->cpus[0]->byte_order == EMUL_BIG_ENDIAN)
154                    encoding = ELFDATA2MSB;
155    
156          f = fopen(filename, "r");          f = fopen(filename, "r");
157          if (f == NULL) {          if (f == NULL) {
158                  perror(filename);                  perror(filename);
159                  exit(1);                  exit(1);
160          }          }
161    
162          if (osf1_hack) {          if (flags & AOUT_FLAG_DECOSF1) {
163                  fread(&buf, 1, 32, f);                  fread(&buf, 1, 32, f);
164                  vaddr = buf[16] + (buf[17] << 8) +                  vaddr = buf[16] + (buf[17] << 8) +
165                      (buf[18] << 16) + (buf[19] << 24);                      (buf[18] << 16) + (buf[19] << 24);
# Line 161  static void file_load_aout(struct machin Line 170  static void file_load_aout(struct machin
170                  symbsize = 0;                  symbsize = 0;
171                  fseek(f, 0, SEEK_END);                  fseek(f, 0, SEEK_END);
172                  /*  This is of course wrong, but should work anyway:  */                  /*  This is of course wrong, but should work anyway:  */
173                  textsize = ftell(f) - 512;                  textsize = ftello(f) - 512;
174                  datasize = 0;                  datasize = 0;
175                  fseek(f, 512, SEEK_SET);                  fseek(f, 512, SEEK_SET);
176          } else {          } else {
# Line 173  static void file_load_aout(struct machin Line 182  static void file_load_aout(struct machin
182                  }                  }
183    
184                  unencode(entry, &aout_header.a_entry, uint32_t);                  unencode(entry, &aout_header.a_entry, uint32_t);
                 vaddr = entry;  
185                  debug("a.out, entry point 0x%08lx\n", (long)entry);                  debug("a.out, entry point 0x%08lx\n", (long)entry);
186                    vaddr = entry;
187    
188                    if (flags & AOUT_FLAG_VADDR_ZERO_HACK)
189                            vaddr = 0;
190    
191                  unencode(textsize, &aout_header.a_text, uint32_t);                  unencode(textsize, &aout_header.a_text, uint32_t);
192                  unencode(datasize, &aout_header.a_data, uint32_t);                  unencode(datasize, &aout_header.a_data, uint32_t);
# Line 183  static void file_load_aout(struct machin Line 195  static void file_load_aout(struct machin
195                  unencode(symbsize, &aout_header.a_syms, uint32_t);                  unencode(symbsize, &aout_header.a_syms, uint32_t);
196          }          }
197    
198            if (flags & AOUT_FLAG_FROM_BEGINNING) {
199                    fseek(f, 0, SEEK_SET);
200                    vaddr &= ~0xfff;
201            }
202    
203          /*  Load text and data:  */          /*  Load text and data:  */
204          total_len = textsize + datasize;          total_len = textsize + datasize;
205          while (total_len != 0) {          while (total_len != 0) {
# Line 190  static void file_load_aout(struct machin Line 207  static void file_load_aout(struct machin
207                  len = fread(buf, 1, len, f);                  len = fread(buf, 1, len, f);
208    
209                  /*  printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",                  /*  printf("fread len=%i vaddr=%x buf[0..]=%02x %02x %02x\n",
210                      len, (int)vaddr, buf[0], buf[1], buf[2]);  */                      (int)len, (int)vaddr, buf[0], buf[1], buf[2]);  */
211    
212                  if (len > 0)                  if (len > 0) {
213                          m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,                          int len2 = 0;
214                              &buf[0], len, MEM_WRITE, NO_EXCEPTIONS);                          uint64_t vaddr1 = vaddr &
215                  else {                              ((1 << BITS_PER_MEMBLOCK) - 1);
216                          if (osf1_hack)                          uint64_t vaddr2 = (vaddr +
217                                len) & ((1 << BITS_PER_MEMBLOCK) - 1);
218                            if (vaddr2 < vaddr1) {
219                                    len2 = len - vaddr2;
220                                    m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr,
221                                        &buf[0], len2, MEM_WRITE, NO_EXCEPTIONS);
222                            }
223                            m->cpus[0]->memory_rw(m->cpus[0], mem, vaddr + len2,
224                                &buf[len2], len-len2, MEM_WRITE, NO_EXCEPTIONS);
225                    } else {
226                            if (flags & AOUT_FLAG_DECOSF1)
227                                  break;                                  break;
228                          else {                          else {
229                                  fprintf(stderr, "could not read from %s\n",                                  fprintf(stderr, "could not read from %s\n",
# Line 217  static void file_load_aout(struct machin Line 244  static void file_load_aout(struct machin
244                  char *string_symbols;                  char *string_symbols;
245                  off_t oldpos;                  off_t oldpos;
246    
247                  debug("symbols: %i bytes @ 0x%x\n", symbsize, (int)ftell(f));                  debug("symbols: %i bytes @ 0x%x\n", symbsize, (int)ftello(f));
248                  syms = malloc(symbsize);                  syms = malloc(symbsize);
249                  if (syms == NULL) {                  if (syms == NULL) {
250                          fprintf(stderr, "out of memory\n");                          fprintf(stderr, "out of memory\n");
# Line 230  static void file_load_aout(struct machin Line 257  static void file_load_aout(struct machin
257                          exit(1);                          exit(1);
258                  }                  }
259    
260                  oldpos = ftell(f);                  oldpos = ftello(f);
261                  fseek(f, 0, SEEK_END);                  fseek(f, 0, SEEK_END);
262                  strings_len = ftell(f) - oldpos;                  strings_len = ftello(f) - oldpos;
263                  fseek(f, oldpos, SEEK_SET);                  fseek(f, oldpos, SEEK_SET);
264                  debug("strings: %i bytes @ 0x%x\n", strings_len, (int)ftell(f));                  debug("strings: %i bytes @ 0x%x\n", strings_len,(int)ftello(f));
265                  string_symbols = malloc(strings_len);                  string_symbols = malloc(strings_len);
266                  if (string_symbols == NULL) {                  if (string_symbols == NULL) {
267                          fprintf(stderr, "out of memory\n");                          fprintf(stderr, "out of memory\n");
# Line 256  static void file_load_aout(struct machin Line 283  static void file_load_aout(struct machin
283    
284                          if (type != 0 && addr != 0)                          if (type != 0 && addr != 0)
285                                  add_symbol_name(&m->symbol_context,                                  add_symbol_name(&m->symbol_context,
286                                      addr, 0, string_symbols + str_index, 0);                                      addr, 0, string_symbols + str_index, 0, -1);
287                          i++;                          i++;
288                  }                  }
289    
# Line 266  static void file_load_aout(struct machin Line 293  static void file_load_aout(struct machin
293    
294          fclose(f);          fclose(f);
295    
296            *entrypointp = (int32_t)entry;
297    
298            if (encoding == ELFDATA2LSB)
299                    *byte_orderp = EMUL_LITTLE_ENDIAN;
300            else
301                    *byte_orderp = EMUL_BIG_ENDIAN;
302    
303            n_executables_loaded ++;
304    }
305    
306    
307    /*
308     *  file_load_macho():
309     *
310     *  Loads a Mach-O binary image into the emulated memory. The entry point
311     *  is stored in the specified CPU's registers.
312     *
313     *  TODO:
314     *
315     *      o)  Almost everything.
316     *
317     *      o)  I haven't had time to look into whether Apple's open source
318     *          license is BSD-compatible or not. Perhaps it would be possible
319     *          to use a header file containing symbolic names, and not use
320     *          hardcoded values.
321     */
322    static void file_load_macho(struct machine *m, struct memory *mem,
323            char *filename, uint64_t *entrypointp, int arch, int *byte_orderp,
324            int is_64bit, int is_reversed)
325    {
326            FILE *f;
327            uint64_t entry = 0;
328            int entry_set = 0;
329            int encoding = ELFDATA2MSB;
330            unsigned char buf[65536];
331            char *symbols, *strings;
332            uint32_t cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags;
333            uint64_t vmaddr, vmsize, fileoff, filesize;
334            int cmd_type, cmd_len, pos, i, flavor;
335            int32_t symoff, nsyms, stroff, strsize;
336            size_t len;
337    
338            if (m->cpus[0]->byte_order == EMUL_BIG_ENDIAN)
339                    encoding = ELFDATA2MSB;
340    
341            f = fopen(filename, "r");
342            if (f == NULL) {
343                    perror(filename);
344                    exit(1);
345            }
346    
347            if (is_64bit) {
348                    fatal("TODO: 64-bit Mach-O. Not supported yet.\n");
349                    exit(1);
350            }
351            if (is_reversed) {
352                    fatal("TODO: Reversed-endianness. Not supported yet.\n");
353                    exit(1);
354            }
355    
356            len = fread(buf, 1, sizeof(buf), f);
357            if (len < 100) {
358                    fatal("Bad Mach-O file?\n");
359                    exit(1);
360            }
361    
362            unencode(cputype,    &buf[4], uint32_t);
363            unencode(cpusubtype, &buf[8], uint32_t);
364            unencode(filetype,   &buf[12], uint32_t);
365            unencode(ncmds,      &buf[16], uint32_t);
366            unencode(sizeofcmds, &buf[20], uint32_t);
367            unencode(flags,      &buf[24], uint32_t);
368    
369            /*  debug("cputype=0x%x cpusubtype=0x%x filetype=0x%x\n",
370                cputype, cpusubtype, filetype);
371                debug("ncmds=%i sizeofcmds=0x%08x flags=0x%08x\n",
372                ncmds, sizeofcmds, flags);  */
373    
374            /*
375             *  Compare to "normal" values.
376             *  NOTE/TODO: These were for a Darwin (Macintosh PPC) kernel.
377             */
378            if (cputype != 0x12) {
379                    fatal("Error: Unimplemented cputype 0x%x\n", cputype);
380                    exit(1);
381            }
382            if (cpusubtype != 0) {
383                    fatal("Error: Unimplemented cpusubtype 0x%x\n", cpusubtype);
384                    exit(1);
385            }
386            /*  Filetype 2 means an executable image.  */
387            if (filetype != 2) {
388                    fatal("Error: Unimplemented filetype 0x%x\n", filetype);
389                    exit(1);
390            }
391            if (!(flags & 1)) {
392                    fatal("Error: File has 'undefined references'. Cannot"
393                        " be executed.\n", flags);
394                    exit(1);
395            }
396    
397            /*  I've only encountered flags == 1 so far.  */
398            if (flags != 1) {
399                    fatal("Error: Unimplemented flags 0x%x\n", flags);
400                    exit(1);
401            }
402    
403            /*
404             *  Read all load commands:
405             */
406            pos = is_64bit? 32 : 28;
407            cmd_type = 0;
408            do {
409                    /*  Read command type and length:  */
410                    unencode(cmd_type, &buf[pos], uint32_t);
411                    unencode(cmd_len,  &buf[pos+4], uint32_t);
412    
413    #if 0
414                    debug("cmd %i, len=%i\n", cmd_type, cmd_len);
415                    for (i=8; i<cmd_len; i++) {
416                            unsigned char ch = buf[pos+i];
417                            if (ch >= ' ' && ch < 127)
418                                    debug("%c", ch);
419                            else
420                                    debug(".");
421                    }
422    #endif
423                    switch (cmd_type) {
424                    case 1: /*  LC_SEGMENT  */
425                            debug("seg ");
426                            for (i=0; i<16; i++) {
427                                    if (buf[pos + 8 + i] == 0)
428                                            break;
429                                    debug("%c", buf[pos + 8 + i]);
430                            }
431                            unencode(vmaddr,   &buf[pos+8+16+0], uint32_t);
432                            unencode(vmsize,   &buf[pos+8+16+4], uint32_t);
433                            unencode(fileoff,  &buf[pos+8+16+8], uint32_t);
434                            unencode(filesize, &buf[pos+8+16+12], uint32_t);
435                            debug(": vmaddr=0x%x size=0x%x fileoff=0x%x",
436                                (int)vmaddr, (int)vmsize, (int)fileoff);
437    
438                            if (filesize == 0) {
439                                    debug("\n");
440                                    break;
441                            }
442    
443                            fseek(f, fileoff, SEEK_SET);
444    
445                            /*  Load data from the file:  */
446                            while (filesize != 0) {
447                                    unsigned char buf[32768];
448                                    ssize_t len = filesize > sizeof(buf) ?
449                                        sizeof(buf) : filesize;
450                                    len = fread(buf, 1, len, f);
451    
452                                    /*  printf("fread len=%i vmaddr=%x buf[0..]="
453                                        "%02x %02x %02x\n", (int)len, (int)vmaddr,
454                                        buf[0], buf[1], buf[2]);  */
455    
456                                    if (len > 0) {
457                                            int len2 = 0;
458                                            uint64_t vaddr1 = vmaddr &
459                                                ((1 << BITS_PER_MEMBLOCK) - 1);
460                                            uint64_t vaddr2 = (vmaddr +
461                                                len) & ((1 << BITS_PER_MEMBLOCK)-1);
462                                            if (vaddr2 < vaddr1) {
463                                                    len2 = len - vaddr2;
464                                                    m->cpus[0]->memory_rw(m->cpus[
465                                                        0], mem, vmaddr, &buf[0],
466                                                        len2, MEM_WRITE,
467                                                        NO_EXCEPTIONS);
468                                            }
469                                            m->cpus[0]->memory_rw(m->cpus[0], mem,
470                                                vmaddr + len2, &buf[len2], len-len2,
471                                                MEM_WRITE, NO_EXCEPTIONS);
472                                    } else {
473                                            fprintf(stderr, "error reading\n");
474                                            exit(1);
475                                    }
476    
477                                    vmaddr += len;
478                                    filesize -= len;
479                            }
480    
481                            debug("\n");
482                            break;
483    
484                    case 2: /*  LC_SYMTAB  */
485                            unencode(symoff,  &buf[pos+8], uint32_t);
486                            unencode(nsyms,   &buf[pos+12], uint32_t);
487                            unencode(stroff,  &buf[pos+16], uint32_t);
488                            unencode(strsize, &buf[pos+20], uint32_t);
489                            debug("symtable: %i symbols @ 0x%x (strings at "
490                                "0x%x)\n", nsyms, symoff, stroff);
491    
492                            symbols = malloc(12 * nsyms);
493                            if (symbols == NULL) {
494                                    fprintf(stderr, "out of memory\n");
495                                    exit(1);
496                            }
497                            fseek(f, symoff, SEEK_SET);
498                            fread(symbols, 1, 12 * nsyms, f);
499    
500                            strings = malloc(strsize);
501                            if (strings == NULL) {
502                                    fprintf(stderr, "out of memory\n");
503                                    exit(1);
504                            }
505                            fseek(f, stroff, SEEK_SET);
506                            fread(strings, 1, strsize, f);
507    
508                            for (i=0; i<nsyms; i++) {
509                                    int n_strx, n_type, n_sect, n_desc;
510                                    uint32_t n_value;
511                                    unencode(n_strx,  &symbols[i*12+0], int32_t);
512                                    unencode(n_type,  &symbols[i*12+4], uint8_t);
513                                    unencode(n_sect,  &symbols[i*12+5], uint8_t);
514                                    unencode(n_desc,  &symbols[i*12+6], int16_t);
515                                    unencode(n_value, &symbols[i*12+8], uint32_t);
516                                    /*  debug("%i: strx=%i type=%i sect=%i desc=%i"
517                                        " value=0x%x\n", i, n_strx, n_type,
518                                        n_sect, n_desc, n_value);  */
519                                    add_symbol_name(&m->symbol_context,
520                                        n_value, 0, strings + n_strx, 0, -1);
521                            }
522    
523                            free(symbols);
524                            free(strings);
525                            break;
526    
527                    case 5: debug("unix thread context: ");
528                            /*  See http://cvs.sf.net/viewcvs.py/hte/
529                                HT%20Editor/machostruc.h or similar for details
530                                on the thread struct.  */
531                            unencode(flavor, &buf[pos+8], uint32_t);
532                            if (flavor != 1) {
533                                    fatal("unimplemented flavor %i\n", flavor);
534                                    exit(1);
535                            }
536    
537                            if (arch != ARCH_PPC) {
538                                    fatal("non-PPC arch? TODO\n");
539                                    exit(1);
540                            }
541    
542                            unencode(entry, &buf[pos+16], uint32_t);
543                            entry_set = 1;
544                            debug("pc=0x%x\n", (int)entry);
545    
546                            for (i=1; i<40; i++) {
547                                    uint32_t x;
548                                    unencode(x, &buf[pos+16+i*4], uint32_t);
549                                    if (x != 0) {
550                                            fatal("Entry nr %i in the Mach-O"
551                                                " thread struct is non-zero"
552                                                " (0x%x). This is not supported"
553                                                " yet. TODO\n", i, x);
554                                            exit(1);
555                                    }
556                            }
557                            break;
558    
559                    default:fatal("WARNING! Unimplemented load command %i!\n",
560                                cmd_type);
561                    }
562    
563                    pos += cmd_len;
564            } while (pos < sizeofcmds && cmd_type != 0);
565    
566            fclose(f);
567    
568            if (!entry_set) {
569                    fatal("No entry point? Aborting.\n");
570                    exit(1);
571            }
572    
573          *entrypointp = entry;          *entrypointp = entry;
574    
575          if (encoding == ELFDATA2LSB)          if (encoding == ELFDATA2LSB)
# Line 465  static void file_load_ecoff(struct machi Line 769  static void file_load_ecoff(struct machi
769                  if (s_scnptr != 0 && s_size != 0 &&                  if (s_scnptr != 0 && s_size != 0 &&
770                      s_vaddr != 0 && !(s_flags & 0x02)) {                      s_vaddr != 0 && !(s_flags & 0x02)) {
771                          /*  Remember the current file offset:  */                          /*  Remember the current file offset:  */
772                          oldpos = ftell(f);                          oldpos = ftello(f);
773    
774                          /*  Load the section into emulated memory:  */                          /*  Load the section into emulated memory:  */
775                          fseek(f, s_scnptr, SEEK_SET);                          fseek(f, s_scnptr, SEEK_SET);
# Line 566  static void file_load_ecoff(struct machi Line 870  static void file_load_ecoff(struct machi
870                                          memcpy(name, sym->name, 8);                                          memcpy(name, sym->name, 8);
871                                          name[8] = '\0';                                          name[8] = '\0';
872                                          add_symbol_name(&m->symbol_context,                                          add_symbol_name(&m->symbol_context,
873                                              v, 0, name, 0);                                              v, 0, name, 0, -1);
874                                          n_real_symbols ++;                                          n_real_symbols ++;
875                                  } else if (t == 0x20 && !sym->name[0]) {                                  } else if (t == 0x20 && !sym->name[0]) {
876                                          off_t ofs;                                          off_t ofs;
# Line 578  static void file_load_ecoff(struct machi Line 882  static void file_load_ecoff(struct machi
882                                          /*  debug(" [altname=0x%x '%s']",                                          /*  debug(" [altname=0x%x '%s']",
883                                              altname, name);  */                                              altname, name);  */
884                                          add_symbol_name(&m->symbol_context,                                          add_symbol_name(&m->symbol_context,
885                                              v, 0, name, 0);                                              v, 0, name, 0, -1);
886                                          n_real_symbols ++;                                          n_real_symbols ++;
887                                  }                                  }
888    
# Line 649  static void file_load_ecoff(struct machi Line 953  static void file_load_ecoff(struct machi
953    
954                          add_symbol_name(&m->symbol_context,                          add_symbol_name(&m->symbol_context,
955                              extsyms[sym_nr].es_value, 0,                              extsyms[sym_nr].es_value, 0,
956                              symbol_data + extsyms[sym_nr].es_strindex, 0);                              symbol_data + extsyms[sym_nr].es_strindex, 0, -1);
957                  }                  }
958    
959                  free(extsyms);                  free(extsyms);
# Line 891  static void file_load_raw(struct machine Line 1195  static void file_load_raw(struct machine
1195          }          }
1196    
1197          debug("RAW: 0x%llx bytes @ 0x%08llx",          debug("RAW: 0x%llx bytes @ 0x%08llx",
1198              (long long) (ftell(f) - skip), (long long)loadaddr);              (long long) (ftello(f) - skip), (long long)loadaddr);
1199          if (skip != 0)          if (skip != 0)
1200                  debug(" (0x%llx bytes of header skipped)", (long long)skip);                  debug(" (0x%llx bytes of header skipped)", (long long)skip);
1201          debug("\n");          debug("\n");
# Line 997  static void file_load_elf(struct machine Line 1301  static void file_load_elf(struct machine
1301                  unencode(eshoff,     &hdr64.e_shoff,     Elf64_Off);                  unencode(eshoff,     &hdr64.e_shoff,     Elf64_Off);
1302                  if (ephentsize != sizeof(Elf64_Phdr)) {                  if (ephentsize != sizeof(Elf64_Phdr)) {
1303                          fprintf(stderr, "%s: incorrect phentsize? %i, should "                          fprintf(stderr, "%s: incorrect phentsize? %i, should "
1304                              "be %i\n", filename, (int)ephentsize,                              "be %i\nPerhaps this is a dynamically linked "
1305                              (int)sizeof(Elf64_Phdr));                              "binary (which isn't supported yet).\n", filename,
1306                                (int)ephentsize, (int)sizeof(Elf64_Phdr));
1307                          exit(1);                          exit(1);
1308                  }                  }
1309                  if (eshentsize != sizeof(Elf64_Shdr)) {                  if (eshentsize != sizeof(Elf64_Shdr)) {
1310                          fprintf(stderr, "%s: incorrect phentsize? %i, should "                          fprintf(stderr, "%s: incorrect shentsize? %i, should "
1311                              "be %i\n", filename, (int)ephentsize,                              "be %i\nPerhaps this is a dynamically linked "
1312                              (int)sizeof(Elf64_Shdr));                              "binary (which isn't supported yet).\n", filename,
1313                                (int)eshentsize, (int)sizeof(Elf64_Shdr));
1314                          exit(1);                          exit(1);
1315                  }                  }
1316          } else {          } else {
# Line 1020  static void file_load_elf(struct machine Line 1326  static void file_load_elf(struct machine
1326                  unencode(eshoff,     &hdr32.e_shoff,     Elf32_Off);                  unencode(eshoff,     &hdr32.e_shoff,     Elf32_Off);
1327                  if (ephentsize != sizeof(Elf32_Phdr)) {                  if (ephentsize != sizeof(Elf32_Phdr)) {
1328                          fprintf(stderr, "%s: incorrect phentsize? %i, should "                          fprintf(stderr, "%s: incorrect phentsize? %i, should "
1329                              "be %i\n", filename, (int)ephentsize,                              "be %i\nPerhaps this is a dynamically linked "
1330                              (int)sizeof(Elf32_Phdr));                              "binary (which isn't supported yet).\n", filename,
1331                                (int)ephentsize, (int)sizeof(Elf32_Phdr));
1332                          exit(1);                          exit(1);
1333                  }                  }
1334                  if (eshentsize != sizeof(Elf32_Shdr)) {                  if (eshentsize != sizeof(Elf32_Shdr)) {
1335                          fprintf(stderr, "%s: incorrect phentsize? %i, should "                          fprintf(stderr, "%s: incorrect shentsize? %i, should "
1336                              "be %i\n", filename, (int)ephentsize,                              "be %i\nPerhaps this is a dynamically linked "
1337                              (int)sizeof(Elf32_Shdr));                              "binary (which isn't supported yet).\n", filename,
1338                                (int)eshentsize, (int)sizeof(Elf32_Shdr));
1339                          exit(1);                          exit(1);
1340                  }                  }
1341          }          }
# Line 1040  static void file_load_elf(struct machine Line 1348  static void file_load_elf(struct machine
1348    
1349          ok = 0;          ok = 0;
1350          switch (arch) {          switch (arch) {
1351            case ARCH_ALPHA:
1352                    switch (emachine) {
1353                    case EM_ALPHA:
1354                    case -28634:
1355                            ok = 1;
1356                    }
1357                    break;
1358            case ARCH_ARM:
1359                    switch (emachine) {
1360                    case EM_ARM:
1361                            ok = 1;
1362                    }
1363                    break;
1364            case ARCH_AVR:
1365                    switch (emachine) {
1366                    case EM_AVR:
1367                            ok = 1;
1368                    }
1369                    break;
1370            case ARCH_HPPA:
1371                    switch (emachine) {
1372                    case EM_PARISC:
1373                            ok = 1;
1374                    }
1375                    break;
1376            case ARCH_I960:
1377                    switch (emachine) {
1378                    case EM_960:
1379                            ok = 1;
1380                    }
1381                    break;
1382            case ARCH_IA64:
1383                    switch (emachine) {
1384                    case EM_IA_64:
1385                            ok = 1;
1386                    }
1387                    break;
1388            case ARCH_M68K:
1389                    switch (emachine) {
1390                    case EM_68K:
1391                            ok = 1;
1392                    }
1393                    break;
1394          case ARCH_MIPS:          case ARCH_MIPS:
1395            case ARCH_NEWMIPS:
1396                  switch (emachine) {                  switch (emachine) {
1397                  case EM_MIPS:                  case EM_MIPS:
1398                  case EM_MIPS_RS3_LE:                  case EM_MIPS_RS3_LE:
# Line 1054  static void file_load_elf(struct machine Line 1406  static void file_load_elf(struct machine
1406                          ok = 1;                          ok = 1;
1407                  }                  }
1408                  break;                  break;
1409          case ARCH_SPARC:          case ARCH_SH:
1410                  switch (emachine) {                  switch (emachine) {
1411                  case EM_SPARC:                  case EM_SH:
                 case EM_SPARCV9:  
1412                          ok = 1;                          ok = 1;
1413                  }                  }
1414                  break;                  break;
1415          case ARCH_HPPA:          case ARCH_SPARC:
1416                  switch (emachine) {                  switch (emachine) {
1417                  case EM_PARISC:                  case EM_SPARC:
1418                    case EM_SPARCV9:
1419                          ok = 1;                          ok = 1;
1420                  }                  }
1421                  break;                  break;
1422          case ARCH_ALPHA:          case ARCH_X86:
1423                  switch (emachine) {                  switch (emachine) {
1424                  case EM_ALPHA:                  case EM_386:
1425                  case -28634:                  case EM_486:
1426                            *tocp = 1;
1427                            ok = 1;
1428                            break;
1429                    case EM_AMD64:
1430                            *tocp = 2;
1431                          ok = 1;                          ok = 1;
1432                            break;
1433                  }                  }
1434                  break;                  break;
1435          default:          default:
# Line 1105  static void file_load_elf(struct machine Line 1463  static void file_load_elf(struct machine
1463           *  TODO:  Find out what e_flag actually contains.           *  TODO:  Find out what e_flag actually contains.
1464           *  TODO 2: This only sets mips16 for cpu 0. Yuck. Fix this!           *  TODO 2: This only sets mips16 for cpu 0. Yuck. Fix this!
1465           */           */
1466            if ((arch == ARCH_MIPS || arch == ARCH_NEWMIPS)
1467          if (((eflags >> 24) & 0xff) == 0x24) {              && ((eflags >> 24) & 0xff) == 0x24) {
1468                  debug("MIPS16 encoding (e_flags = 0x%08x)\n", eflags);                  debug("MIPS16 encoding (e_flags = 0x%08x)\n", eflags);
1469  #ifdef ENABLE_MIPS16  #ifdef ENABLE_MIPS16
1470                  m->cpus[0]->cd.mips.mips16 = 1;                  m->cpus[0]->cd.mips.mips16 = 1;
# Line 1115  static void file_load_elf(struct machine Line 1473  static void file_load_elf(struct machine
1473                      "(or use the --mips16 configure option)\n");                      "(or use the --mips16 configure option)\n");
1474                  exit(1);                  exit(1);
1475  #endif  #endif
1476          } else if (eentry & 0x3) {          } else if ((arch == ARCH_MIPS || arch == ARCH_NEWMIPS)
1477                        && (eentry & 0x3)) {
1478                  debug("MIPS16 encoding (eentry not 32-bit aligned)\n");                  debug("MIPS16 encoding (eentry not 32-bit aligned)\n");
1479  #ifdef ENABLE_MIPS16  #ifdef ENABLE_MIPS16
1480                  m->cpus[0]->cd.mips.mips16 = 1;                  m->cpus[0]->cd.mips.mips16 = 1;
# Line 1126  static void file_load_elf(struct machine Line 1485  static void file_load_elf(struct machine
1485  #endif  #endif
1486          }          }
1487    
1488            /*
1489             *  SH64: 32-bit instruction encoding?  TODO
1490             */
1491            if (arch == ARCH_SH && (eentry & 1)) {
1492                    debug("SH64: 32-bit instruction encoding\n");
1493                    m->cpus[0]->cd.sh.compact = 0;
1494                    m->cpus[0]->cd.sh.bits = 64;
1495            }
1496    
1497          /*  Read the program headers:  */          /*  Read the program headers:  */
1498    
1499          for (i=0; i<ephnum; i++) {          for (i=0; i<ephnum; i++) {
# Line 1162  static void file_load_elf(struct machine Line 1530  static void file_load_elf(struct machine
1530                          unencode(p_align,   &phdr32.p_align,   Elf32_Word);                          unencode(p_align,   &phdr32.p_align,   Elf32_Word);
1531                  }                  }
1532    
1533                    /*
1534                     *  Hack for loading Linux/PPC kernels, linked to high
1535                     *  addresses, at low addresses.
1536                     */
1537                    if (arch == ARCH_PPC) {
1538                            if (elf64) {
1539                                    p_vaddr &= 0x0fffffffffffffffULL;
1540                                    p_paddr &= 0x0fffffffffffffffULL;
1541                            } else {
1542                                    p_vaddr &= 0x0fffffff;
1543                                    p_paddr &= 0x0fffffff;
1544                            }
1545                    }
1546    
1547                  if (p_memsz != 0 && (p_type == PT_LOAD ||                  if (p_memsz != 0 && (p_type == PT_LOAD ||
1548                      (p_type & PF_MASKPROC) == PT_MIPS_REGINFO)) {                      (p_type & PF_MASKPROC) == PT_MIPS_REGINFO)) {
1549                          debug("chunk %i (", i);                          debug("chunk %i (", i);
# Line 1179  static void file_load_elf(struct machine Line 1561  static void file_load_elf(struct machine
1561    
1562                          debug(" len=0x%llx\n", (long long)p_memsz);                          debug(" len=0x%llx\n", (long long)p_memsz);
1563    
1564                          if (p_vaddr != p_paddr) {                          if (p_vaddr != p_paddr)
1565                                  fprintf(stderr, "%s: vaddr != paddr. TODO: "                                  fatal("WARNING! vaddr (0x%llx) and paddr "
1566                                      "how to handle this? vaddr=%016llx paddr"                                      "(0x%llx) differ; using vaddr\n",
1567                                      "=%016llx\n", filename, (long long)p_vaddr,                                      (long long)p_vaddr, (long long)p_paddr);
                                     (long long)p_paddr);  
                                 exit(1);  
                         }  
1568    
1569                          if (p_memsz < p_filesz) {                          if (p_memsz < p_filesz) {
1570                                  fprintf(stderr, "%s: memsz < filesz. TODO: how"                                  fprintf(stderr, "%s: memsz < filesz. TODO: how"
# Line 1248  static void file_load_elf(struct machine Line 1627  static void file_load_elf(struct machine
1627                  }                  }
1628          }          }
1629    
1630          /*  Read the section headers to find the address of the _gp symbol:  */          /*
1631             *  Read the section headers to find the address of the _gp
1632             *  symbol (for MIPS):
1633             */
1634    
1635          for (i=0; i<eshnum; i++) {          for (i=0; i<eshnum; i++) {
1636                  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 1402  static void file_load_elf(struct machine Line 1784  static void file_load_elf(struct machine
1784                          } else {                          } else {
1785                                  sym32 = symbols_sym32[i];                                  sym32 = symbols_sym32[i];
1786                                  unencode(st_name, &sym32.st_name,  Elf32_Word);                                  unencode(st_name, &sym32.st_name,  Elf32_Word);
1787                                  unencode(st_info, &sym64.st_info,  Elf_Byte);                                  unencode(st_info, &sym32.st_info,  Elf_Byte);
1788                                  unencode(addr,    &sym32.st_value, Elf32_Word);                                  unencode(addr,    &sym32.st_value, Elf32_Word);
1789                                  unencode(size,    &sym32.st_size, Elf32_Word);                                  unencode(size,    &sym32.st_size, Elf32_Word);
1790                          }                          }
1791    
1792                            /*  debug("symbol info=0x%02x addr=0x%016llx"
1793                                " (%i) '%s'\n", st_info, (long long)addr,
1794                                st_name, symbol_strings + st_name);  */
1795    
1796                          if (size == 0)                          if (size == 0)
1797                                  size ++;                                  size ++;
1798    
1799                          if (addr != 0) {                          if (addr != 0) /* && ((st_info >> 4) & 0xf)
1800                                >= STB_GLOBAL) */ {
1801                                  /*  debug("symbol info=0x%02x addr=0x%016llx"                                  /*  debug("symbol info=0x%02x addr=0x%016llx"
1802                                      " '%s'\n", st_info, (long long)addr,                                      " '%s'\n", st_info, (long long)addr,
1803                                      symbol_strings + st_name);  */                                      symbol_strings + st_name);  */
1804                                  add_symbol_name(&m->symbol_context,                                  add_symbol_name(&m->symbol_context,
1805                                      addr, size, symbol_strings + st_name, 0);                                      addr, size, symbol_strings + st_name,
1806                                        0, -1);
1807                          }                          }
1808    
1809                          if (strcmp(symbol_strings + st_name, "_gp") == 0) {                          if (strcmp(symbol_strings + st_name, "_gp") == 0) {
# Line 1514  void file_load(struct machine *machine, Line 1902  void file_load(struct machine *machine,
1902          int iadd = 4;          int iadd = 4;
1903          FILE *f;          FILE *f;
1904          unsigned char buf[12];          unsigned char buf[12];
1905          int len, i;          unsigned char buf2[2];
1906            size_t len, len2, i;
1907          off_t size;          off_t size;
1908    
1909          if (byte_orderp == NULL) {          if (byte_orderp == NULL) {
# Line 1546  void file_load(struct machine *machine, Line 1935  void file_load(struct machine *machine,
1935          }          }
1936    
1937          fseek(f, 0, SEEK_END);          fseek(f, 0, SEEK_END);
1938          size = ftell(f);          size = ftello(f);
1939          fseek(f, 0, SEEK_SET);          fseek(f, 0, SEEK_SET);
1940    
1941          memset(buf, 0, sizeof(buf));          memset(buf, 0, sizeof(buf));
1942          len = fread(buf, 1, sizeof(buf), f);          len = fread(buf, 1, sizeof(buf), f);
1943            fseek(f, 510, SEEK_SET);
1944            len2 = fread(buf2, 1, sizeof(buf2), f);
1945          fclose(f);          fclose(f);
1946    
1947          if (len < (signed int)sizeof(buf)) {          if (len < (signed int)sizeof(buf)) {
# Line 1566  void file_load(struct machine *machine, Line 1957  void file_load(struct machine *machine,
1957                  goto ret;                  goto ret;
1958          }          }
1959    
1960          /*  Is it an a.out?  (Special case for DEC OSF1 kernels.)  */          /*  Is it an a.out?  */
1961          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) {
1962                    /*  MIPS a.out  */
1963                  file_load_aout(machine, mem, filename, 0,                  file_load_aout(machine, mem, filename, 0,
1964                      entrypointp, arch, byte_orderp);                      entrypointp, arch, byte_orderp);
1965                  goto ret;                  goto ret;
1966          }          }
1967            if (buf[0]==0x00 && buf[1]==0x87 && buf[2]==0x01 && buf[3]==0x08) {
1968                    /*  M68K a.out  */
1969                    file_load_aout(machine, mem, filename,
1970                        AOUT_FLAG_VADDR_ZERO_HACK  /*  for OpenBSD/mac68k  */,
1971                        entrypointp, arch, byte_orderp);
1972                    goto ret;
1973            }
1974            if (buf[0]==0x00 && buf[1]==0x8f && buf[2]==0x01 && buf[3]==0x0b) {
1975                    /*  ARM a.out  */
1976                    file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING,
1977                        entrypointp, arch, byte_orderp);
1978                    goto ret;
1979            }
1980            if (buf[0]==0x00 && buf[1]==0x86 && buf[2]==0x01 && buf[3]==0x0b) {
1981                    /*  i386 a.out (old OpenBSD and NetBSD etc)  */
1982                    file_load_aout(machine, mem, filename, AOUT_FLAG_FROM_BEGINNING,
1983                        entrypointp, arch, byte_orderp);
1984                    goto ret;
1985            }
1986          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) {
1987                  file_load_aout(machine, mem, filename, 1,                  /*  DEC OSF1 on MIPS:  */
1988                    file_load_aout(machine, mem, filename, AOUT_FLAG_DECOSF1,
1989                      entrypointp, arch, byte_orderp);                      entrypointp, arch, byte_orderp);
1990                  goto ret;                  goto ret;
1991          }          }
1992    
1993          /*          /*
1994             *  Is it a Mach-O file?
1995             */
1996            if (buf[0] == 0xfe && buf[1] == 0xed && buf[2] == 0xfa &&
1997                (buf[3] == 0xce || buf[3] == 0xcf)) {
1998                    file_load_macho(machine, mem, filename, entrypointp,
1999                        arch, byte_orderp, buf[3] == 0xcf, 0);
2000                    goto ret;
2001            }
2002            if ((buf[0] == 0xce || buf[0] == 0xcf) && buf[1] == 0xfa &&
2003                buf[2] == 0xed && buf[3] == 0xfe) {
2004                    file_load_macho(machine, mem, filename, entrypointp,
2005                        arch, byte_orderp, buf[0] == 0xcf, 1);
2006                    goto ret;
2007            }
2008    
2009            /*
2010           *  Is it an ecoff?           *  Is it an ecoff?
2011           *           *
2012           *  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 1618  void file_load(struct machine *machine, Line 2046  void file_load(struct machine *machine,
2046                  fprintf(stderr, "\nThis file is very large (%lli bytes)\n",                  fprintf(stderr, "\nThis file is very large (%lli bytes)\n",
2047                      (long long)size);                      (long long)size);
2048                  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 "
2049                      "image?\n");                      "image? (Use the -d option.)\n");
2050                  exit(1);                  exit(1);
2051          }          }
2052    
2053            if (size == 1474560)
2054                    fprintf(stderr, "Hm... this file is the size of a 1.44 MB "
2055                        "floppy image. Maybe you forgot the\n-d switch?\n");
2056    
2057          /*          /*
2058           *  Last resort:  symbol definitions from nm (or nm -S):           *  Last resort:  symbol definitions from nm (or nm -S):
2059           *           *
# Line 1637  void file_load(struct machine *machine, Line 2069  void file_load(struct machine *machine,
2069                              "unknown.\n\n ", filename);                              "unknown.\n\n ", filename);
2070                          for (i=0; i<(signed)sizeof(buf); i++)                          for (i=0; i<(signed)sizeof(buf); i++)
2071                                  fprintf(stderr, " %02x", buf[i]);                                  fprintf(stderr, " %02x", buf[i]);
2072    
2073                            if (len2 == 2 && buf2[0] == 0x55 && buf2[1] == 0xaa)
2074                                    fprintf(stderr, "\n\nIt has a PC-style "
2075                                        "bootsector marker.");
2076    
2077                          fprintf(stderr, "\n\nPossible explanations:\n\n"                          fprintf(stderr, "\n\nPossible explanations:\n\n"
2078                              "  o)  If this is a disk image, you forgot '-d' "                              "  o)  If this is a disk image, you forgot '-d' "
2079                              "on the command line.\n"                              "on the command line.\n"

Legend:
Removed from v.2  
changed lines
  Added in v.20

  ViewVC Help
Powered by ViewVC 1.1.26