/[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 22 by dpavlin, Mon Oct 8 16:19:37 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-2006  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.127 2006/01/22 23:20:33 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 are:   *  memory. File formats recognized so far are:
# Line 61  extern int verbose; Line 61  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 78  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 1158  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 1186  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 1196  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 1205  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) (ftello(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 1378  static void file_load_elf(struct machine Line 1405  static void file_load_elf(struct machine
1405                          ok = 1;                          ok = 1;
1406                  }                  }
1407                  break;                  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:
# Line 1395  static void file_load_elf(struct machine Line 1428  static void file_load_elf(struct machine
1428                  case EM_IA_64:                  case EM_IA_64:
1429                          ok = 1;                          ok = 1;
1430                  }                  }
1431                  break;                  break;  */
1432          case ARCH_M68K:          case ARCH_M68K:
1433                  switch (emachine) {                  switch (emachine) {
1434                  case EM_68K:                  case EM_68K:
# Line 1429  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:
# Line 1441  static void file_load_elf(struct machine Line 1474  static void file_load_elf(struct machine
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 1463  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);
   
         /*  
          *  MIPS16 encoding?  
          *  
          *  TODO:  Find out what e_flag actually contains.  
          *  TODO 2: This only sets mips16 for cpu 0. Yuck. Fix this!  
          */  
         if (arch == ARCH_MIPS && ((eflags >> 24) & 0xff) == 0x24) {  
                 debug("MIPS16 encoding (e_flags = 0x%08x)\n", eflags);  
 #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  
         } else if (arch == ARCH_MIPS && (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  
         }  
1502    
1503          /*          /*
1504           *  SH64: 32-bit instruction encoding?  TODO           *  SH64: 32-bit instruction encoding?
1505           */           */
1506          if (arch == ARCH_SH && (eentry & 1)) {          if (arch == ARCH_SH && (eentry & 1)) {
1507                  debug("SH64: 32-bit instruction encoding\n");                  debug("SH64: 32-bit instruction encoding\n");
1508                  m->cpus[0]->cd.sh.compact = 0;                  m->cpus[0]->cd.sh.compact = 0;
1509                  m->cpus[0]->cd.sh.bits = 64;                  m->cpus[0]->cd.sh.cpu_type.bits = 64;
1510          }          }
1511    
1512          /*  Read the program headers:  */          /*  Read the program headers:  */
# Line 1539  static void file_load_elf(struct machine Line 1546  static void file_load_elf(struct machine
1546                  }                  }
1547    
1548                  /*                  /*
1549                   *  Hack for loading Linux/PPC kernels, linked to high                   *  Hack for loading PPC kernels that are linked to high
1550                   *  addresses, at low addresses.                   *  addresses. (This requires enabling of instruction and
1551                     *  data virtual address translation.)
1552                   */                   */
1553                  if (arch == ARCH_PPC) {                  if (arch == ARCH_PPC) {
1554                          if (elf64) {                          if ( (elf64 && (p_vaddr >> 60) != 0) ||
1555                                  p_vaddr &= 0x0fffffffffffffffULL;                              (!elf64 && (p_vaddr >> 28) != 0) )
1556                                  p_paddr &= 0x0fffffffffffffffULL;                                  m->cpus[m->bootstrap_cpu]->
1557                          } else {                                      cd.ppc.msr |= PPC_MSR_IR | PPC_MSR_DR;
                                 p_vaddr &= 0x0fffffff;  
                                 p_paddr &= 0x0fffffff;  
                         }  
1558                  }                  }
1559    
1560                  if (p_memsz != 0 && (p_type == PT_LOAD ||                  if (p_memsz != 0 && (p_type == PT_LOAD ||
# Line 1558  static void file_load_elf(struct machine Line 1563  static void file_load_elf(struct machine
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                                  if (elf64)                                  if (elf64)
1579                                          fatal("NOTE: vaddr (0x%llx) and "                                          debug("NOTE: vaddr (0x%"PRIx64") and "
1580                                              "paddr (0x%llx) differ; using "                                              "paddr (0x%"PRIx64") differ; using "
1581                                              "vaddr\n", (long long)p_vaddr,                                              "vaddr\n", (uint64_t) p_vaddr,
1582                                              (long long)p_paddr);                                              (uint64_t) p_paddr);
1583                                  else                                  else
1584                                          fatal("NOTE: vaddr (0x%08x) and "                                          debug("NOTE: vaddr (0x%08"PRIx32") and "
1585                                              "paddr (0x%08x) differ; using vaddr"                                              "paddr (0x%08"PRIx32") differ; usin"
1586                                              "\n", (int)p_vaddr, (int)p_paddr);                                              "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 1653  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 1740  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 1774  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 1804  static void file_load_elf(struct machine Line 1810  static void file_load_elf(struct machine
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%016llx"                          /*  debug("symbol info=0x%02x addr=0x%016"PRIx64
1814                              " (%i) '%s'\n", st_info, (long long)addr,                              " (%i) '%s'\n", st_info, (uint64_t) addr,
1815                              st_name, symbol_strings + st_name);  */                              st_name, symbol_strings + st_name);  */
1816    
1817                          if (size == 0)                          if (size == 0)
# Line 1813  static void file_load_elf(struct machine Line 1819  static void file_load_elf(struct machine
1819    
1820                          if (addr != 0) /* && ((st_info >> 4) & 0xf)                          if (addr != 0) /* && ((st_info >> 4) & 0xf)
1821                              >= STB_GLOBAL) */ {                              >= STB_GLOBAL) */ {
1822                                  /*  debug("symbol info=0x%02x addr=0x%016llx"                                  /*  debug("symbol info=0x%02x addr=0x%016"PRIx64
1823                                      " '%s'\n", st_info, (long long)addr,                                      " '%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,                                      addr, size, symbol_strings + st_name,
# Line 1824  static void file_load_elf(struct machine Line 1830  static void file_load_elf(struct machine
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 1879  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 2080  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

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

  ViewVC Help
Powered by ViewVC 1.1.26