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