Exemple #1
0
/*
 Load a Mach-O executable or dylinker.
 The file may be fat or thin.
*/
static int 
load_mach_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype, 
              const char *filename, 
              vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end, 
              vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry)
{
   vki_uint32_t magic;
   SysRes res;

   if (size < sizeof(magic)) {
      print("bad executable (no Mach-O magic)\n");
      return -1;
   }
   res = VG_(pread)(fd, &magic, sizeof(magic), offset);
   if (sr_isError(res)  ||  sr_Res(res) != sizeof(magic)) {
      print("bad executable (no Mach-O magic)\n");
      return -1;
   }
   
   if (magic == MAGIC) {
      // thin
      return load_thin_file(fd, offset, size, filetype, filename, 
                            out_stack_start, out_stack_end, 
                            out_text, out_entry, out_linker_entry);
   } else if (magic == VG_(htonl)(FAT_MAGIC)) {
      // fat
      return load_fat_file(fd, offset, size, filetype, filename, 
                           out_stack_start, out_stack_end, 
                           out_text, out_entry, out_linker_entry);
   } else {
      // huh?
      print("bad executable (bad Mach-O magic)\n");
      return -1;
   }
}
Exemple #2
0
/*
 Load a fat Mach-O executable.
*/
static int 
load_fat_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype, 
             const HChar *filename, 
             vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end, 
             vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry)
{
   struct fat_header fh;
   vki_off_t arch_offset;
   int i;
   cpu_type_t good_arch;
#if defined(VGA_arm)
   cpu_subtype_t highest_subtype;
#endif
   SysRes res;

#if defined(VGA_ppc32)
   good_arch = CPU_TYPE_POWERPC;
#elif defined(VGA_ppc64be)
   good_arch = CPU_TYPE_POWERPC64BE;
#elif defined(VGA_ppc64le)
   good_arch = CPU_TYPE_POWERPC64LE;
#elif defined(VGA_x86)
   good_arch = CPU_TYPE_I386;
#elif defined(VGA_amd64)
   good_arch = CPU_TYPE_X86_64;
#elif defined(VGA_arm)
   good_arch = CPU_TYPE_ARM;
   highest_subtype = CPU_SUBTYPE_ARM_V7;
#else
# error unknown architecture
#endif

   // Read fat header
   // All fat contents are BIG-ENDIAN
   if (size < sizeof(fh)) {
      print("bad executable (bad fat header)\n");
      return -1;
   }
   res = VG_(pread)(fd, &fh, sizeof(fh), offset);
   if (sr_isError(res)  ||  sr_Res(res) != sizeof(fh)) {
      print("bad executable (bad fat header)\n");
      return -1;
   }
   
   // Scan arch headers looking for a good one
   arch_offset = offset + sizeof(fh);
   fh.nfat_arch = VG_(ntohl)(fh.nfat_arch);
   for (i = 0; i < fh.nfat_arch; i++) {
      struct fat_arch arch;
      if (arch_offset + sizeof(arch) > size) {
          print("bad executable (corrupt fat archs)\n");
          return -1;
      }

      res = VG_(pread)(fd, &arch, sizeof(arch), arch_offset);
      arch_offset += sizeof(arch);
      if (sr_isError(res)  ||  sr_Res(res) != sizeof(arch)) {
         VG_(printf)("bad executable (corrupt fat arch) %x %llu\n", 
                     arch.cputype, (ULong)arch_offset);
         return -1;
      }

      arch.cputype = VG_(ntohl)(arch.cputype);
      arch.cpusubtype = VG_(ntohl)(arch.cpusubtype);
      arch.offset = VG_(ntohl)(arch.offset);
      arch.size = VG_(ntohl)(arch.size);
      arch.align = VG_(ntohl)(arch.align);

#if defined(VGA_arm)
      if ((arch.cputype == good_arch) && (arch.cpusubtype <= highest_subtype)) {
#else
      if (arch.cputype == good_arch) {
#endif
         // use this arch
         if (arch.offset > size  ||  arch.offset + arch.size > size) {
            print("bad executable (corrupt fat arch 2)\n");
            return -1;
         }
         return load_mach_file(fd, offset+arch.offset, arch.size, filetype, 
                               filename, out_stack_start, out_stack_end, 
                               out_text, out_entry, out_linker_entry);
      }
   }

   print("bad executable (can't run on this machine)\n");
   return -1;
}

/*
 Load a Mach-O executable or dylinker.
 The file may be fat or thin.
*/
static int 
load_mach_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype, 
              const HChar *filename, 
              vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end, 
              vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry)
{
   vki_uint32_t magic;
   SysRes res;

   if (size < sizeof(magic)) {
      print("bad executable (no Mach-O magic)\n");
      return -1;
   }
   res = VG_(pread)(fd, &magic, sizeof(magic), offset);
   if (sr_isError(res)  ||  sr_Res(res) != sizeof(magic)) {
      print("bad executable (no Mach-O magic)\n");
      return -1;
   }
   
   if (magic == MAGIC) {
      // thin
      return load_thin_file(fd, offset, size, filetype, filename, 
                            out_stack_start, out_stack_end, 
                            out_text, out_entry, out_linker_entry);
   } else if (magic == VG_(htonl)(FAT_MAGIC)) {
      // fat
      return load_fat_file(fd, offset, size, filetype, filename, 
                           out_stack_start, out_stack_end, 
                           out_text, out_entry, out_linker_entry);
   } else {
      // huh?
      print("bad executable (bad Mach-O magic)\n");
      return -1;
   }
}