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-2015 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
load_client(ExeInfo * info,Addr * client_ip,Addr * client_toc)69 static 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 */
setup_client_env(HChar ** origenv,const HChar * toolname)126 static 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 */
copy_str(HChar ** tab,const HChar * str)289 static 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
349 struct auxv
350 {
351 Word a_type;
352 union {
353 void *a_ptr;
354 Word a_val;
355 } u;
356 };
357
358 static
find_auxv(UWord * sp)359 struct 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
381 static
setup_client_stack(void * init_sp,HChar ** orig_envp,const ExeInfo * info,UInt ** client_auxv,Addr clstack_end,SizeT clstack_max_size,const VexArchInfo * vex_archinfo)382 Addr 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 = %u\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=%u auxsize=%u stacksize=%u maxsize=0x%lx\n"
498 "clstack_start %p\n"
499 "clstack_end %p\n",
500 stringsize, auxsize, stacksize, 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 # elif defined(VGP_s390x_linux)
702 {
703 /* Advertise hardware features "below" TE only. TE and VXRS
704 (and anything above) are not supported by Valgrind. */
705 auxv->u.a_val &= VKI_HWCAP_S390_TE - 1;
706 }
707 # endif
708 break;
709 # if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
710 case AT_HWCAP2: {
711 Bool auxv_2_07, hw_caps_2_07;
712 /* The HWCAP2 field may contain an arch_2_07 entry that indicates
713 * if the processor is compliant with the 2.07 ISA. (i.e. Power 8
714 * or beyond). The Valgrind vai.hwcaps value
715 * (coregrind/m_machine.c) has the VEX_HWCAPS_PPC64_ISA2_07
716 * flag set so Valgrind knows about Power8. Need to pass the
717 * HWCAP2 value along so the user level programs can detect that
718 * the processor supports ISA 2.07 and beyond.
719 */
720 /* Power Architecture 64-Bit ELF V2 ABI Specification
721 July 21, 2014, version 1.0, Page 124
722 www-03.ibm.com/technologyconnect/tgcm/TGCMServlet.wss?alias=OpenPOWER&linkid=1n0000
723
724 AT_HWCAP2
725 The a_val member of this entry is a bit map of hardware
726 capabilities. Some bit mask values include:
727
728 PPC_FEATURE2_ARCH_2_07 0x80000000
729 PPC_FEATURE2_HAS_HTM 0x40000000
730 PPC_FEATURE2_HAS_DSCR 0x20000000
731 PPC_FEATURE2_HAS_EBB 0x10000000
732 PPC_FEATURE2_HAS_ISEL 0x08000000
733 PPC_FEATURE2_HAS_TAR 0x04000000
734 PPC_FEATURE2_HAS_VCRYPTO 0x02000000
735 */
736 auxv_2_07 = (auxv->u.a_val & 0x80000000ULL) == 0x80000000ULL;
737 hw_caps_2_07 = (vex_archinfo->hwcaps & VEX_HWCAPS_PPC64_ISA2_07)
738 == VEX_HWCAPS_PPC64_ISA2_07;
739
740 /* Verify the PPC_FEATURE2_ARCH_2_07 setting in HWCAP2
741 * matches the setting in VEX HWCAPS.
742 */
743 vg_assert(auxv_2_07 == hw_caps_2_07);
744 }
745
746 break;
747 # endif
748
749 case AT_ICACHEBSIZE:
750 case AT_DCACHEBSIZE:
751 case AT_UCACHEBSIZE:
752 # if defined(VGP_ppc32_linux)
753 /* acquire cache info */
754 if (auxv->u.a_val > 0) {
755 VG_(machine_ppc32_set_clszB)( auxv->u.a_val );
756 VG_(debugLog)(2, "initimg",
757 "PPC32 icache line size %u (type %u)\n",
758 (UInt)auxv->u.a_val, (UInt)auxv->a_type );
759 }
760 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
761 /* acquire cache info */
762 if (auxv->u.a_val > 0) {
763 VG_(machine_ppc64_set_clszB)( auxv->u.a_val );
764 VG_(debugLog)(2, "initimg",
765 "PPC64 icache line size %u (type %u)\n",
766 (UInt)auxv->u.a_val, (UInt)auxv->a_type );
767 }
768 # endif
769 break;
770
771 # if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
772 || defined(VGP_ppc64le_linux)
773 case AT_IGNOREPPC:
774 break;
775 # endif
776
777 case AT_SECURE:
778 /* If this is 1, then it means that this program is
779 running suid, and therefore the dynamic linker should
780 be careful about LD_PRELOAD, etc. However, since
781 stage1 (the thing the kernel actually execve's) should
782 never be SUID, and we need LD_PRELOAD to work for the
783 client, we set AT_SECURE to 0. */
784 auxv->u.a_val = 0;
785 break;
786
787 case AT_SYSINFO:
788 /* Trash this, because we don't reproduce it */
789 auxv->a_type = AT_IGNORE;
790 break;
791
792 # if !defined(VGP_ppc32_linux) && !defined(VGP_ppc64be_linux) \
793 && !defined(VGP_ppc64le_linux)
794 case AT_SYSINFO_EHDR: {
795 /* Trash this, because we don't reproduce it */
796 const NSegment* ehdrseg = VG_(am_find_nsegment)((Addr)auxv->u.a_ptr);
797 vg_assert(ehdrseg);
798 VG_(am_munmap_valgrind)(ehdrseg->start, ehdrseg->end - ehdrseg->start);
799 auxv->a_type = AT_IGNORE;
800 break;
801 }
802 # endif
803
804 case AT_RANDOM:
805 /* points to 16 random bytes - we need to ensure this is
806 propagated to the client as glibc will assume it is
807 present if it is built for kernel 2.6.29 or later */
808 auxv->u.a_ptr = strtab;
809 VG_(memcpy)(strtab, orig_auxv->u.a_ptr, 16);
810 strtab += 16;
811 break;
812
813 case AT_EXECFN:
814 /* points to the executable filename */
815 auxv->u.a_ptr = copy_str(&strtab, VG_(args_the_exename));
816 break;
817
818 default:
819 /* stomp out anything we don't know about */
820 VG_(debugLog)(2, "initimg",
821 "stomping auxv entry %llu\n",
822 (ULong)auxv->a_type);
823 auxv->a_type = AT_IGNORE;
824 break;
825 }
826 }
827 *auxv = *orig_auxv;
828 vg_assert(auxv->a_type == AT_NULL);
829
830 vg_assert((strtab-stringbase) == stringsize);
831
832 /* client_SP is pointing at client's argc/argv */
833
834 if (0) VG_(printf)("startup SP = %#lx\n", client_SP);
835 return client_SP;
836 }
837
838
839 /* Allocate the client data segment. It is an expandable anonymous
840 mapping abutting a shrinkable reservation of size max_dseg_size.
841 The data segment starts at VG_(brk_base), which is page-aligned,
842 and runs up to VG_(brk_limit), which isn't. */
843
setup_client_dataseg(SizeT max_size)844 static void setup_client_dataseg ( SizeT max_size )
845 {
846 Bool ok;
847 SysRes sres;
848 Addr anon_start = VG_(brk_base);
849 SizeT anon_size = VKI_PAGE_SIZE;
850 Addr resvn_start = anon_start + anon_size;
851 SizeT resvn_size = max_size - anon_size;
852
853 vg_assert(VG_IS_PAGE_ALIGNED(anon_size));
854 vg_assert(VG_IS_PAGE_ALIGNED(resvn_size));
855 vg_assert(VG_IS_PAGE_ALIGNED(anon_start));
856 vg_assert(VG_IS_PAGE_ALIGNED(resvn_start));
857
858 /* Because there's been no brk activity yet: */
859 vg_assert(VG_(brk_base) == VG_(brk_limit));
860
861 /* Try to create the data seg and associated reservation where
862 VG_(brk_base) says. */
863 ok = VG_(am_create_reservation)(
864 resvn_start,
865 resvn_size,
866 SmLower,
867 anon_size
868 );
869
870 if (!ok) {
871 /* Hmm, that didn't work. Well, let aspacem suggest an address
872 it likes better, and try again with that. */
873 anon_start = VG_(am_get_advisory_client_simple)
874 ( 0/*floating*/, anon_size+resvn_size, &ok );
875 if (ok) {
876 resvn_start = anon_start + anon_size;
877 ok = VG_(am_create_reservation)(
878 resvn_start,
879 resvn_size,
880 SmLower,
881 anon_size
882 );
883 if (ok)
884 VG_(brk_base) = VG_(brk_limit) = anon_start;
885 }
886 /* that too might have failed, but if it has, we're hosed: there
887 is no Plan C. */
888 }
889 vg_assert(ok);
890
891 /* We make the data segment (heap) executable because LinuxThreads on
892 ppc32 creates trampolines in this area. Also, on x86/Linux the data
893 segment is RWX natively, at least according to /proc/self/maps.
894 Also, having a non-executable data seg would kill any program which
895 tried to create code in the data seg and then run it. */
896 sres = VG_(am_mmap_anon_fixed_client)(
897 anon_start,
898 anon_size,
899 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC
900 );
901 vg_assert(!sr_isError(sres));
902 vg_assert(sr_Res(sres) == anon_start);
903 }
904
905
906 /*====================================================================*/
907 /*=== TOP-LEVEL: VG_(setup_client_initial_image) ===*/
908 /*====================================================================*/
909
910 /* Create the client's initial memory image. */
VG_(ii_create_image)911 IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii,
912 const VexArchInfo* vex_archinfo )
913 {
914 ExeInfo info;
915 HChar** env = NULL;
916
917 IIFinaliseImageInfo iifii;
918 VG_(memset)( &iifii, 0, sizeof(iifii) );
919
920 //--------------------------------------------------------------
921 // Load client executable, finding in $PATH if necessary
922 // p: get_helprequest_and_toolname() [for 'exec', 'need_help']
923 // p: layout_remaining_space [so there's space]
924 //--------------------------------------------------------------
925 VG_(debugLog)(1, "initimg", "Loading client\n");
926
927 if (VG_(args_the_exename) == NULL)
928 VG_(err_missing_prog)();
929
930 load_client(&info, &iifii.initial_client_IP, &iifii.initial_client_TOC);
931
932 //--------------------------------------------------------------
933 // Set up client's environment
934 // p: set-libdir [for VG_(libdir)]
935 // p: get_helprequest_and_toolname [for toolname]
936 //--------------------------------------------------------------
937 VG_(debugLog)(1, "initimg", "Setup client env\n");
938 env = setup_client_env(iicii.envp, iicii.toolname);
939
940 //--------------------------------------------------------------
941 // Setup client stack, eip, and VG_(client_arg[cv])
942 // p: load_client() [for 'info']
943 // p: fix_environment() [for 'env']
944 //--------------------------------------------------------------
945 {
946 /* When allocating space for the client stack on Linux, take
947 notice of the --main-stacksize value. This makes it possible
948 to run programs with very large (primary) stack requirements
949 simply by specifying --main-stacksize. */
950 /* Logic is as follows:
951 - by default, use the client's current stack rlimit
952 - if that exceeds 16M, clamp to 16M
953 - if a larger --main-stacksize value is specified, use that instead
954 - in all situations, the minimum allowed stack size is 1M
955 */
956 void* init_sp = iicii.argv - 1;
957 SizeT m1 = 1024 * 1024;
958 SizeT m16 = 16 * m1;
959 SizeT szB = (SizeT)VG_(client_rlimit_stack).rlim_cur;
960 if (szB < m1) szB = m1;
961 if (szB > m16) szB = m16;
962 if (VG_(clo_main_stacksize) > 0) szB = VG_(clo_main_stacksize);
963 if (szB < m1) szB = m1;
964 szB = VG_PGROUNDUP(szB);
965 VG_(debugLog)(1, "initimg",
966 "Setup client stack: size will be %lu\n", szB);
967
968 iifii.clstack_max_size = szB;
969
970 iifii.initial_client_SP
971 = setup_client_stack( init_sp, env,
972 &info, &iifii.client_auxv,
973 iicii.clstack_end, iifii.clstack_max_size,
974 vex_archinfo );
975
976 VG_(free)(env);
977
978 VG_(debugLog)(2, "initimg",
979 "Client info: "
980 "initial_IP=%p initial_TOC=%p brk_base=%p\n",
981 (void*)(iifii.initial_client_IP),
982 (void*)(iifii.initial_client_TOC),
983 (void*)VG_(brk_base) );
984 VG_(debugLog)(2, "initimg",
985 "Client info: "
986 "initial_SP=%p max_stack_size=%lu\n",
987 (void*)(iifii.initial_client_SP),
988 iifii.clstack_max_size );
989 }
990
991 //--------------------------------------------------------------
992 // Setup client data (brk) segment. Initially a 1-page segment
993 // which abuts a shrinkable reservation.
994 // p: load_client() [for 'info' and hence VG_(brk_base)]
995 //--------------------------------------------------------------
996 {
997 SizeT m1 = 1024 * 1024;
998 SizeT m8 = 8 * m1;
999 SizeT dseg_max_size = (SizeT)VG_(client_rlimit_data).rlim_cur;
1000 VG_(debugLog)(1, "initimg", "Setup client data (brk) segment\n");
1001 if (dseg_max_size < m1) dseg_max_size = m1;
1002 if (dseg_max_size > m8) dseg_max_size = m8;
1003 dseg_max_size = VG_PGROUNDUP(dseg_max_size);
1004
1005 setup_client_dataseg( dseg_max_size );
1006 }
1007
1008 return iifii;
1009 }
1010
1011
1012 /*====================================================================*/
1013 /*=== TOP-LEVEL: VG_(finalise_thread1state) ===*/
1014 /*====================================================================*/
1015
1016 /* Just before starting the client, we may need to make final
1017 adjustments to its initial image. Also we need to set up the VEX
1018 guest state for thread 1 (the root thread) and copy in essential
1019 starting values. This is handed the IIFinaliseImageInfo created by
1020 VG_(ii_create_image).
1021 */
VG_(ii_finalise_image)1022 void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii )
1023 {
1024 ThreadArchState* arch = &VG_(threads)[1].arch;
1025
1026 /* On Linux we get client_{ip/sp/toc}, and start the client with
1027 all other registers zeroed. */
1028
1029 # if defined(VGP_x86_linux)
1030 vg_assert(0 == sizeof(VexGuestX86State) % LibVEX_GUEST_STATE_ALIGN);
1031
1032 /* Zero out the initial state, and set up the simulated FPU in a
1033 sane way. */
1034 LibVEX_GuestX86_initialise(&arch->vex);
1035
1036 /* Zero out the shadow areas. */
1037 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State));
1038 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State));
1039
1040 /* Put essential stuff into the new state. */
1041 arch->vex.guest_ESP = iifii.initial_client_SP;
1042 arch->vex.guest_EIP = iifii.initial_client_IP;
1043
1044 /* initialise %cs, %ds and %ss to point at the operating systems
1045 default code, data and stack segments. Also %es (see #291253). */
1046 asm volatile("movw %%cs, %0" : : "m" (arch->vex.guest_CS));
1047 asm volatile("movw %%ds, %0" : : "m" (arch->vex.guest_DS));
1048 asm volatile("movw %%ss, %0" : : "m" (arch->vex.guest_SS));
1049 asm volatile("movw %%es, %0" : : "m" (arch->vex.guest_ES));
1050
1051 # elif defined(VGP_amd64_linux)
1052 vg_assert(0 == sizeof(VexGuestAMD64State) % LibVEX_GUEST_STATE_ALIGN);
1053
1054 /* Zero out the initial state, and set up the simulated FPU in a
1055 sane way. */
1056 LibVEX_GuestAMD64_initialise(&arch->vex);
1057
1058 /* Zero out the shadow areas. */
1059 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestAMD64State));
1060 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State));
1061
1062 /* Put essential stuff into the new state. */
1063 arch->vex.guest_RSP = iifii.initial_client_SP;
1064 arch->vex.guest_RIP = iifii.initial_client_IP;
1065
1066 # elif defined(VGP_ppc32_linux)
1067 vg_assert(0 == sizeof(VexGuestPPC32State) % LibVEX_GUEST_STATE_ALIGN);
1068
1069 /* Zero out the initial state, and set up the simulated FPU in a
1070 sane way. */
1071 LibVEX_GuestPPC32_initialise(&arch->vex);
1072
1073 /* Zero out the shadow areas. */
1074 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC32State));
1075 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC32State));
1076
1077 /* Put essential stuff into the new state. */
1078 arch->vex.guest_GPR1 = iifii.initial_client_SP;
1079 arch->vex.guest_CIA = iifii.initial_client_IP;
1080
1081 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1082 vg_assert(0 == sizeof(VexGuestPPC64State) % LibVEX_GUEST_STATE_ALIGN);
1083
1084 /* Zero out the initial state, and set up the simulated FPU in a
1085 sane way. */
1086 LibVEX_GuestPPC64_initialise(&arch->vex);
1087
1088 /* Zero out the shadow areas. */
1089 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC64State));
1090 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC64State));
1091
1092 /* Put essential stuff into the new state. */
1093 arch->vex.guest_GPR1 = iifii.initial_client_SP;
1094 arch->vex.guest_GPR2 = iifii.initial_client_TOC;
1095 arch->vex.guest_CIA = iifii.initial_client_IP;
1096 #if defined(VGP_ppc64le_linux)
1097 arch->vex.guest_GPR12 = iifii.initial_client_IP;
1098 #endif
1099
1100 # elif defined(VGP_arm_linux)
1101 /* Zero out the initial state, and set up the simulated FPU in a
1102 sane way. */
1103 LibVEX_GuestARM_initialise(&arch->vex);
1104
1105 /* Zero out the shadow areas. */
1106 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestARMState));
1107 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestARMState));
1108
1109 arch->vex.guest_R13 = iifii.initial_client_SP;
1110 arch->vex.guest_R15T = iifii.initial_client_IP;
1111
1112 /* This is just EABI stuff. */
1113 // FIXME jrs: what's this for?
1114 arch->vex.guest_R1 = iifii.initial_client_SP;
1115
1116 # elif defined(VGP_arm64_linux)
1117 /* Zero out the initial state. */
1118 LibVEX_GuestARM64_initialise(&arch->vex);
1119
1120 /* Zero out the shadow areas. */
1121 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestARM64State));
1122 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestARM64State));
1123
1124 arch->vex.guest_XSP = iifii.initial_client_SP;
1125 arch->vex.guest_PC = iifii.initial_client_IP;
1126
1127 # elif defined(VGP_s390x_linux)
1128 vg_assert(0 == sizeof(VexGuestS390XState) % LibVEX_GUEST_STATE_ALIGN);
1129
1130 /* Zero out the initial state. This also sets the guest_fpc to 0, which
1131 is also done by the kernel for the fpc during execve. */
1132 LibVEX_GuestS390X_initialise(&arch->vex);
1133
1134 /* Mark all registers as undefined ... */
1135 VG_(memset)(&arch->vex_shadow1, 0xFF, sizeof(VexGuestS390XState));
1136 VG_(memset)(&arch->vex_shadow2, 0x00, sizeof(VexGuestS390XState));
1137 /* ... except SP, FPC, and IA */
1138 arch->vex_shadow1.guest_SP = 0;
1139 arch->vex_shadow1.guest_fpc = 0;
1140 arch->vex_shadow1.guest_IA = 0;
1141
1142 /* Put essential stuff into the new state. */
1143 arch->vex.guest_SP = iifii.initial_client_SP;
1144 arch->vex.guest_IA = iifii.initial_client_IP;
1145 /* See sys_execve in <linux>/arch/s390/kernel/process.c */
1146 arch->vex.guest_fpc = 0;
1147
1148 /* Tell the tool about the registers we just wrote */
1149 VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_STACK_PTR, 8);
1150 VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_FPC_REG, 4);
1151 VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_INSTR_PTR, 8);
1152
1153 /* At the end of this function there is code to mark all guest state
1154 registers as defined. For s390 that would be wrong, because the ABI
1155 says that all registers except SP, IA, and FPC are undefined upon
1156 process startup. */
1157 #define PRECISE_GUEST_REG_DEFINEDNESS_AT_STARTUP 1
1158
1159 # elif defined(VGP_mips32_linux)
1160 vg_assert(0 == sizeof(VexGuestMIPS32State) % LibVEX_GUEST_STATE_ALIGN);
1161 /* Zero out the initial state, and set up the simulated FPU in a
1162 sane way. */
1163 LibVEX_GuestMIPS32_initialise(&arch->vex);
1164
1165 /* Zero out the shadow areas. */
1166 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestMIPS32State));
1167 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestMIPS32State));
1168
1169 arch->vex.guest_r29 = iifii.initial_client_SP;
1170 arch->vex.guest_PC = iifii.initial_client_IP;
1171 arch->vex.guest_r31 = iifii.initial_client_SP;
1172
1173 # elif defined(VGP_mips64_linux)
1174 vg_assert(0 == sizeof(VexGuestMIPS64State) % LibVEX_GUEST_STATE_ALIGN);
1175 /* Zero out the initial state, and set up the simulated FPU in a
1176 sane way. */
1177 LibVEX_GuestMIPS64_initialise(&arch->vex);
1178
1179 /* Zero out the shadow areas. */
1180 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestMIPS64State));
1181 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestMIPS64State));
1182
1183 arch->vex.guest_r29 = iifii.initial_client_SP;
1184 arch->vex.guest_PC = iifii.initial_client_IP;
1185 arch->vex.guest_r31 = iifii.initial_client_SP;
1186
1187 # elif defined(VGP_tilegx_linux)
1188 vg_assert(0 == sizeof(VexGuestTILEGXState) % LibVEX_GUEST_STATE_ALIGN);
1189
1190 /* Zero out the initial state. */
1191 LibVEX_GuestTILEGX_initialise(&arch->vex);
1192
1193 /* Zero out the shadow areas. */
1194 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestTILEGXState));
1195 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestTILEGXState));
1196
1197 /* Put essential stuff into the new state. */
1198 arch->vex.guest_r54 = iifii.initial_client_SP;
1199 arch->vex.guest_pc = iifii.initial_client_IP;
1200
1201 # else
1202 # error Unknown platform
1203 # endif
1204
1205 # if !defined(PRECISE_GUEST_REG_DEFINEDNESS_AT_STARTUP)
1206 /* Tell the tool that we just wrote to the registers. */
1207 VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0,
1208 sizeof(VexGuestArchState));
1209 # endif
1210
1211 /* Tell the tool about the client data segment and then kill it which will
1212 make it inaccessible/unaddressable. */
1213 const NSegment *seg = VG_(am_find_nsegment)(VG_(brk_base));
1214 vg_assert(seg);
1215 vg_assert(seg->kind == SkAnonC);
1216 VG_TRACK(new_mem_brk, VG_(brk_base), seg->end + 1 - VG_(brk_base),
1217 1/*tid*/);
1218 VG_TRACK(die_mem_brk, VG_(brk_base), seg->end + 1 - VG_(brk_base));
1219 }
1220
1221 #endif // defined(VGO_linux)
1222
1223 /*--------------------------------------------------------------------*/
1224 /*--- ---*/
1225 /*--------------------------------------------------------------------*/
1226