1 2/*--------------------------------------------------------------------*/ 3/*--- Startup: create initial process image on Linux ---*/ 4/*--- initimg-linux.c ---*/ 5/*--------------------------------------------------------------------*/ 6 7/* 8 This file is part of Valgrind, a dynamic binary instrumentation 9 framework. 10 11 Copyright (C) 2000-2013 Julian Seward 12 jseward@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_linux) 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_syscall.h" 50#include "pub_core_tooliface.h" /* VG_TRACK */ 51#include "pub_core_threadstate.h" /* ThreadArchState */ 52#include "priv_initimg_pathscan.h" 53#include "pub_core_initimg.h" /* self */ 54 55/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */ 56#define _GNU_SOURCE 57#define _FILE_OFFSET_BITS 64 58/* This is for ELF types etc, and also the AT_ constants. */ 59#include <elf.h> 60/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */ 61 62 63/*====================================================================*/ 64/*=== Loading the client ===*/ 65/*====================================================================*/ 66 67/* Load the client whose name is VG_(argv_the_exename). */ 68 69static void load_client ( /*OUT*/ExeInfo* info, 70 /*OUT*/Addr* client_ip, 71 /*OUT*/Addr* client_toc) 72{ 73 const HChar* exe_name; 74 Int ret; 75 SysRes res; 76 77 vg_assert( VG_(args_the_exename) != NULL); 78 exe_name = ML_(find_executable)( VG_(args_the_exename) ); 79 80 if (!exe_name) { 81 VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename)); 82 VG_(exit)(127); // 127 is Posix NOTFOUND 83 } 84 85 VG_(memset)(info, 0, sizeof(*info)); 86 ret = VG_(do_exec)(exe_name, info); 87 if (ret < 0) { 88 VG_(printf)("valgrind: could not execute '%s'\n", exe_name); 89 VG_(exit)(1); 90 } 91 92 // The client was successfully loaded! Continue. 93 94 /* Get hold of a file descriptor which refers to the client 95 executable. This is needed for attaching to GDB. */ 96 res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR); 97 if (!sr_isError(res)) 98 VG_(cl_exec_fd) = sr_Res(res); 99 100 /* Copy necessary bits of 'info' that were filled in */ 101 *client_ip = info->init_ip; 102 *client_toc = info->init_toc; 103 VG_(brk_base) = VG_(brk_limit) = VG_PGROUNDUP(info->brkbase); 104} 105 106 107/*====================================================================*/ 108/*=== Setting up the client's environment ===*/ 109/*====================================================================*/ 110 111/* Prepare the client's environment. This is basically a copy of our 112 environment, except: 113 114 LD_PRELOAD=$VALGRIND_LIB/vgpreload_core-PLATFORM.so: 115 ($VALGRIND_LIB/vgpreload_TOOL-PLATFORM.so:)? 116 $LD_PRELOAD 117 118 If this is missing, then it is added. 119 120 Also, remove any binding for VALGRIND_LAUNCHER=. The client should 121 not be able to see this. 122 123 If this needs to handle any more variables it should be hacked 124 into something table driven. The copy is VG_(malloc)'d space. 125*/ 126static HChar** setup_client_env ( HChar** origenv, const HChar* toolname) 127{ 128 vg_assert(origenv); 129 vg_assert(toolname); 130 131 const HChar* preload_core = "vgpreload_core"; 132 const HChar* ld_preload = "LD_PRELOAD="; 133 const HChar* v_launcher = VALGRIND_LAUNCHER "="; 134 Int ld_preload_len = VG_(strlen)( ld_preload ); 135 Int v_launcher_len = VG_(strlen)( v_launcher ); 136 Bool ld_preload_done = False; 137 Int vglib_len = VG_(strlen)(VG_(libdir)); 138 Bool debug = False; 139 140 HChar** cpp; 141 HChar** ret; 142 HChar* preload_tool_path; 143 Int envc, i; 144 145 /* Alloc space for the vgpreload_core.so path and vgpreload_<tool>.so 146 paths. We might not need the space for vgpreload_<tool>.so, but it 147 doesn't hurt to over-allocate briefly. The 16s are just cautious 148 slop. */ 149 Int preload_core_path_len = vglib_len + sizeof(preload_core) 150 + sizeof(VG_PLATFORM) + 16; 151 Int preload_tool_path_len = vglib_len + VG_(strlen)(toolname) 152 + sizeof(VG_PLATFORM) + 16; 153 Int preload_string_len = preload_core_path_len + preload_tool_path_len; 154 HChar* preload_string = VG_(malloc)("initimg-linux.sce.1", 155 preload_string_len); 156 /* Determine if there's a vgpreload_<tool>_<platform>.so file, and setup 157 preload_string. */ 158 preload_tool_path = VG_(malloc)("initimg-linux.sce.2", preload_tool_path_len); 159 VG_(snprintf)(preload_tool_path, preload_tool_path_len, 160 "%s/vgpreload_%s-%s.so", VG_(libdir), toolname, VG_PLATFORM); 161 if (VG_(access)(preload_tool_path, True/*r*/, False/*w*/, False/*x*/) == 0) { 162 VG_(snprintf)(preload_string, preload_string_len, "%s/%s-%s.so:%s", 163 VG_(libdir), preload_core, VG_PLATFORM, preload_tool_path); 164 } else { 165 VG_(snprintf)(preload_string, preload_string_len, "%s/%s-%s.so", 166 VG_(libdir), preload_core, VG_PLATFORM); 167 } 168 VG_(free)(preload_tool_path); 169 170 VG_(debugLog)(2, "initimg", "preload_string:\n"); 171 VG_(debugLog)(2, "initimg", " \"%s\"\n", preload_string); 172 173 /* Count the original size of the env */ 174 if (debug) VG_(printf)("\n\n"); 175 envc = 0; 176 for (cpp = origenv; cpp && *cpp; cpp++) { 177 envc++; 178 if (debug) VG_(printf)("XXXXXXXXX: BEFORE %s\n", *cpp); 179 } 180 181 /* Allocate a new space */ 182 ret = VG_(malloc) ("initimg-linux.sce.3", 183 sizeof(HChar *) * (envc+1+1)); /* 1 new entry + NULL */ 184 185 /* copy it over */ 186 for (cpp = ret; *origenv; ) { 187 if (debug) VG_(printf)("XXXXXXXXX: COPY %s\n", *origenv); 188 *cpp++ = *origenv++; 189 } 190 *cpp = NULL; 191 192 vg_assert(envc == (cpp - ret)); 193 194 /* Walk over the new environment, mashing as we go */ 195 for (cpp = ret; cpp && *cpp; cpp++) { 196 if (VG_(memcmp)(*cpp, ld_preload, ld_preload_len) == 0) { 197 Int len = VG_(strlen)(*cpp) + preload_string_len; 198 HChar *cp = VG_(malloc)("initimg-linux.sce.4", len); 199 200 VG_(snprintf)(cp, len, "%s%s:%s", 201 ld_preload, preload_string, (*cpp)+ld_preload_len); 202 203 *cpp = cp; 204 205 ld_preload_done = True; 206 } 207 if (debug) VG_(printf)("XXXXXXXXX: MASH %s\n", *cpp); 208 } 209 210 /* Add the missing bits */ 211 if (!ld_preload_done) { 212 Int len = ld_preload_len + preload_string_len; 213 HChar *cp = VG_(malloc) ("initimg-linux.sce.5", len); 214 215 VG_(snprintf)(cp, len, "%s%s", ld_preload, preload_string); 216 217 ret[envc++] = cp; 218 if (debug) VG_(printf)("XXXXXXXXX: ADD %s\n", cp); 219 } 220 221 /* ret[0 .. envc-1] is live now. */ 222 /* Find and remove a binding for VALGRIND_LAUNCHER. */ 223 for (i = 0; i < envc; i++) 224 if (0 == VG_(memcmp(ret[i], v_launcher, v_launcher_len))) 225 break; 226 227 if (i < envc) { 228 for (; i < envc-1; i++) 229 ret[i] = ret[i+1]; 230 envc--; 231 } 232 233 VG_(free)(preload_string); 234 ret[envc] = NULL; 235 236 for (i = 0; i < envc; i++) { 237 if (debug) VG_(printf)("XXXXXXXXX: FINAL %s\n", ret[i]); 238 } 239 240 return ret; 241} 242 243 244/*====================================================================*/ 245/*=== Setting up the client's stack ===*/ 246/*====================================================================*/ 247 248#ifndef AT_DCACHEBSIZE 249#define AT_DCACHEBSIZE 19 250#endif /* AT_DCACHEBSIZE */ 251 252#ifndef AT_ICACHEBSIZE 253#define AT_ICACHEBSIZE 20 254#endif /* AT_ICACHEBSIZE */ 255 256#ifndef AT_UCACHEBSIZE 257#define AT_UCACHEBSIZE 21 258#endif /* AT_UCACHEBSIZE */ 259 260#ifndef AT_BASE_PLATFORM 261#define AT_BASE_PLATFORM 24 262#endif /* AT_BASE_PLATFORM */ 263 264#ifndef AT_RANDOM 265#define AT_RANDOM 25 266#endif /* AT_RANDOM */ 267 268#ifndef AT_HWCAP2 269#define AT_HWCAP2 26 270#endif /* AT_HWCAP2 */ 271 272#ifndef AT_EXECFN 273#define AT_EXECFN 31 274#endif /* AT_EXECFN */ 275 276#ifndef AT_SYSINFO 277#define AT_SYSINFO 32 278#endif /* AT_SYSINFO */ 279 280#ifndef AT_SYSINFO_EHDR 281#define AT_SYSINFO_EHDR 33 282#endif /* AT_SYSINFO_EHDR */ 283 284#ifndef AT_SECURE 285#define AT_SECURE 23 /* secure mode boolean */ 286#endif /* AT_SECURE */ 287 288/* Add a string onto the string table, and return its address */ 289static HChar *copy_str(HChar **tab, const HChar *str) 290{ 291 HChar *cp = *tab; 292 HChar *orig = cp; 293 294 while(*str) 295 *cp++ = *str++; 296 *cp++ = '\0'; 297 298 if (0) 299 VG_(printf)("copied %p \"%s\" len %lld\n", orig, orig, (Long)(cp-orig)); 300 301 *tab = cp; 302 303 return orig; 304} 305 306 307/* ---------------------------------------------------------------- 308 309 This sets up the client's initial stack, containing the args, 310 environment and aux vector. 311 312 The format of the stack is: 313 314 higher address +-----------------+ <- clstack_end 315 | | 316 : string table : 317 | | 318 +-----------------+ 319 | AT_NULL | 320 - - 321 | auxv | 322 +-----------------+ 323 | NULL | 324 - - 325 | envp | 326 +-----------------+ 327 | NULL | 328 - - 329 | argv | 330 +-----------------+ 331 | argc | 332 lower address +-----------------+ <- sp 333 | undefined | 334 : : 335 336 Allocate and create the initial client stack. It is allocated down 337 from clstack_end, which was previously determined by the address 338 space manager. The returned value is the SP value for the client. 339 340 The client's auxv is created by copying and modifying our own one. 341 As a side effect of scanning our own auxv, some important bits of 342 info are collected: 343 344 VG_(cache_line_size_ppc32) // ppc32 only -- cache line size 345 VG_(have_altivec_ppc32) // ppc32 only -- is Altivec supported? 346 347 ---------------------------------------------------------------- */ 348 349struct auxv 350{ 351 Word a_type; 352 union { 353 void *a_ptr; 354 Word a_val; 355 } u; 356}; 357 358static 359struct auxv *find_auxv(UWord* sp) 360{ 361 sp++; // skip argc (Nb: is word-sized, not int-sized!) 362 363 while (*sp != 0) // skip argv 364 sp++; 365 sp++; 366 367 while (*sp != 0) // skip env 368 sp++; 369 sp++; 370 371#if defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 372# if defined AT_IGNOREPPC 373 while (*sp == AT_IGNOREPPC) // skip AT_IGNOREPPC entries 374 sp += 2; 375# endif 376#endif 377 378 return (struct auxv *)sp; 379} 380 381static 382Addr setup_client_stack( void* init_sp, 383 HChar** orig_envp, 384 const ExeInfo* info, 385 UInt** client_auxv, 386 Addr clstack_end, 387 SizeT clstack_max_size, 388 const VexArchInfo* vex_archinfo ) 389{ 390 /* The HW configuration setting (hwcaps) of the target can be 391 * checked against the Vex settings of the host platform as given 392 * by the values in vex_archinfo. 393 */ 394 395 SysRes res; 396 HChar **cpp; 397 HChar *strtab; /* string table */ 398 HChar *stringbase; 399 Addr *ptr; 400 struct auxv *auxv; 401 const struct auxv *orig_auxv; 402 const struct auxv *cauxv; 403 unsigned stringsize; /* total size of strings in bytes */ 404 unsigned auxsize; /* total size of auxv in bytes */ 405 Int argc; /* total argc */ 406 Int envc; /* total number of env vars */ 407 unsigned stacksize; /* total client stack size */ 408 Addr client_SP; /* client stack base (initial SP) */ 409 Addr clstack_start; 410 Int i; 411 412 vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1)); 413 vg_assert( VG_(args_for_client) ); 414 415 /* use our own auxv as a prototype */ 416 orig_auxv = find_auxv(init_sp); 417 418 /* ==================== compute sizes ==================== */ 419 420 /* first of all, work out how big the client stack will be */ 421 stringsize = 0; 422 423 /* paste on the extra args if the loader needs them (ie, the #! 424 interpreter and its argument) */ 425 argc = 0; 426 if (info->interp_name != NULL) { 427 argc++; 428 stringsize += VG_(strlen)(info->interp_name) + 1; 429 } 430 if (info->interp_args != NULL) { 431 argc++; 432 stringsize += VG_(strlen)(info->interp_args) + 1; 433 } 434 435 /* now scan the args we're given... */ 436 stringsize += VG_(strlen)( VG_(args_the_exename) ) + 1; 437 438 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { 439 argc++; 440 stringsize += VG_(strlen)( * (HChar**) 441 VG_(indexXA)( VG_(args_for_client), i )) 442 + 1; 443 } 444 445 /* ...and the environment */ 446 envc = 0; 447 for (cpp = orig_envp; cpp && *cpp; cpp++) { 448 envc++; 449 stringsize += VG_(strlen)(*cpp) + 1; 450 } 451 452 /* now, how big is the auxv? */ 453 auxsize = sizeof(*auxv); /* there's always at least one entry: AT_NULL */ 454 for (cauxv = orig_auxv; cauxv->a_type != AT_NULL; cauxv++) { 455 if (cauxv->a_type == AT_PLATFORM || 456 cauxv->a_type == AT_BASE_PLATFORM) 457 stringsize += VG_(strlen)(cauxv->u.a_ptr) + 1; 458 else if (cauxv->a_type == AT_RANDOM) 459 stringsize += 16; 460 else if (cauxv->a_type == AT_EXECFN) 461 stringsize += VG_(strlen)(VG_(args_the_exename)) + 1; 462 auxsize += sizeof(*cauxv); 463 } 464 465# if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \ 466 || defined(VGP_ppc64le_linux) 467 auxsize += 2 * sizeof(*cauxv); 468# endif 469 470 /* OK, now we know how big the client stack is */ 471 stacksize = 472 sizeof(Word) + /* argc */ 473 sizeof(HChar **) + /* argc[0] == exename */ 474 sizeof(HChar **)*argc + /* argv */ 475 sizeof(HChar **) + /* terminal NULL */ 476 sizeof(HChar **)*envc + /* envp */ 477 sizeof(HChar **) + /* terminal NULL */ 478 auxsize + /* auxv */ 479 VG_ROUNDUP(stringsize, sizeof(Word)); /* strings (aligned) */ 480 481 if (0) VG_(printf)("stacksize = %d\n", stacksize); 482 483 /* client_SP is the client's stack pointer */ 484 client_SP = clstack_end - stacksize; 485 client_SP = VG_ROUNDDN(client_SP, 16); /* make stack 16 byte aligned */ 486 487 /* base of the string table (aligned) */ 488 stringbase = strtab = (HChar *)clstack_end 489 - VG_ROUNDUP(stringsize, sizeof(int)); 490 491 clstack_start = VG_PGROUNDDN(client_SP); 492 493 /* The max stack size */ 494 clstack_max_size = VG_PGROUNDUP(clstack_max_size); 495 496 if (0) 497 VG_(printf)("stringsize=%d auxsize=%d stacksize=%d maxsize=0x%x\n" 498 "clstack_start %p\n" 499 "clstack_end %p\n", 500 stringsize, auxsize, stacksize, (Int)clstack_max_size, 501 (void*)clstack_start, (void*)clstack_end); 502 503 /* ==================== allocate space ==================== */ 504 505 { SizeT anon_size = clstack_end - clstack_start + 1; 506 SizeT resvn_size = clstack_max_size - anon_size; 507 Addr anon_start = clstack_start; 508 Addr resvn_start = anon_start - resvn_size; 509 SizeT inner_HACK = 0; 510 Bool ok; 511 512 /* So far we've only accounted for space requirements down to the 513 stack pointer. If this target's ABI requires a redzone below 514 the stack pointer, we need to allocate an extra page, to 515 handle the worst case in which the stack pointer is almost at 516 the bottom of a page, and so there is insufficient room left 517 over to put the redzone in. In this case the simple thing to 518 do is allocate an extra page, by shrinking the reservation by 519 one page and growing the anonymous area by a corresponding 520 page. */ 521 vg_assert(VG_STACK_REDZONE_SZB >= 0); 522 vg_assert(VG_STACK_REDZONE_SZB < VKI_PAGE_SIZE); 523 if (VG_STACK_REDZONE_SZB > 0) { 524 vg_assert(resvn_size > VKI_PAGE_SIZE); 525 resvn_size -= VKI_PAGE_SIZE; 526 anon_start -= VKI_PAGE_SIZE; 527 anon_size += VKI_PAGE_SIZE; 528 } 529 530 vg_assert(VG_IS_PAGE_ALIGNED(anon_size)); 531 vg_assert(VG_IS_PAGE_ALIGNED(resvn_size)); 532 vg_assert(VG_IS_PAGE_ALIGNED(anon_start)); 533 vg_assert(VG_IS_PAGE_ALIGNED(resvn_start)); 534 vg_assert(resvn_start == clstack_end + 1 - clstack_max_size); 535 536# ifdef ENABLE_INNER 537 inner_HACK = 1024*1024; // create 1M non-fault-extending stack 538# endif 539 540 if (0) 541 VG_(printf)("%#lx 0x%lx %#lx 0x%lx\n", 542 resvn_start, resvn_size, anon_start, anon_size); 543 544 /* Create a shrinkable reservation followed by an anonymous 545 segment. Together these constitute a growdown stack. */ 546 res = VG_(mk_SysRes_Error)(0); 547 ok = VG_(am_create_reservation)( 548 resvn_start, 549 resvn_size -inner_HACK, 550 SmUpper, 551 anon_size +inner_HACK 552 ); 553 if (ok) { 554 /* allocate a stack - mmap enough space for the stack */ 555 res = VG_(am_mmap_anon_fixed_client)( 556 anon_start -inner_HACK, 557 anon_size +inner_HACK, 558 info->stack_prot 559 ); 560 } 561 if ((!ok) || sr_isError(res)) { 562 /* Allocation of the stack failed. We have to stop. */ 563 VG_(printf)("valgrind: " 564 "I failed to allocate space for the application's stack.\n"); 565 VG_(printf)("valgrind: " 566 "This may be the result of a very large --main-stacksize=\n"); 567 VG_(printf)("valgrind: setting. Cannot continue. Sorry.\n\n"); 568 VG_(exit)(1); 569 } 570 571 vg_assert(ok); 572 vg_assert(!sr_isError(res)); 573 574 /* Record stack extent -- needed for stack-change code. */ 575 VG_(clstk_start_base) = anon_start -inner_HACK; 576 VG_(clstk_end) = VG_(clstk_start_base) + anon_size +inner_HACK -1; 577 578 } 579 580 /* ==================== create client stack ==================== */ 581 582 ptr = (Addr*)client_SP; 583 584 /* --- client argc --- */ 585 *ptr++ = argc + 1; 586 587 /* --- client argv --- */ 588 if (info->interp_name) { 589 *ptr++ = (Addr)copy_str(&strtab, info->interp_name); 590 VG_(free)(info->interp_name); 591 } 592 if (info->interp_args) { 593 *ptr++ = (Addr)copy_str(&strtab, info->interp_args); 594 VG_(free)(info->interp_args); 595 } 596 597 *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename)); 598 599 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { 600 *ptr++ = (Addr)copy_str( 601 &strtab, 602 * (HChar**) VG_(indexXA)( VG_(args_for_client), i ) 603 ); 604 } 605 *ptr++ = 0; 606 607 /* --- envp --- */ 608 VG_(client_envp) = (HChar **)ptr; 609 for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++) 610 *ptr = (Addr)copy_str(&strtab, *cpp); 611 *ptr++ = 0; 612 613 /* --- auxv --- */ 614 auxv = (struct auxv *)ptr; 615 *client_auxv = (UInt *)auxv; 616 VG_(client_auxv) = (UWord *)*client_auxv; 617 // ??? According to 'man proc', auxv is a array of unsigned long 618 // terminated by two zeros. Why is valgrind working with UInt ? 619 // We do not take ULong* (as ULong 8 bytes on a 32 bits), 620 // => we take UWord* 621 622# if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \ 623 || defined(VGP_ppc64le_linux) 624 auxv[0].a_type = AT_IGNOREPPC; 625 auxv[0].u.a_val = AT_IGNOREPPC; 626 auxv[1].a_type = AT_IGNOREPPC; 627 auxv[1].u.a_val = AT_IGNOREPPC; 628 auxv += 2; 629# endif 630 631 for (; orig_auxv->a_type != AT_NULL; auxv++, orig_auxv++) { 632 633 /* copy the entry... */ 634 *auxv = *orig_auxv; 635 636 /* ...and fix up / examine the copy */ 637 switch(auxv->a_type) { 638 639 case AT_IGNORE: 640 case AT_PHENT: 641 case AT_PAGESZ: 642 case AT_FLAGS: 643 case AT_NOTELF: 644 case AT_UID: 645 case AT_EUID: 646 case AT_GID: 647 case AT_EGID: 648 case AT_CLKTCK: 649# if !defined(__ANDROID__) 650 case AT_FPUCW: /* missing on android */ 651# endif 652 /* All these are pointerless, so we don't need to do 653 anything about them. */ 654 break; 655 656 case AT_PHDR: 657 if (info->phdr == 0) 658 auxv->a_type = AT_IGNORE; 659 else 660 auxv->u.a_val = info->phdr; 661 break; 662 663 case AT_PHNUM: 664 if (info->phdr == 0) 665 auxv->a_type = AT_IGNORE; 666 else 667 auxv->u.a_val = info->phnum; 668 break; 669 670 case AT_BASE: 671 auxv->u.a_val = info->interp_offset; 672 break; 673 674 case AT_PLATFORM: 675 case AT_BASE_PLATFORM: 676 /* points to a platform description string */ 677 auxv->u.a_ptr = copy_str(&strtab, orig_auxv->u.a_ptr); 678 break; 679 680 case AT_ENTRY: 681 auxv->u.a_val = info->entry; 682 break; 683 684 case AT_HWCAP: 685# if defined(VGP_arm_linux) 686 { Bool has_neon = (auxv->u.a_val & VKI_HWCAP_NEON) > 0; 687 VG_(debugLog)(2, "initimg", 688 "ARM has-neon from-auxv: %s\n", 689 has_neon ? "YES" : "NO"); 690 VG_(machine_arm_set_has_NEON)( has_neon ); 691 #define VKI_HWCAP_TLS 32768 692 Bool has_tls = (auxv->u.a_val & VKI_HWCAP_TLS) > 0; 693 VG_(debugLog)(2, "initimg", 694 "ARM has-tls from-auxv: %s\n", 695 has_tls ? "YES" : "NO"); 696 /* If real hw sets properly HWCAP_TLS, we might 697 use this info to decide to really execute set_tls syscall 698 in syswrap-arm-linux.c rather than to base this on 699 conditional compilation. */ 700 } 701# endif 702 break; 703# if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 704 case AT_HWCAP2: { 705 Bool auxv_2_07, hw_caps_2_07; 706 /* The HWCAP2 field may contain an arch_2_07 entry that indicates 707 * if the processor is compliant with the 2.07 ISA. (i.e. Power 8 708 * or beyond). The Valgrind vai.hwcaps value 709 * (coregrind/m_machine.c) has the VEX_HWCAPS_PPC64_ISA2_07 710 * flag set so Valgrind knows about Power8. Need to pass the 711 * HWCAP2 value along so the user level programs can detect that 712 * the processor supports ISA 2.07 and beyond. 713 */ 714 /* Power Architecture 64-Bit ELF V2 ABI Specification 715 July 21, 2014, version 1.0, Page 124 716 www-03.ibm.com/technologyconnect/tgcm/TGCMServlet.wss?alias=OpenPOWER&linkid=1n0000 717 718 AT_HWCAP2 719 The a_val member of this entry is a bit map of hardware 720 capabilities. Some bit mask values include: 721 722 PPC_FEATURE2_ARCH_2_07 0x80000000 723 PPC_FEATURE2_HAS_HTM 0x40000000 724 PPC_FEATURE2_HAS_DSCR 0x20000000 725 PPC_FEATURE2_HAS_EBB 0x10000000 726 PPC_FEATURE2_HAS_ISEL 0x08000000 727 PPC_FEATURE2_HAS_TAR 0x04000000 728 PPC_FEATURE2_HAS_VCRYPTO 0x02000000 729 */ 730 auxv_2_07 = (auxv->u.a_val & 0x80000000ULL) == 0x80000000ULL; 731 hw_caps_2_07 = (vex_archinfo->hwcaps & VEX_HWCAPS_PPC64_ISA2_07) 732 == VEX_HWCAPS_PPC64_ISA2_07; 733 734 /* Verify the PPC_FEATURE2_ARCH_2_07 setting in HWCAP2 735 * matches the setting in VEX HWCAPS. 736 */ 737 vg_assert(auxv_2_07 == hw_caps_2_07); 738 } 739 740 break; 741# endif 742 743 case AT_ICACHEBSIZE: 744 case AT_DCACHEBSIZE: 745 case AT_UCACHEBSIZE: 746# if defined(VGP_ppc32_linux) 747 /* acquire cache info */ 748 if (auxv->u.a_val > 0) { 749 VG_(machine_ppc32_set_clszB)( auxv->u.a_val ); 750 VG_(debugLog)(2, "initimg", 751 "PPC32 icache line size %u (type %u)\n", 752 (UInt)auxv->u.a_val, (UInt)auxv->a_type ); 753 } 754# elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 755 /* acquire cache info */ 756 if (auxv->u.a_val > 0) { 757 VG_(machine_ppc64_set_clszB)( auxv->u.a_val ); 758 VG_(debugLog)(2, "initimg", 759 "PPC64 icache line size %u (type %u)\n", 760 (UInt)auxv->u.a_val, (UInt)auxv->a_type ); 761 } 762# endif 763 break; 764 765# if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \ 766 || defined(VGP_ppc64le_linux) 767 case AT_IGNOREPPC: 768 break; 769# endif 770 771 case AT_SECURE: 772 /* If this is 1, then it means that this program is 773 running suid, and therefore the dynamic linker should 774 be careful about LD_PRELOAD, etc. However, since 775 stage1 (the thing the kernel actually execve's) should 776 never be SUID, and we need LD_PRELOAD to work for the 777 client, we set AT_SECURE to 0. */ 778 auxv->u.a_val = 0; 779 break; 780 781 case AT_SYSINFO: 782 /* Trash this, because we don't reproduce it */ 783 auxv->a_type = AT_IGNORE; 784 break; 785 786# if !defined(VGP_ppc32_linux) && !defined(VGP_ppc64be_linux) \ 787 && !defined(VGP_ppc64le_linux) 788 case AT_SYSINFO_EHDR: { 789 /* Trash this, because we don't reproduce it */ 790 const NSegment* ehdrseg = VG_(am_find_nsegment)((Addr)auxv->u.a_ptr); 791 vg_assert(ehdrseg); 792 VG_(am_munmap_valgrind)(ehdrseg->start, ehdrseg->end - ehdrseg->start); 793 auxv->a_type = AT_IGNORE; 794 break; 795 } 796# endif 797 798 case AT_RANDOM: 799 /* points to 16 random bytes - we need to ensure this is 800 propagated to the client as glibc will assume it is 801 present if it is built for kernel 2.6.29 or later */ 802 auxv->u.a_ptr = strtab; 803 VG_(memcpy)(strtab, orig_auxv->u.a_ptr, 16); 804 strtab += 16; 805 break; 806 807 case AT_EXECFN: 808 /* points to the executable filename */ 809 auxv->u.a_ptr = copy_str(&strtab, VG_(args_the_exename)); 810 break; 811 812 default: 813 /* stomp out anything we don't know about */ 814 VG_(debugLog)(2, "initimg", 815 "stomping auxv entry %lld\n", 816 (ULong)auxv->a_type); 817 auxv->a_type = AT_IGNORE; 818 break; 819 } 820 } 821 *auxv = *orig_auxv; 822 vg_assert(auxv->a_type == AT_NULL); 823 824 vg_assert((strtab-stringbase) == stringsize); 825 826 /* client_SP is pointing at client's argc/argv */ 827 828 if (0) VG_(printf)("startup SP = %#lx\n", client_SP); 829 return client_SP; 830} 831 832 833/* Allocate the client data segment. It is an expandable anonymous 834 mapping abutting a shrinkable reservation of size max_dseg_size. 835 The data segment starts at VG_(brk_base), which is page-aligned, 836 and runs up to VG_(brk_limit), which isn't. */ 837 838static void setup_client_dataseg ( SizeT max_size ) 839{ 840 Bool ok; 841 SysRes sres; 842 Addr anon_start = VG_(brk_base); 843 SizeT anon_size = VKI_PAGE_SIZE; 844 Addr resvn_start = anon_start + anon_size; 845 SizeT resvn_size = max_size - anon_size; 846 847 vg_assert(VG_IS_PAGE_ALIGNED(anon_size)); 848 vg_assert(VG_IS_PAGE_ALIGNED(resvn_size)); 849 vg_assert(VG_IS_PAGE_ALIGNED(anon_start)); 850 vg_assert(VG_IS_PAGE_ALIGNED(resvn_start)); 851 852 /* Because there's been no brk activity yet: */ 853 vg_assert(VG_(brk_base) == VG_(brk_limit)); 854 855 /* Try to create the data seg and associated reservation where 856 VG_(brk_base) says. */ 857 ok = VG_(am_create_reservation)( 858 resvn_start, 859 resvn_size, 860 SmLower, 861 anon_size 862 ); 863 864 if (!ok) { 865 /* Hmm, that didn't work. Well, let aspacem suggest an address 866 it likes better, and try again with that. */ 867 anon_start = VG_(am_get_advisory_client_simple) 868 ( 0/*floating*/, anon_size+resvn_size, &ok ); 869 if (ok) { 870 resvn_start = anon_start + anon_size; 871 ok = VG_(am_create_reservation)( 872 resvn_start, 873 resvn_size, 874 SmLower, 875 anon_size 876 ); 877 if (ok) 878 VG_(brk_base) = VG_(brk_limit) = anon_start; 879 } 880 /* that too might have failed, but if it has, we're hosed: there 881 is no Plan C. */ 882 } 883 vg_assert(ok); 884 885 /* We make the data segment (heap) executable because LinuxThreads on 886 ppc32 creates trampolines in this area. Also, on x86/Linux the data 887 segment is RWX natively, at least according to /proc/self/maps. 888 Also, having a non-executable data seg would kill any program which 889 tried to create code in the data seg and then run it. */ 890 sres = VG_(am_mmap_anon_fixed_client)( 891 anon_start, 892 anon_size, 893 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC 894 ); 895 vg_assert(!sr_isError(sres)); 896 vg_assert(sr_Res(sres) == anon_start); 897} 898 899 900/*====================================================================*/ 901/*=== TOP-LEVEL: VG_(setup_client_initial_image) ===*/ 902/*====================================================================*/ 903 904/* Create the client's initial memory image. */ 905IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii, 906 const VexArchInfo* vex_archinfo ) 907{ 908 ExeInfo info; 909 HChar** env = NULL; 910 911 IIFinaliseImageInfo iifii; 912 VG_(memset)( &iifii, 0, sizeof(iifii) ); 913 914 //-------------------------------------------------------------- 915 // Load client executable, finding in $PATH if necessary 916 // p: get_helprequest_and_toolname() [for 'exec', 'need_help'] 917 // p: layout_remaining_space [so there's space] 918 //-------------------------------------------------------------- 919 VG_(debugLog)(1, "initimg", "Loading client\n"); 920 921 if (VG_(args_the_exename) == NULL) 922 VG_(err_missing_prog)(); 923 924 load_client(&info, &iifii.initial_client_IP, &iifii.initial_client_TOC); 925 926 //-------------------------------------------------------------- 927 // Set up client's environment 928 // p: set-libdir [for VG_(libdir)] 929 // p: get_helprequest_and_toolname [for toolname] 930 //-------------------------------------------------------------- 931 VG_(debugLog)(1, "initimg", "Setup client env\n"); 932 env = setup_client_env(iicii.envp, iicii.toolname); 933 934 //-------------------------------------------------------------- 935 // Setup client stack, eip, and VG_(client_arg[cv]) 936 // p: load_client() [for 'info'] 937 // p: fix_environment() [for 'env'] 938 //-------------------------------------------------------------- 939 { 940 /* When allocating space for the client stack on Linux, take 941 notice of the --main-stacksize value. This makes it possible 942 to run programs with very large (primary) stack requirements 943 simply by specifying --main-stacksize. */ 944 /* Logic is as follows: 945 - by default, use the client's current stack rlimit 946 - if that exceeds 16M, clamp to 16M 947 - if a larger --main-stacksize value is specified, use that instead 948 - in all situations, the minimum allowed stack size is 1M 949 */ 950 void* init_sp = iicii.argv - 1; 951 SizeT m1 = 1024 * 1024; 952 SizeT m16 = 16 * m1; 953 SizeT szB = (SizeT)VG_(client_rlimit_stack).rlim_cur; 954 if (szB < m1) szB = m1; 955 if (szB > m16) szB = m16; 956 if (VG_(clo_main_stacksize) > 0) szB = VG_(clo_main_stacksize); 957 if (szB < m1) szB = m1; 958 szB = VG_PGROUNDUP(szB); 959 VG_(debugLog)(1, "initimg", 960 "Setup client stack: size will be %ld\n", szB); 961 962 iifii.clstack_max_size = szB; 963 964 iifii.initial_client_SP 965 = setup_client_stack( init_sp, env, 966 &info, &iifii.client_auxv, 967 iicii.clstack_end, iifii.clstack_max_size, 968 vex_archinfo ); 969 970 VG_(free)(env); 971 972 VG_(debugLog)(2, "initimg", 973 "Client info: " 974 "initial_IP=%p initial_TOC=%p brk_base=%p\n", 975 (void*)(iifii.initial_client_IP), 976 (void*)(iifii.initial_client_TOC), 977 (void*)VG_(brk_base) ); 978 VG_(debugLog)(2, "initimg", 979 "Client info: " 980 "initial_SP=%p max_stack_size=%ld\n", 981 (void*)(iifii.initial_client_SP), 982 (SizeT)iifii.clstack_max_size ); 983 } 984 985 //-------------------------------------------------------------- 986 // Setup client data (brk) segment. Initially a 1-page segment 987 // which abuts a shrinkable reservation. 988 // p: load_client() [for 'info' and hence VG_(brk_base)] 989 //-------------------------------------------------------------- 990 { 991 SizeT m1 = 1024 * 1024; 992 SizeT m8 = 8 * m1; 993 SizeT dseg_max_size = (SizeT)VG_(client_rlimit_data).rlim_cur; 994 VG_(debugLog)(1, "initimg", "Setup client data (brk) segment\n"); 995 if (dseg_max_size < m1) dseg_max_size = m1; 996 if (dseg_max_size > m8) dseg_max_size = m8; 997 dseg_max_size = VG_PGROUNDUP(dseg_max_size); 998 999 setup_client_dataseg( dseg_max_size ); 1000 } 1001 1002 return iifii; 1003} 1004 1005 1006/*====================================================================*/ 1007/*=== TOP-LEVEL: VG_(finalise_thread1state) ===*/ 1008/*====================================================================*/ 1009 1010/* Just before starting the client, we may need to make final 1011 adjustments to its initial image. Also we need to set up the VEX 1012 guest state for thread 1 (the root thread) and copy in essential 1013 starting values. This is handed the IIFinaliseImageInfo created by 1014 VG_(ii_create_image). 1015*/ 1016void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii ) 1017{ 1018 ThreadArchState* arch = &VG_(threads)[1].arch; 1019 1020 /* On Linux we get client_{ip/sp/toc}, and start the client with 1021 all other registers zeroed. */ 1022 1023# if defined(VGP_x86_linux) 1024 vg_assert(0 == sizeof(VexGuestX86State) % LibVEX_GUEST_STATE_ALIGN); 1025 1026 /* Zero out the initial state, and set up the simulated FPU in a 1027 sane way. */ 1028 LibVEX_GuestX86_initialise(&arch->vex); 1029 1030 /* Zero out the shadow areas. */ 1031 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State)); 1032 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State)); 1033 1034 /* Put essential stuff into the new state. */ 1035 arch->vex.guest_ESP = iifii.initial_client_SP; 1036 arch->vex.guest_EIP = iifii.initial_client_IP; 1037 1038 /* initialise %cs, %ds and %ss to point at the operating systems 1039 default code, data and stack segments. Also %es (see #291253). */ 1040 asm volatile("movw %%cs, %0" : : "m" (arch->vex.guest_CS)); 1041 asm volatile("movw %%ds, %0" : : "m" (arch->vex.guest_DS)); 1042 asm volatile("movw %%ss, %0" : : "m" (arch->vex.guest_SS)); 1043 asm volatile("movw %%es, %0" : : "m" (arch->vex.guest_ES)); 1044 1045# elif defined(VGP_amd64_linux) 1046 vg_assert(0 == sizeof(VexGuestAMD64State) % LibVEX_GUEST_STATE_ALIGN); 1047 1048 /* Zero out the initial state, and set up the simulated FPU in a 1049 sane way. */ 1050 LibVEX_GuestAMD64_initialise(&arch->vex); 1051 1052 /* Zero out the shadow areas. */ 1053 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestAMD64State)); 1054 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State)); 1055 1056 /* Put essential stuff into the new state. */ 1057 arch->vex.guest_RSP = iifii.initial_client_SP; 1058 arch->vex.guest_RIP = iifii.initial_client_IP; 1059 1060# elif defined(VGP_ppc32_linux) 1061 vg_assert(0 == sizeof(VexGuestPPC32State) % LibVEX_GUEST_STATE_ALIGN); 1062 1063 /* Zero out the initial state, and set up the simulated FPU in a 1064 sane way. */ 1065 LibVEX_GuestPPC32_initialise(&arch->vex); 1066 1067 /* Zero out the shadow areas. */ 1068 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC32State)); 1069 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC32State)); 1070 1071 /* Put essential stuff into the new state. */ 1072 arch->vex.guest_GPR1 = iifii.initial_client_SP; 1073 arch->vex.guest_CIA = iifii.initial_client_IP; 1074 1075# elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 1076 vg_assert(0 == sizeof(VexGuestPPC64State) % LibVEX_GUEST_STATE_ALIGN); 1077 1078 /* Zero out the initial state, and set up the simulated FPU in a 1079 sane way. */ 1080 LibVEX_GuestPPC64_initialise(&arch->vex); 1081 1082 /* Zero out the shadow areas. */ 1083 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC64State)); 1084 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC64State)); 1085 1086 /* Put essential stuff into the new state. */ 1087 arch->vex.guest_GPR1 = iifii.initial_client_SP; 1088 arch->vex.guest_GPR2 = iifii.initial_client_TOC; 1089 arch->vex.guest_CIA = iifii.initial_client_IP; 1090#if defined(VGP_ppc64le_linux) 1091 arch->vex.guest_GPR12 = iifii.initial_client_IP; 1092#endif 1093 1094# elif defined(VGP_arm_linux) 1095 /* Zero out the initial state, and set up the simulated FPU in a 1096 sane way. */ 1097 LibVEX_GuestARM_initialise(&arch->vex); 1098 1099 /* Zero out the shadow areas. */ 1100 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestARMState)); 1101 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestARMState)); 1102 1103 arch->vex.guest_R13 = iifii.initial_client_SP; 1104 arch->vex.guest_R15T = iifii.initial_client_IP; 1105 1106 /* This is just EABI stuff. */ 1107 // FIXME jrs: what's this for? 1108 arch->vex.guest_R1 = iifii.initial_client_SP; 1109 1110# elif defined(VGP_arm64_linux) 1111 /* Zero out the initial state. */ 1112 LibVEX_GuestARM64_initialise(&arch->vex); 1113 1114 /* Zero out the shadow areas. */ 1115 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestARM64State)); 1116 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestARM64State)); 1117 1118 arch->vex.guest_XSP = iifii.initial_client_SP; 1119 arch->vex.guest_PC = iifii.initial_client_IP; 1120 1121# elif defined(VGP_s390x_linux) 1122 vg_assert(0 == sizeof(VexGuestS390XState) % LibVEX_GUEST_STATE_ALIGN); 1123 1124 /* Zero out the initial state. This also sets the guest_fpc to 0, which 1125 is also done by the kernel for the fpc during execve. */ 1126 LibVEX_GuestS390X_initialise(&arch->vex); 1127 1128 /* Mark all registers as undefined ... */ 1129 VG_(memset)(&arch->vex_shadow1, 0xFF, sizeof(VexGuestS390XState)); 1130 VG_(memset)(&arch->vex_shadow2, 0x00, sizeof(VexGuestS390XState)); 1131 /* ... except SP, FPC, and IA */ 1132 arch->vex_shadow1.guest_SP = 0; 1133 arch->vex_shadow1.guest_fpc = 0; 1134 arch->vex_shadow1.guest_IA = 0; 1135 1136 /* Put essential stuff into the new state. */ 1137 arch->vex.guest_SP = iifii.initial_client_SP; 1138 arch->vex.guest_IA = iifii.initial_client_IP; 1139 /* See sys_execve in <linux>/arch/s390/kernel/process.c */ 1140 arch->vex.guest_fpc = 0; 1141 1142 /* Tell the tool about the registers we just wrote */ 1143 VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_STACK_PTR, 8); 1144 VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_FPC_REG, 4); 1145 VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_INSTR_PTR, 8); 1146 1147 /* At the end of this function there is code to mark all guest state 1148 registers as defined. For s390 that would be wrong, because the ABI 1149 says that all registers except SP, IA, and FPC are undefined upon 1150 process startup. */ 1151#define PRECISE_GUEST_REG_DEFINEDNESS_AT_STARTUP 1 1152 1153# elif defined(VGP_mips32_linux) 1154 vg_assert(0 == sizeof(VexGuestMIPS32State) % LibVEX_GUEST_STATE_ALIGN); 1155 /* Zero out the initial state, and set up the simulated FPU in a 1156 sane way. */ 1157 LibVEX_GuestMIPS32_initialise(&arch->vex); 1158 1159 /* Zero out the shadow areas. */ 1160 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestMIPS32State)); 1161 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestMIPS32State)); 1162 1163 arch->vex.guest_r29 = iifii.initial_client_SP; 1164 arch->vex.guest_PC = iifii.initial_client_IP; 1165 arch->vex.guest_r31 = iifii.initial_client_SP; 1166 1167# elif defined(VGP_mips64_linux) 1168 vg_assert(0 == sizeof(VexGuestMIPS64State) % LibVEX_GUEST_STATE_ALIGN); 1169 /* Zero out the initial state, and set up the simulated FPU in a 1170 sane way. */ 1171 LibVEX_GuestMIPS64_initialise(&arch->vex); 1172 1173 /* Zero out the shadow areas. */ 1174 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestMIPS64State)); 1175 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestMIPS64State)); 1176 1177 arch->vex.guest_r29 = iifii.initial_client_SP; 1178 arch->vex.guest_PC = iifii.initial_client_IP; 1179 arch->vex.guest_r31 = iifii.initial_client_SP; 1180 1181# elif defined(VGP_tilegx_linux) 1182 vg_assert(0 == sizeof(VexGuestTILEGXState) % LibVEX_GUEST_STATE_ALIGN); 1183 1184 /* Zero out the initial state. */ 1185 LibVEX_GuestTILEGX_initialise(&arch->vex); 1186 1187 /* Zero out the shadow areas. */ 1188 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestTILEGXState)); 1189 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestTILEGXState)); 1190 1191 /* Put essential stuff into the new state. */ 1192 arch->vex.guest_r54 = iifii.initial_client_SP; 1193 arch->vex.guest_pc = iifii.initial_client_IP; 1194 1195# else 1196# error Unknown platform 1197# endif 1198 1199# if !defined(PRECISE_GUEST_REG_DEFINEDNESS_AT_STARTUP) 1200 /* Tell the tool that we just wrote to the registers. */ 1201 VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0, 1202 sizeof(VexGuestArchState)); 1203# endif 1204 1205 /* Tell the tool about the client data segment and then kill it which will 1206 make it inaccessible/unaddressable. */ 1207 const NSegment *seg = VG_(am_find_nsegment)(VG_(brk_base)); 1208 vg_assert(seg); 1209 vg_assert(seg->kind == SkAnonC); 1210 VG_TRACK(new_mem_brk, VG_(brk_base), seg->end + 1 - VG_(brk_base), 1211 1/*tid*/); 1212 VG_TRACK(die_mem_brk, VG_(brk_base), seg->end + 1 - VG_(brk_base)); 1213} 1214 1215#endif // defined(VGO_linux) 1216 1217/*--------------------------------------------------------------------*/ 1218/*--- ---*/ 1219/*--------------------------------------------------------------------*/ 1220