1 2 /*--------------------------------------------------------------------*/ 3 /*--- Startup: create initial process image on Darwin ---*/ 4 /*--- initimg-darwin.c ---*/ 5 /*--------------------------------------------------------------------*/ 6 7 /* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2000-2017 Julian Seward 12 jseward (at) acm.org 13 14 This program is free software; you can redistribute it and/or 15 modify it under the terms of the GNU General Public License as 16 published by the Free Software Foundation; either version 2 of the 17 License, or (at your option) any later version. 18 19 This program is distributed in the hope that it will be useful, but 20 WITHOUT ANY WARRANTY; without even the implied warranty of 21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 General Public License for more details. 23 24 You should have received a copy of the GNU General Public License 25 along with this program; if not, write to the Free Software 26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27 02111-1307, USA. 28 29 The GNU General Public License is contained in the file COPYING. 30 */ 31 32 #if defined(VGO_darwin) 33 34 #include "pub_core_basics.h" 35 #include "pub_core_vki.h" 36 #include "pub_core_debuglog.h" 37 #include "pub_core_libcbase.h" 38 #include "pub_core_libcassert.h" 39 #include "pub_core_libcfile.h" 40 #include "pub_core_libcproc.h" 41 #include "pub_core_libcprint.h" 42 #include "pub_core_xarray.h" 43 #include "pub_core_clientstate.h" 44 #include "pub_core_aspacemgr.h" 45 #include "pub_core_mallocfree.h" 46 #include "pub_core_machine.h" 47 #include "pub_core_ume.h" 48 #include "pub_core_options.h" 49 #include "pub_core_tooliface.h" /* VG_TRACK */ 50 #include "pub_core_threadstate.h" /* ThreadArchState */ 51 #include "priv_initimg_pathscan.h" 52 #include "pub_core_initimg.h" /* self */ 53 54 55 /*====================================================================*/ 56 /*=== Loading the client ===*/ 57 /*====================================================================*/ 58 59 /* Load the client whose name is VG_(argv_the_exename). */ 60 61 static void load_client ( /*OUT*/ExeInfo* info, 62 /*OUT*/Addr* client_ip) 63 { 64 const HChar* exe_name; 65 Int ret; 66 SysRes res; 67 68 vg_assert( VG_(args_the_exename) != NULL); 69 exe_name = ML_(find_executable)( VG_(args_the_exename) ); 70 71 if (!exe_name) { 72 VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename)); 73 VG_(exit)(127); // 127 is Posix NOTFOUND 74 } 75 76 VG_(memset)(info, 0, sizeof(*info)); 77 ret = VG_(do_exec)(exe_name, info); 78 79 // The client was successfully loaded! Continue. 80 81 /* Get hold of a file descriptor which refers to the client 82 executable. This is needed for attaching to GDB. */ 83 res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR); 84 if (!sr_isError(res)) 85 VG_(cl_exec_fd) = sr_Res(res); 86 87 /* Copy necessary bits of 'info' that were filled in */ 88 *client_ip = info->init_ip; 89 } 90 91 92 /*====================================================================*/ 93 /*=== Setting up the client's environment ===*/ 94 /*====================================================================*/ 95 96 /* Prepare the client's environment. This is basically a copy of our 97 environment, except: 98 99 DYLD_INSERT_LIBRARIES=$VALGRIND_LIB/vgpreload_core-PLATFORM.so: 100 ($VALGRIND_LIB/vgpreload_TOOL-PLATFORM.so:)? 101 DYLD_INSERT_LIBRARIES 102 103 If this is missing, then it is added. 104 105 Also, remove any binding for VALGRIND_LAUNCHER=. The client should 106 not be able to see this. 107 108 Also, add DYLD_SHARED_REGION=avoid, because V doesn't know how 109 to process the dyld shared cache file. 110 111 Also, change VYLD_* (mangled by launcher) back to DYLD_*. 112 113 If this needs to handle any more variables it should be hacked 114 into something table driven. The copy is VG_(malloc)'d space. 115 */ 116 static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) 117 { 118 const HChar* preload_core = "vgpreload_core"; 119 const HChar* ld_preload = "DYLD_INSERT_LIBRARIES="; 120 const HChar* dyld_cache = "DYLD_SHARED_REGION="; 121 const HChar* dyld_cache_value= "avoid"; 122 const HChar* v_launcher = VALGRIND_LAUNCHER "="; 123 Int ld_preload_len = VG_(strlen)( ld_preload ); 124 Int dyld_cache_len = VG_(strlen)( dyld_cache ); 125 Int v_launcher_len = VG_(strlen)( v_launcher ); 126 Bool ld_preload_done = False; 127 Bool dyld_cache_done = False; 128 Int vglib_len = VG_(strlen)(VG_(libdir)); 129 130 HChar** cpp; 131 HChar** ret; 132 HChar* preload_tool_path; 133 Int envc, i; 134 135 /* Alloc space for the vgpreload_core.so path and vgpreload_<tool>.so 136 paths. We might not need the space for vgpreload_<tool>.so, but it 137 doesn't hurt to over-allocate briefly. The 16s are just cautious 138 slop. */ 139 Int preload_core_path_len = vglib_len + sizeof(preload_core) 140 + sizeof(VG_PLATFORM) + 16; 141 Int preload_tool_path_len = vglib_len + VG_(strlen)(toolname) 142 + sizeof(VG_PLATFORM) + 16; 143 Int preload_string_len = preload_core_path_len + preload_tool_path_len; 144 HChar* preload_string = VG_(malloc)("initimg-darwin.sce.1", preload_string_len); 145 146 /* Determine if there's a vgpreload_<tool>_<platform>.so file, and setup 147 preload_string. */ 148 preload_tool_path = VG_(malloc)("initimg-darwin.sce.2", preload_tool_path_len); 149 VG_(snprintf)(preload_tool_path, preload_tool_path_len, 150 "%s/vgpreload_%s-%s.so", VG_(libdir), toolname, VG_PLATFORM); 151 if (VG_(access)(preload_tool_path, True/*r*/, False/*w*/, False/*x*/) == 0) { 152 VG_(snprintf)(preload_string, preload_string_len, "%s/%s-%s.so:%s", 153 VG_(libdir), preload_core, VG_PLATFORM, preload_tool_path); 154 } else { 155 VG_(snprintf)(preload_string, preload_string_len, "%s/%s-%s.so", 156 VG_(libdir), preload_core, VG_PLATFORM); 157 } 158 VG_(free)(preload_tool_path); 159 160 VG_(debugLog)(2, "initimg", "preload_string:\n"); 161 VG_(debugLog)(2, "initimg", " \"%s\"\n", preload_string); 162 163 /* Count the original size of the env */ 164 envc = 0; 165 for (cpp = origenv; cpp && *cpp; cpp++) 166 envc++; 167 168 /* Allocate a new space */ 169 ret = VG_(malloc) ("initimg-darwin.sce.3", 170 sizeof(HChar *) * (envc+2+1)); /* 2 new entries + NULL */ 171 172 /* copy it over */ 173 for (cpp = ret; *origenv; ) 174 *cpp++ = *origenv++; 175 *cpp = NULL; 176 177 vg_assert(envc == (cpp - ret)); 178 179 /* Walk over the new environment, mashing as we go */ 180 for (cpp = ret; cpp && *cpp; cpp++) { 181 if (VG_(memcmp)(*cpp, ld_preload, ld_preload_len) == 0) { 182 Int len = VG_(strlen)(*cpp) + preload_string_len; 183 HChar *cp = VG_(malloc)("initimg-darwin.sce.4", len); 184 185 VG_(snprintf)(cp, len, "%s%s:%s", 186 ld_preload, preload_string, (*cpp)+ld_preload_len); 187 188 *cpp = cp; 189 190 ld_preload_done = True; 191 } 192 if (VG_(memcmp)(*cpp, dyld_cache, dyld_cache_len) == 0) { 193 Int len = dyld_cache_len + VG_(strlen)(dyld_cache_value) + 1; 194 HChar *cp = VG_(malloc)("initimg-darwin.sce.4.2", len); 195 196 VG_(snprintf)(cp, len, "%s%s", dyld_cache, dyld_cache_value); 197 198 *cpp = cp; 199 200 ld_preload_done = True; 201 } 202 } 203 204 /* Add the missing bits */ 205 if (!ld_preload_done) { 206 Int len = ld_preload_len + preload_string_len; 207 HChar *cp = VG_(malloc) ("initimg-darwin.sce.5", len); 208 209 VG_(snprintf)(cp, len, "%s%s", ld_preload, preload_string); 210 211 ret[envc++] = cp; 212 } 213 if (!dyld_cache_done) { 214 Int len = dyld_cache_len + VG_(strlen)(dyld_cache_value) + 1; 215 HChar *cp = VG_(malloc) ("initimg-darwin.sce.5.2", len); 216 217 VG_(snprintf)(cp, len, "%s%s", dyld_cache, dyld_cache_value); 218 219 ret[envc++] = cp; 220 } 221 222 223 /* ret[0 .. envc-1] is live now. */ 224 /* Find and remove a binding for VALGRIND_LAUNCHER. */ 225 for (i = 0; i < envc; i++) 226 if (0 == VG_(memcmp)(ret[i], v_launcher, v_launcher_len)) 227 break; 228 229 if (i < envc) { 230 for (; i < envc-1; i++) 231 ret[i] = ret[i+1]; 232 envc--; 233 } 234 235 /* Change VYLD_ to DYLD */ 236 for (i = 0; i < envc; i++) { 237 if (0 == VG_(strncmp)(ret[i], "VYLD_", 5)) { 238 ret[i][0] = 'D'; 239 } 240 } 241 242 243 VG_(free)(preload_string); 244 ret[envc] = NULL; 245 return ret; 246 } 247 248 249 /*====================================================================*/ 250 /*=== Setting up the client's stack ===*/ 251 /*====================================================================*/ 252 253 /* Add a string onto the string table, and return its address */ 254 static HChar *copy_str(HChar **tab, const HChar *str) 255 { 256 HChar *cp = *tab; 257 HChar *orig = cp; 258 259 while(*str) 260 *cp++ = *str++; 261 *cp++ = '\0'; 262 263 if (0) 264 VG_(printf)("copied %p \"%s\" len %lld\n", orig, orig, (Long)(cp-orig)); 265 266 *tab = cp; 267 268 return orig; 269 } 270 271 272 /* ---------------------------------------------------------------- 273 274 This sets up the client's initial stack, containing the args, 275 environment and aux vector. 276 277 The format of the stack on Darwin is: 278 279 higher address +-----------------+ <- clstack_end 280 | | 281 : string table : 282 | | 283 +-----------------+ 284 | NULL | 285 +-----------------+ 286 | executable_path | (first arg to execve()) 287 +-----------------+ 288 | NULL | 289 - - 290 | envp | 291 +-----------------+ 292 | NULL | 293 - - 294 | argv | 295 +-----------------+ 296 | argc | 297 +-----------------+ 298 | mach_header * | (dynamic only) 299 lower address +-----------------+ <- sp 300 | undefined | 301 : : 302 303 Allocate and create the initial client stack. It is allocated down 304 from clstack_end, which was previously determined by the address 305 space manager. The returned value is the SP value for the client. 306 307 ---------------------------------------------------------------- */ 308 309 static 310 Addr setup_client_stack( void* init_sp, 311 HChar** orig_envp, 312 const ExeInfo* info, 313 Addr clstack_end, 314 SizeT clstack_max_size, 315 const VexArchInfo* vex_archinfo ) 316 { 317 HChar **cpp; 318 HChar *strtab; /* string table */ 319 HChar *stringbase; 320 Addr *ptr; 321 unsigned stringsize; /* total size of strings in bytes */ 322 unsigned auxsize; /* total size of auxv in bytes */ 323 Int argc; /* total argc */ 324 Int envc; /* total number of env vars */ 325 unsigned stacksize; /* total client stack size */ 326 Addr client_SP; /* client stack base (initial SP) */ 327 Addr clstack_start; 328 Int i; 329 330 vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1)); 331 vg_assert( VG_(args_for_client) ); 332 333 /* ==================== compute sizes ==================== */ 334 335 /* first of all, work out how big the client stack will be */ 336 stringsize = 0; 337 auxsize = 0; 338 339 /* paste on the extra args if the loader needs them (ie, the #! 340 interpreter and its argument) */ 341 argc = 0; 342 if (info->interp_name != NULL) { 343 argc++; 344 stringsize += VG_(strlen)(info->interp_name) + 1; 345 } 346 if (info->interp_args != NULL) { 347 argc++; 348 stringsize += VG_(strlen)(info->interp_args) + 1; 349 } 350 351 /* now scan the args we're given... */ 352 stringsize += VG_(strlen)( VG_(args_the_exename) ) + 1; 353 354 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { 355 argc++; 356 stringsize += VG_(strlen)( * (HChar**) 357 VG_(indexXA)( VG_(args_for_client), i )) 358 + 1; 359 } 360 361 /* ...and the environment */ 362 envc = 0; 363 for (cpp = orig_envp; cpp && *cpp; cpp++) { 364 envc++; 365 stringsize += VG_(strlen)(*cpp) + 1; 366 } 367 368 /* Darwin executable_path + NULL */ 369 auxsize += 2 * sizeof(Word); 370 if (info->executable_path) { 371 stringsize += 1 + VG_(strlen)(info->executable_path); 372 } 373 374 /* Darwin mach_header */ 375 if (info->dynamic) auxsize += sizeof(Word); 376 377 /* OK, now we know how big the client stack is */ 378 stacksize = 379 sizeof(Word) + /* argc */ 380 sizeof(HChar **) + /* argc[0] == exename */ 381 sizeof(HChar **)*argc + /* argv */ 382 sizeof(HChar **) + /* terminal NULL */ 383 sizeof(HChar **)*envc + /* envp */ 384 sizeof(HChar **) + /* terminal NULL */ 385 auxsize + /* auxv */ 386 VG_ROUNDUP(stringsize, sizeof(Word)); /* strings (aligned) */ 387 388 if (0) VG_(printf)("stacksize = %d\n", stacksize); 389 390 /* client_SP is the client's stack pointer */ 391 client_SP = clstack_end + 1 - stacksize; 392 client_SP = VG_ROUNDDN(client_SP, 32); /* make stack 32 byte aligned */ 393 394 /* base of the string table (aligned) */ 395 stringbase = strtab = (HChar *)clstack_end 396 - VG_ROUNDUP(stringsize, sizeof(int)); 397 398 /* The max stack size */ 399 clstack_max_size = VG_PGROUNDUP(clstack_max_size); 400 401 /* Darwin stack is chosen by the ume loader */ 402 clstack_start = clstack_end + 1 - clstack_max_size; 403 404 /* Record stack extent -- needed for stack-change code. */ 405 /* GrP fixme really? */ 406 VG_(clstk_start_base) = clstack_start; 407 VG_(clstk_end) = clstack_end; 408 409 if (0) 410 VG_(printf)("stringsize=%d auxsize=%d stacksize=%d maxsize=0x%x\n" 411 "clstack_start %p\n" 412 "clstack_end %p\n", 413 stringsize, auxsize, stacksize, (Int)clstack_max_size, 414 (void*)clstack_start, (void*)clstack_end); 415 416 /* ==================== allocate space ==================== */ 417 418 /* Stack was allocated by the ume loader. */ 419 420 /* ==================== create client stack ==================== */ 421 422 ptr = (Addr*)client_SP; 423 424 /* --- mach_header --- */ 425 if (info->dynamic) *ptr++ = info->text; 426 427 /* --- client argc --- */ 428 *ptr++ = (Addr)(argc + 1); 429 430 /* --- client argv --- */ 431 if (info->interp_name) 432 *ptr++ = (Addr)copy_str(&strtab, info->interp_name); 433 if (info->interp_args) 434 *ptr++ = (Addr)copy_str(&strtab, info->interp_args); 435 436 *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename)); 437 438 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { 439 *ptr++ = (Addr)copy_str( 440 &strtab, 441 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ) 442 ); 443 } 444 *ptr++ = 0; 445 446 /* --- envp --- */ 447 VG_(client_envp) = (HChar **)ptr; 448 for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++) 449 *ptr = (Addr)copy_str(&strtab, *cpp); 450 *ptr++ = 0; 451 452 /* --- executable_path + NULL --- */ 453 if (info->executable_path) 454 *ptr++ = (Addr)copy_str(&strtab, info->executable_path); 455 else 456 *ptr++ = 0; 457 *ptr++ = 0; 458 459 vg_assert((strtab-stringbase) == stringsize); 460 461 /* client_SP is pointing at client's argc/argv */ 462 463 if (0) VG_(printf)("startup SP = %#lx\n", client_SP); 464 return client_SP; 465 } 466 467 468 /*====================================================================*/ 469 /*=== Record system memory regions ===*/ 470 /*====================================================================*/ 471 472 static void record_system_memory(void) 473 { 474 /* JRS 2014-Jul-08: this messes up the sync checker, because the 475 information that the kernel gives us doesn't include anything 476 about the commpage mapping. This functionality has therefore 477 been moved to m_main.c, valgrind_main(), section "Tell the tool 478 about the initial client memory permissions". See comments there 479 for rationale. */ 480 return; 481 /*NOTREACHED*/ 482 483 /* Tell aspacem where the client's kernel commpage is */ 484 #if defined(VGA_amd64) 485 /* commpage 0x7fff:ffe00000+ - not in vm_region */ 486 // GrP fixme check again 487 VG_(am_notify_client_mmap)(0x7fffffe00000, 0x7ffffffff000-0x7fffffe00000, 488 VKI_PROT_READ|VKI_PROT_EXEC, 0, -1, 0); 489 490 #elif defined(VGA_x86) 491 /* commpage 0xfffec000+ - not in vm_region */ 492 // GrP fixme check again 493 VG_(am_notify_client_mmap)(0xfffec000, 0xfffff000-0xfffec000, 494 VKI_PROT_READ|VKI_PROT_EXEC, 0, -1, 0); 495 496 #else 497 # error unknown architecture 498 #endif 499 } 500 501 502 /*====================================================================*/ 503 /*=== TOP-LEVEL: VG_(ii_create_image) ===*/ 504 /*====================================================================*/ 505 506 /* Create the client's initial memory image. */ 507 IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii, 508 const VexArchInfo* vex_archinfo ) 509 { 510 ExeInfo info; 511 VG_(memset)( &info, 0, sizeof(info) ); 512 513 HChar** env = NULL; 514 515 IIFinaliseImageInfo iifii; 516 VG_(memset)( &iifii, 0, sizeof(iifii) ); 517 518 //-------------------------------------------------------------- 519 // Load client executable, finding in $PATH if necessary 520 // p: get_helprequest_and_toolname() [for 'exec', 'need_help'] 521 // p: layout_remaining_space [so there's space] 522 //-------------------------------------------------------------- 523 VG_(debugLog)(1, "initimg", "Loading client\n"); 524 525 if (VG_(args_the_exename) == NULL) 526 VG_(err_missing_prog)(); 527 528 load_client(&info, &iifii.initial_client_IP); 529 530 //-------------------------------------------------------------- 531 // Set up client's environment 532 // p: set-libdir [for VG_(libdir)] 533 // p: get_helprequest_and_toolname [for toolname] 534 //-------------------------------------------------------------- 535 VG_(debugLog)(1, "initimg", "Setup client env\n"); 536 env = setup_client_env(iicii.envp, iicii.toolname); 537 538 //-------------------------------------------------------------- 539 // Setup client stack, eip, and VG_(client_arg[cv]) 540 // p: load_client() [for 'info'] 541 // p: fix_environment() [for 'env'] 542 //-------------------------------------------------------------- 543 iicii.clstack_end = info.stack_end; 544 iifii.clstack_max_size = info.stack_end - info.stack_start + 1; 545 546 iifii.initial_client_SP = 547 setup_client_stack( iicii.argv - 1, env, &info, 548 iicii.clstack_end, iifii.clstack_max_size, 549 vex_archinfo ); 550 551 VG_(free)(env); 552 553 VG_(debugLog)(2, "initimg", 554 "Client info: " 555 "initial_IP=%p initial_SP=%p stack=[%p..%p]\n", 556 (void*)(iifii.initial_client_IP), 557 (void*)(iifii.initial_client_SP), 558 (void*)(info.stack_start), 559 (void*)(info.stack_end)); 560 561 562 // Tell aspacem about commpage, etc 563 record_system_memory(); 564 565 VG_(free)(info.interp_name); info.interp_name = NULL; 566 VG_(free)(info.interp_args); info.interp_args = NULL; 567 return iifii; 568 } 569 570 571 /*====================================================================*/ 572 /*=== TOP-LEVEL: VG_(ii_finalise_image) ===*/ 573 /*====================================================================*/ 574 575 /* Just before starting the client, we may need to make final 576 adjustments to its initial image. Also we need to set up the VEX 577 guest state for thread 1 (the root thread) and copy in essential 578 starting values. This is handed the IIFinaliseImageInfo created by 579 VG_(ii_create_image). 580 */ 581 void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii ) 582 { 583 ThreadArchState* arch = &VG_(threads)[1].arch; 584 585 /* GrP fixme doesn't handle all registers from LC_THREAD or LC_UNIXTHREAD */ 586 587 # if defined(VGP_x86_darwin) 588 vg_assert(0 == sizeof(VexGuestX86State) % 16); 589 590 /* Zero out the initial state, and set up the simulated FPU in a 591 sane way. */ 592 LibVEX_GuestX86_initialise(&arch->vex); 593 594 /* Zero out the shadow areas. */ 595 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State)); 596 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State)); 597 598 /* Put essential stuff into the new state. */ 599 arch->vex.guest_ESP = iifii.initial_client_SP; 600 arch->vex.guest_EIP = iifii.initial_client_IP; 601 602 # elif defined(VGP_amd64_darwin) 603 vg_assert(0 == sizeof(VexGuestAMD64State) % 16); 604 605 /* Zero out the initial state, and set up the simulated FPU in a 606 sane way. */ 607 LibVEX_GuestAMD64_initialise(&arch->vex); 608 609 /* Zero out the shadow areas. */ 610 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestAMD64State)); 611 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State)); 612 613 /* Put essential stuff into the new state. */ 614 arch->vex.guest_RSP = iifii.initial_client_SP; 615 arch->vex.guest_RIP = iifii.initial_client_IP; 616 617 # else 618 # error Unknown platform 619 # endif 620 621 /* Tell the tool that we just wrote to the registers. */ 622 VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0, 623 sizeof(VexGuestArchState)); 624 } 625 626 #endif // defined(VGO_darwin) 627 628 /*--------------------------------------------------------------------*/ 629 /*--- end ---*/ 630 /*--------------------------------------------------------------------*/ 631