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