Home | History | Annotate | Download | only in m_ume
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- User-mode execve() for Mach-O executables      m_ume_macho.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2005-2015 Apple Inc.
     11       Greg Parker  gparker (at) apple.com
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     26    02111-1307, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 #if defined(VGO_darwin)
     32 
     33 #include "pub_core_basics.h"
     34 #include "pub_core_vki.h"
     35 
     36 #include "pub_core_aspacemgr.h"     // various mapping fns
     37 #include "pub_core_debuglog.h"
     38 #include "pub_core_libcassert.h"    // VG_(exit), vg_assert
     39 #include "pub_core_libcbase.h"      // VG_(memcmp), etc
     40 #include "pub_core_libcfile.h"      // VG_(open) et al
     41 #include "pub_core_libcprint.h"
     42 #include "pub_core_libcproc.h"
     43 #include "pub_core_machine.h"       // VG_ELF_CLASS (XXX: which should be moved)
     44 #include "pub_core_mallocfree.h"    // VG_(malloc), VG_(free)
     45 #include "pub_core_syscall.h"       // VG_(strerror)
     46 #include "pub_core_ume.h"           // self
     47 
     48 #include "priv_ume.h"
     49 
     50 #include <mach/mach.h>
     51 
     52 #include <mach-o/dyld.h>
     53 #include <mach-o/fat.h>
     54 #include <mach-o/loader.h>
     55 
     56 #if VG_WORDSIZE == 4
     57 #define MAGIC MH_MAGIC
     58 #define MACH_HEADER mach_header
     59 #define LC_SEGMENT_CMD LC_SEGMENT
     60 #define SEGMENT_COMMAND segment_command
     61 #define SECTION section
     62 #else
     63 #define MAGIC MH_MAGIC_64
     64 #define MACH_HEADER mach_header_64
     65 #define LC_SEGMENT_CMD LC_SEGMENT_64
     66 #define SEGMENT_COMMAND segment_command_64
     67 #define SECTION section_64
     68 #endif
     69 
     70 
     71 static void print(const HChar *str)
     72 {
     73    VG_(printf)("%s", str);
     74 }
     75 
     76 static void check_mmap(SysRes res, Addr base, SizeT len, const HChar* who)
     77 {
     78    if (sr_isError(res)) {
     79       VG_(printf)("valgrind: mmap-FIXED(0x%llx, %lld) failed in UME (%s) "
     80                   "with error %lu (%s).\n",
     81                   (ULong)base, (Long)len, who,
     82                   sr_Err(res), VG_(strerror)(sr_Err(res)) );
     83       VG_(exit)(1);
     84    }
     85 }
     86 
     87 #if DARWIN_VERS >= DARWIN_10_8
     88 static void check_mmap_float(SysRes res, SizeT len, const HChar* who)
     89 {
     90    if (sr_isError(res)) {
     91       VG_(printf)("valgrind: mmap-FLOAT(size=%lld) failed in UME (%s) "
     92                   "with error %lu (%s).\n",
     93                   (Long)len, who,
     94                   sr_Err(res), VG_(strerror)(sr_Err(res)) );
     95       VG_(exit)(1);
     96    }
     97 }
     98 #endif
     99 
    100 static int
    101 load_thin_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype,
    102                const HChar *filename,
    103                vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end,
    104                vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry);
    105 
    106 static int
    107 load_fat_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype,
    108               const HChar *filename,
    109               vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end,
    110               vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry);
    111 
    112 static int
    113 load_mach_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype,
    114                const HChar *filename,
    115                vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end,
    116                vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry);
    117 
    118 
    119 /* Open and map a dylinker file.
    120    Returns 0 on success, -1 on any failure.
    121    filename must be an absolute path.
    122    The dylinker's entry point is returned in *out_linker_entry.
    123  */
    124 static int
    125 open_dylinker(const HChar *filename, vki_uint8_t **out_linker_entry)
    126 {
    127    struct vg_stat sb;
    128    vki_size_t filesize;
    129    SysRes res;
    130    int fd;
    131    int err;
    132 
    133    if (filename[0] != '/') {
    134       print("bad executable (dylinker name is not an absolute path)\n");
    135       return -1;
    136    }
    137 
    138    res = VG_(open)(filename, VKI_O_RDONLY, 0);
    139    fd = sr_Res(res);
    140    if (sr_isError(res)) {
    141       print("couldn't open dylinker: ");
    142       print(filename);
    143       print("\n");
    144       return -1;
    145    }
    146    err = VG_(fstat)(fd, &sb);
    147    if (err) {
    148       print("couldn't stat dylinker: ");
    149       print(filename);
    150       print("\n");
    151       VG_(close)(fd);
    152       return -1;
    153    }
    154    filesize = sb.size;
    155 
    156    err = load_mach_file(fd, 0, filesize, MH_DYLINKER, filename,
    157                         NULL, NULL, NULL, out_linker_entry, NULL);
    158    if (err) {
    159       print("...while loading dylinker: ");
    160       print(filename);
    161       print("\n");
    162    }
    163    VG_(close)(fd);
    164    return err;
    165 }
    166 
    167 
    168 /*
    169    Process an LC_SEGMENT command, mapping it into memory if appropriate.
    170    fd[offset..size) is a Mach-O thin file.
    171    Returns 0 on success, -1 on any failure.
    172    If this segment contains the executable's Mach headers, their
    173      loaded address is returned in *text.
    174    If this segment is a __UNIXSTACK, its start address is returned in
    175      *stack_start.
    176 */
    177 static int
    178 load_segment(int fd, vki_off_t offset, vki_off_t size,
    179              vki_uint8_t **text, vki_uint8_t **stack_start,
    180              struct SEGMENT_COMMAND *segcmd, const HChar *filename)
    181 {
    182    SysRes res;
    183    Addr addr;
    184    vki_size_t filesize; // page-aligned
    185    vki_size_t vmsize;   // page-aligned
    186    unsigned int prot;
    187 
    188    // GrP fixme mark __UNIXSTACK as SF_STACK
    189 
    190    // Don't honour the client's request to map PAGEZERO.  Why not?
    191    // Because when the kernel loaded the valgrind tool executable,
    192    // it will have mapped pagezero itself.  So further attempts
    193    // to map it when loading the client are guaranteed to fail.
    194 #if VG_WORDSIZE == 4
    195    if (segcmd->vmaddr == 0 && 0 == VG_(strcmp)(segcmd->segname, SEG_PAGEZERO)) {
    196       if (segcmd->vmsize != 0x1000) {
    197          print("bad executable (__PAGEZERO is not 4 KB)\n");
    198          return -1;
    199       }
    200       return 0;
    201    }
    202 #endif
    203 #if VG_WORDSIZE == 8
    204    if (segcmd->vmaddr == 0 && 0 == VG_(strcmp)(segcmd->segname, SEG_PAGEZERO)) {
    205       if (segcmd->vmsize != 0x100000000) {
    206          print("bad executable (__PAGEZERO is not 4 GB)\n");
    207          return -1;
    208       }
    209       return 0;
    210    }
    211 #endif
    212 
    213    // Record the segment containing the Mach headers themselves
    214    if (segcmd->fileoff == 0  &&  segcmd->filesize != 0) {
    215       if (text) *text = (vki_uint8_t *)segcmd->vmaddr;
    216    }
    217 
    218    // Record the __UNIXSTACK start
    219    if (0 == VG_(strcmp)(segcmd->segname, SEG_UNIXSTACK)) {
    220       if (stack_start) *stack_start = (vki_uint8_t *)segcmd->vmaddr;
    221    }
    222 
    223    // Sanity-check the segment
    224    if (segcmd->fileoff + segcmd->filesize > size) {
    225       print("bad executable (invalid segment command)\n");
    226       return -1;
    227    }
    228    if (segcmd->vmsize == 0) {
    229       return 0;  // nothing to map - ok
    230    }
    231 
    232    // Get desired memory protection
    233    // GrP fixme need maxprot too
    234    prot = (((segcmd->initprot & VM_PROT_READ) ? VKI_PROT_READ : 0) |
    235            ((segcmd->initprot & VM_PROT_WRITE) ? VKI_PROT_WRITE : 0) |
    236            ((segcmd->initprot & VM_PROT_EXECUTE) ? VKI_PROT_EXEC : 0));
    237 
    238    // Map the segment
    239    filesize = VG_PGROUNDUP(segcmd->filesize);
    240    vmsize = VG_PGROUNDUP(segcmd->vmsize);
    241    if (filesize > 0) {
    242       addr = (Addr)segcmd->vmaddr;
    243       VG_(debugLog)(2, "ume", "mmap fixed (file) (%#lx, %lu)\n", addr, filesize);
    244       res = VG_(am_mmap_named_file_fixed_client)(addr, filesize, prot, fd,
    245                                                  offset + segcmd->fileoff,
    246                                                  filename);
    247       check_mmap(res, addr, filesize, "load_segment1");
    248    }
    249 
    250    // Zero-fill the remainder of the segment, if any
    251    if (segcmd->filesize != filesize) {
    252       // non-page-aligned part
    253       // GrP fixme kernel doesn't do this?
    254       //bzero(segcmd->filesize+(vki_uint8_t *)addr, filesize-segcmd->filesize);
    255    }
    256    if (filesize != vmsize) {
    257       // page-aligned part
    258       SizeT length = vmsize - filesize;
    259       addr = (Addr)(filesize + segcmd->vmaddr);
    260       VG_(debugLog)(2, "ume", "mmap fixed (anon) (%#lx, %lu)\n", addr, length);
    261       res = VG_(am_mmap_anon_fixed_client)(addr, length, prot);
    262       check_mmap(res, addr, length, "load_segment2");
    263    }
    264 
    265    return 0;
    266 }
    267 
    268 
    269 /*
    270    Parse a LC_THREAD or LC_UNIXTHREAD command.
    271    Return 0 on success, -1 on any failure.
    272    The stack address is returned in *stack. If the executable requested
    273    a non-default stack address, *customstack is set to TRUE. The thread's
    274    entry point is returned in *entry.
    275    The stack itself (if any) is not mapped.
    276    Other custom register settings are silently ignored (GrP fixme).
    277 */
    278 static int
    279 load_genericthread(vki_uint8_t **stack_end,
    280                    int *customstack, vki_uint8_t **entry,
    281                    struct thread_command *threadcmd)
    282 {
    283    unsigned int flavor;
    284    unsigned int count;
    285    unsigned int *p;
    286    unsigned int left;
    287 
    288    p = (unsigned int *)(threadcmd + 1);
    289    left = (threadcmd->cmdsize - sizeof(struct thread_command)) / sizeof(*p);
    290 
    291    while (left > 0) {
    292       if (left < 2) {
    293          print("bad executable (invalid thread command)\n");
    294          return -1;
    295       }
    296       flavor = *p++; left--;
    297       count = *p++; left--;
    298 
    299       if (left < count) {
    300          print("bad executable (invalid thread command 2)\n");
    301          return -1;
    302       }
    303 
    304 #if defined(VGA_x86)
    305       if (flavor == i386_THREAD_STATE && count == i386_THREAD_STATE_COUNT) {
    306          i386_thread_state_t *state = (i386_thread_state_t *)p;
    307          if (entry) *entry = (vki_uint8_t *)state->__eip;
    308          if (stack_end) {
    309             *stack_end = (vki_uint8_t *)(state->__esp ? state->__esp
    310                                                       : VKI_USRSTACK);
    311             vg_assert(VG_IS_PAGE_ALIGNED(*stack_end));
    312             (*stack_end)--;
    313          }
    314          if (customstack) *customstack = state->__esp;
    315          return 0;
    316       }
    317 
    318 #elif defined(VGA_amd64)
    319       if (flavor == x86_THREAD_STATE64 && count == x86_THREAD_STATE64_COUNT){
    320          x86_thread_state64_t *state = (x86_thread_state64_t *)p;
    321          if (entry) *entry = (vki_uint8_t *)state->__rip;
    322          if (stack_end) {
    323             *stack_end = (vki_uint8_t *)(state->__rsp ? state->__rsp
    324                                                       : VKI_USRSTACK64);
    325             vg_assert(VG_IS_PAGE_ALIGNED(*stack_end));
    326             (*stack_end)--;
    327          }
    328          if (customstack) *customstack = state->__rsp;
    329          return 0;
    330       }
    331 
    332 #else
    333 # error unknown platform
    334 #endif
    335       p += count;
    336       left -= count;
    337    }
    338 
    339    print("bad executable (no arch-compatible thread state)\n");
    340    return -1;
    341 }
    342 
    343 
    344 /* Returns the main stack size on this platform,
    345    using getrlimit or a fixed size.
    346    GrP fixme 64-bit? */
    347 static vki_size_t default_stack_size(void)
    348 {
    349    struct vki_rlimit lim;
    350    int err = VG_(getrlimit)(VKI_RLIMIT_STACK, &lim);
    351    if (err) return 8*1024*1024; // 8 MB
    352    else return lim.rlim_cur;
    353 }
    354 
    355 
    356 /*
    357    Processes a LC_UNIXTHREAD command.
    358    Returns 0 on success, -1 on any failure.
    359    The stack is mapped in and returned in *out_stack.
    360    The thread's entry point is returned in *out_entry.
    361 */
    362 static int
    363 load_unixthread(vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end,
    364                 vki_uint8_t **out_entry, struct thread_command *threadcmd)
    365 {
    366    int err;
    367    vki_uint8_t *stack_end;
    368    int customstack;
    369 
    370    err = load_genericthread(&stack_end, &customstack, out_entry, threadcmd);
    371    if (err) return -1;
    372 
    373    if (!stack_end) {
    374       print("bad executable (no thread stack)\n");
    375       return -1;
    376    }
    377 
    378    if (!customstack) {
    379       // Map the stack
    380       vki_size_t stacksize = VG_PGROUNDUP(default_stack_size());
    381       vm_address_t stackbase = VG_PGROUNDDN(stack_end+1-stacksize);
    382       SysRes res;
    383 
    384       res = VG_(am_mmap_anon_fixed_client)(stackbase, stacksize, VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC);
    385       check_mmap(res, stackbase, stacksize, "load_unixthread1");
    386       if (out_stack_start) *out_stack_start = (vki_uint8_t *)stackbase;
    387    } else {
    388       // custom stack - mapped via __UNIXTHREAD segment
    389    }
    390 
    391    if (out_stack_end) *out_stack_end = stack_end;
    392 
    393    return 0;
    394 }
    395 
    396 
    397 /* Allocates a stack mapping at a V-chosen address.  Pertains to
    398    LC_MAIN commands, which seem to have appeared in OSX 10.8.
    399 
    400    This is a really nasty hack -- allocates 64M+stack size, then
    401    deallocates the 64M, to guarantee that the stack is at least 64M
    402    above zero. */
    403 #if DARWIN_VERS >= DARWIN_10_8
    404 static int
    405 handle_lcmain ( vki_uint8_t **out_stack_start,
    406                 vki_uint8_t **out_stack_end,
    407                 vki_size_t requested_size )
    408 {
    409    if (requested_size == 0) {
    410       requested_size = default_stack_size();
    411    }
    412    requested_size = VG_PGROUNDUP(requested_size);
    413 
    414    const vki_size_t HACK = 64 * 1024 * 1024;
    415    requested_size += HACK;
    416 
    417    SysRes res = VG_(am_mmap_anon_float_client)(requested_size,
    418                    VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC);
    419    check_mmap_float(res, requested_size, "handle_lcmain");
    420    vg_assert(!sr_isError(res));
    421    *out_stack_start = (vki_uint8_t*)sr_Res(res);
    422    *out_stack_end   = *out_stack_start + requested_size - 1;
    423 
    424    Bool need_discard = False;
    425    res = VG_(am_munmap_client)(&need_discard, (Addr)*out_stack_start, HACK);
    426    if (sr_isError(res)) return -1;
    427    vg_assert(!need_discard); // True == wtf?
    428 
    429    *out_stack_start += HACK;
    430 
    431    return 0;
    432 }
    433 #endif /* DARWIN_VERS >= DARWIN_10_8 */
    434 
    435 
    436 
    437 /*
    438    Processes an LC_LOAD_DYLINKER command.
    439    Returns 0 on success, -1 on any error.
    440    The linker itself is mapped into memory.
    441    The linker's entry point is returned in *linker_entry.
    442 */
    443 static int
    444 load_dylinker(vki_uint8_t **linker_entry, struct dylinker_command *dycmd)
    445 {
    446    const HChar *name;
    447 
    448    if (dycmd->name.offset >= dycmd->cmdsize) {
    449       print("bad executable (invalid dylinker command)\n");
    450       return -1;
    451    }
    452 
    453    name = dycmd->name.offset + (HChar *)dycmd;
    454 
    455    // GrP fixme assumes name is terminated somewhere
    456    return open_dylinker(name, linker_entry);
    457 }
    458 
    459 
    460 /*
    461     Process an LC_THREAD command.
    462     Returns 0 on success, -1 on any failure.
    463     The thread's entry point is returned in *out_entry.
    464 */
    465 static int
    466 load_thread(vki_uint8_t **out_entry, struct thread_command *threadcmd)
    467 {
    468    int customstack;
    469    int err;
    470 
    471    err = load_genericthread(NULL, &customstack, out_entry, threadcmd);
    472    if (err) return -1;
    473    if (customstack) {
    474       print("bad executable (stackless thread has stack)\n");
    475       return -1;
    476    }
    477    return 0;
    478 }
    479 
    480 
    481 /*
    482   Loads a Mach-O executable into memory, along with any threads,
    483   stacks, and dylinker.
    484   Returns 0 on success, -1 on any failure.
    485   fd[offset..offset+size) is a Mach-O thin file.
    486   filetype is MH_EXECUTE or MH_DYLINKER.
    487   The mapped but empty stack is returned in *out_stack.
    488   The executable's Mach headers are returned in *out_text.
    489   The executable's entry point is returned in *out_entry.
    490   The dylinker's entry point (if any) is returned in *out_linker_entry.
    491   GrP fixme need to return whether dylinker was found - stack layout is different
    492 */
    493 static int
    494 load_thin_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype,
    495                const HChar *filename,
    496                vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end,
    497                vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry)
    498 {
    499    VG_(debugLog)(1, "ume", "load_thin_file: begin:   %s\n", filename);
    500    struct MACH_HEADER mh;
    501    vki_uint8_t *headers;
    502    vki_uint8_t *headers_end;
    503    struct load_command *lc;
    504    struct load_command *lcend;
    505    struct SEGMENT_COMMAND *segcmd;
    506    struct thread_command *threadcmd;
    507    struct dylinker_command *dycmd;
    508    int err;
    509    SysRes res;
    510    vki_size_t len;
    511 
    512    vki_uint8_t *stack_start = NULL;   // allocated thread stack (hot end)
    513    vki_uint8_t *stack_end = NULL;   // allocated thread stack (cold end)
    514    vki_uint8_t *entry = NULL;   // static entry point
    515    vki_uint8_t *text = NULL;    // start of text segment (i.e. the mach headers)
    516    vki_uint8_t *linker_entry = NULL; // dylinker entry point
    517 
    518    // Read Mach-O header
    519    if (sizeof(mh) > size) {
    520       print("bad executable (no Mach-O header)\n");
    521    }
    522    res = VG_(pread)(fd, &mh, sizeof(mh), offset);
    523    if (sr_isError(res)  ||  sr_Res(res) != sizeof(mh)) {
    524       print("bad executable (no Mach-O header)\n");
    525       return -1;
    526    }
    527 
    528 
    529    // Sanity-check the header itself
    530    if (mh.magic != MAGIC) {
    531       print("bad executable (no Mach-O magic)\n");
    532       return -1;
    533    }
    534 
    535    if (mh.filetype != filetype) {
    536       // expecting MH_EXECUTE or MH_DYLINKER
    537       print("bad executable (wrong file type)\n");
    538       return -1;
    539    }
    540 
    541 
    542    // Map all headers into memory
    543    len = sizeof(mh) + mh.sizeofcmds;
    544    if (len > size) {
    545       print("bad executable (missing load commands)\n");
    546       return -1;
    547    }
    548 
    549    headers = VG_(malloc)("ume.macho.headers", len);
    550    res = VG_(pread)(fd, headers, len, offset);
    551    if (sr_isError(res)) {
    552       print("couldn't read load commands from executable\n");
    553       return -1;
    554    }
    555    headers_end = headers + len;
    556 
    557 
    558    // Map some segments into client memory:
    559    // LC_SEGMENT    (text, data, etc)
    560    // UNIXSTACK     (stack)
    561    // LOAD_DYLINKER (dyld)
    562    lcend = (struct load_command *)(headers + mh.sizeofcmds + sizeof(mh));
    563    for (lc = (struct load_command *)(headers + sizeof(mh));
    564         lc < lcend;
    565         lc = (struct load_command *)(lc->cmdsize + (vki_uint8_t *)lc))
    566    {
    567       if ((vki_uint8_t *)lc < headers  ||
    568           lc->cmdsize+(vki_uint8_t *)lc > headers_end) {
    569           print("bad executable (invalid load commands)\n");
    570           return -1;
    571       }
    572 
    573       switch (lc->cmd) {
    574 
    575 #if   DARWIN_VERS >= DARWIN_10_8
    576       case LC_MAIN: { /* New in 10.8 */
    577          struct entry_point_command* epcmd
    578             = (struct entry_point_command*)lc;
    579          if (stack_start || stack_end) {
    580             print("bad executable (multiple indications of stack)");
    581             return -1;
    582          }
    583          err = handle_lcmain ( &stack_start, &stack_end, epcmd->stacksize );
    584          if (err) return -1;
    585          VG_(debugLog)(2, "ume", "lc_main: created stack %p-%p\n",
    586 	               stack_start, stack_end);
    587          break;
    588       }
    589 #     endif
    590 
    591       case LC_SEGMENT_CMD:
    592          if (lc->cmdsize < sizeof(struct SEGMENT_COMMAND)) {
    593             print("bad executable (invalid load commands)\n");
    594             return -1;
    595          }
    596          segcmd = (struct SEGMENT_COMMAND *)lc;
    597          err = load_segment(fd, offset, size, &text, &stack_start,
    598                             segcmd, filename);
    599          if (err) return -1;
    600 
    601          break;
    602 
    603       case LC_UNIXTHREAD:
    604          if (stack_end  ||  entry) {
    605             print("bad executable (multiple thread commands)\n");
    606             return -1;
    607          }
    608          if (lc->cmdsize < sizeof(struct thread_command)) {
    609             print("bad executable (invalid load commands)\n");
    610             return -1;
    611          }
    612          threadcmd = (struct thread_command *)lc;
    613          err = load_unixthread(&stack_start, &stack_end, &entry, threadcmd);
    614          if (err) return -1;
    615          break;
    616 
    617       case LC_LOAD_DYLINKER:
    618          if (filetype == MH_DYLINKER) {
    619             print("bad executable (dylinker needs a dylinker)\n");
    620             return -1;
    621          }
    622          if (linker_entry) {
    623             print("bad executable (multiple dylinker commands)\n");
    624          }
    625          if (lc->cmdsize < sizeof(struct dylinker_command)) {
    626             print("bad executable (invalid load commands)\n");
    627             return -1;
    628          }
    629          dycmd = (struct dylinker_command *)lc;
    630          err = load_dylinker(&linker_entry, dycmd);
    631          if (err) return -1;
    632          break;
    633 
    634       case LC_THREAD:
    635          if (filetype == MH_EXECUTE) {
    636             print("bad executable (stackless thread)\n");
    637             return -1;
    638          }
    639          if (stack_end  ||  entry) {
    640             print("bad executable (multiple thread commands)\n");
    641             return -1;
    642          }
    643          if (lc->cmdsize < sizeof(struct thread_command)) {
    644             print("bad executable (invalid load commands)\n");
    645             return -1;
    646          }
    647          threadcmd = (struct thread_command *)lc;
    648          err = load_thread(&entry, threadcmd);
    649          if (err) return -1;
    650          break;
    651 
    652       default:
    653          break;
    654       }
    655    }
    656 
    657 
    658    // Done with the headers
    659    VG_(free)(headers);
    660 
    661    if (filetype == MH_EXECUTE) {
    662       // Verify the necessary pieces for an executable:
    663       // a stack
    664       // a text segment
    665       // an entry point (static or linker)
    666       if (!stack_end || !stack_start) {
    667          VG_(printf)("bad executable %s (no stack)\n", filename);
    668          return -1;
    669       }
    670       if (!text) {
    671          print("bad executable (no text segment)\n");
    672          return -1;
    673       }
    674       if (!entry  &&  !linker_entry) {
    675          print("bad executable (no entry point)\n");
    676          return -1;
    677       }
    678    }
    679    else if (filetype == MH_DYLINKER) {
    680       // Verify the necessary pieces for a dylinker:
    681       // an entry point
    682       if (!entry) {
    683          print("bad executable (no entry point)\n");
    684          return -1;
    685       }
    686    }
    687 
    688    if (out_stack_start) *out_stack_start = stack_start;
    689    if (out_stack_end) *out_stack_end = stack_end;
    690    if (out_text)  *out_text = text;
    691    if (out_entry) *out_entry = entry;
    692    if (out_linker_entry) *out_linker_entry = linker_entry;
    693 
    694    VG_(debugLog)(1, "ume", "load_thin_file: success: %s\n", filename);
    695    return 0;
    696 }
    697 
    698 
    699 /*
    700  Load a fat Mach-O executable.
    701 */
    702 static int
    703 load_fat_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype,
    704              const HChar *filename,
    705              vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end,
    706              vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry)
    707 {
    708    struct fat_header fh;
    709    vki_off_t arch_offset;
    710    int i;
    711    cpu_type_t good_arch;
    712    SysRes res;
    713 
    714 #if defined(VGA_ppc32)
    715    good_arch = CPU_TYPE_POWERPC;
    716 #elif defined(VGA_ppc64be)
    717    good_arch = CPU_TYPE_POWERPC64BE;
    718 #elif defined(VGA_ppc64le)
    719    good_arch = CPU_TYPE_POWERPC64LE;
    720 #elif defined(VGA_x86)
    721    good_arch = CPU_TYPE_I386;
    722 #elif defined(VGA_amd64)
    723    good_arch = CPU_TYPE_X86_64;
    724 #else
    725 # error unknown architecture
    726 #endif
    727 
    728    // Read fat header
    729    // All fat contents are BIG-ENDIAN
    730    if (size < sizeof(fh)) {
    731       print("bad executable (bad fat header)\n");
    732       return -1;
    733    }
    734    res = VG_(pread)(fd, &fh, sizeof(fh), offset);
    735    if (sr_isError(res)  ||  sr_Res(res) != sizeof(fh)) {
    736       print("bad executable (bad fat header)\n");
    737       return -1;
    738    }
    739 
    740    // Scan arch headers looking for a good one
    741    arch_offset = offset + sizeof(fh);
    742    fh.nfat_arch = VG_(ntohl)(fh.nfat_arch);
    743    for (i = 0; i < fh.nfat_arch; i++) {
    744       struct fat_arch arch;
    745       if (arch_offset + sizeof(arch) > size) {
    746           print("bad executable (corrupt fat archs)\n");
    747           return -1;
    748       }
    749 
    750       res = VG_(pread)(fd, &arch, sizeof(arch), arch_offset);
    751       arch_offset += sizeof(arch);
    752       if (sr_isError(res)  ||  sr_Res(res) != sizeof(arch)) {
    753          VG_(printf)("bad executable (corrupt fat arch) %x %llu\n",
    754                      arch.cputype, (ULong)arch_offset);
    755          return -1;
    756       }
    757 
    758       arch.cputype = VG_(ntohl)(arch.cputype);
    759       arch.cpusubtype = VG_(ntohl)(arch.cpusubtype);
    760       arch.offset = VG_(ntohl)(arch.offset);
    761       arch.size = VG_(ntohl)(arch.size);
    762       arch.align = VG_(ntohl)(arch.align);
    763       if (arch.cputype == good_arch) {
    764          // use this arch
    765          if (arch.offset > size  ||  arch.offset + arch.size > size) {
    766             print("bad executable (corrupt fat arch 2)\n");
    767             return -1;
    768          }
    769          return load_mach_file(fd, offset+arch.offset, arch.size, filetype,
    770                                filename, out_stack_start, out_stack_end,
    771                                out_text, out_entry, out_linker_entry);
    772       }
    773    }
    774 
    775    print("bad executable (can't run on this machine)\n");
    776    return -1;
    777 }
    778 
    779 /*
    780  Load a Mach-O executable or dylinker.
    781  The file may be fat or thin.
    782 */
    783 static int
    784 load_mach_file(int fd, vki_off_t offset, vki_off_t size, unsigned long filetype,
    785               const HChar *filename,
    786               vki_uint8_t **out_stack_start, vki_uint8_t **out_stack_end,
    787               vki_uint8_t **out_text, vki_uint8_t **out_entry, vki_uint8_t **out_linker_entry)
    788 {
    789    vki_uint32_t magic;
    790    SysRes res;
    791 
    792    if (size < sizeof(magic)) {
    793       print("bad executable (no Mach-O magic)\n");
    794       return -1;
    795    }
    796    res = VG_(pread)(fd, &magic, sizeof(magic), offset);
    797    if (sr_isError(res)  ||  sr_Res(res) != sizeof(magic)) {
    798       print("bad executable (no Mach-O magic)\n");
    799       return -1;
    800    }
    801 
    802    if (magic == MAGIC) {
    803       // thin
    804       return load_thin_file(fd, offset, size, filetype, filename,
    805                             out_stack_start, out_stack_end,
    806                             out_text, out_entry, out_linker_entry);
    807    } else if (magic == VG_(htonl)(FAT_MAGIC)) {
    808       // fat
    809       return load_fat_file(fd, offset, size, filetype, filename,
    810                            out_stack_start, out_stack_end,
    811                            out_text, out_entry, out_linker_entry);
    812    } else {
    813       // huh?
    814       print("bad executable (bad Mach-O magic)\n");
    815       return -1;
    816    }
    817 }
    818 
    819 
    820 Bool VG_(match_macho)(const void *hdr, SizeT len)
    821 {
    822    const vki_uint32_t *magic = hdr;
    823 
    824    // GrP fixme check more carefully for matching fat arch?
    825 
    826    return (len >= VKI_PAGE_SIZE  &&
    827            (*magic == MAGIC  ||  *magic == VG_(ntohl)(FAT_MAGIC)))
    828       ? True : False;
    829 }
    830 
    831 
    832 Int VG_(load_macho)(Int fd, const HChar *name, ExeInfo *info)
    833 {
    834    int err;
    835    struct vg_stat sb;
    836    vki_uint8_t *stack_start;
    837    vki_uint8_t *stack_end;
    838    vki_uint8_t *text;
    839    vki_uint8_t *entry;
    840    vki_uint8_t *linker_entry;
    841 
    842    err = VG_(fstat)(fd, &sb);
    843    if (err) {
    844       print("couldn't stat executable\n");
    845       return VKI_ENOEXEC;
    846    }
    847 
    848    err = load_mach_file(fd, 0, sb.size, MH_EXECUTE, name,
    849                         &stack_start, &stack_end,
    850                         &text, &entry, &linker_entry);
    851    if (err) return VKI_ENOEXEC;
    852 
    853    // GrP fixme exe_base
    854    // GrP fixme exe_end
    855    info->entry = (Addr)entry;
    856    info->init_ip = (Addr)(linker_entry ? linker_entry : entry);
    857    info->brkbase = 0xffffffff; // GrP fixme hack
    858    info->init_toc = 0; // GrP fixme unused
    859 
    860    info->stack_start = (Addr)stack_start;
    861    info->stack_end = (Addr)stack_end;
    862    info->text = (Addr)text;
    863    info->dynamic = linker_entry ? True : False;
    864 
    865    info->executable_path = VG_(strdup)("ume.macho.executable_path", name);
    866 
    867    return 0;
    868 }
    869 
    870 #endif // defined(VGO_darwin)
    871 
    872 /*--------------------------------------------------------------------*/
    873 /*--- end                                                          ---*/
    874 /*--------------------------------------------------------------------*/
    875 
    876