2 /*--------------------------------------------------------------------*/
3 /*--- Startup: create initial process image on Linux ---*/
4 /*--- initimg-linux.c ---*/
5 /*--------------------------------------------------------------------*/
8 This file is part of Valgrind, a dynamic binary instrumentation
11 Copyright (C) 2000-2017 Julian Seward
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.
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.
24 You should have received a copy of the GNU General Public License
25 along with this program; if not, see <http://www.gnu.org/licenses/>.
27 The GNU General Public License is contained in the file COPYING.
30 #if defined(VGO_linux)
32 #include "pub_core_basics.h"
33 #include "pub_core_vki.h"
34 #include "pub_core_debuglog.h"
35 #include "pub_core_libcbase.h"
36 #include "pub_core_libcassert.h"
37 #include "pub_core_libcfile.h"
38 #include "pub_core_libcproc.h"
39 #include "pub_core_libcprint.h"
40 #include "pub_core_xarray.h"
41 #include "pub_core_clientstate.h"
42 #include "pub_core_aspacemgr.h"
43 #include "pub_core_mallocfree.h"
44 #include "pub_core_machine.h"
45 #include "pub_core_ume.h"
46 #include "pub_core_options.h"
47 #include "pub_core_syscall.h"
48 #include "pub_core_tooliface.h" /* VG_TRACK */
49 #include "pub_core_threadstate.h" /* ThreadArchState */
50 #include "pub_core_pathscan.h" /* find_executable */
51 #include "pub_core_initimg.h" /* self */
53 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
55 #define _FILE_OFFSET_BITS 64
56 /* This is for ELF types etc, and also the AT_ constants. */
58 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
61 /*====================================================================*/
62 /*=== Loading the client ===*/
63 /*====================================================================*/
65 /* Load the client whose name is VG_(argv_the_exename). */
67 static void load_client ( /*MOD*/ExeInfo
* info
,
68 /*OUT*/Addr
* client_ip
,
69 /*OUT*/Addr
* client_toc
)
71 const HChar
* exe_name
;
75 vg_assert( VG_(args_the_exename
) != NULL
);
76 exe_name
= VG_(find_executable
)( VG_(args_the_exename
) );
79 VG_(printf
)("valgrind: %s: command not found\n", VG_(args_the_exename
));
80 VG_(exit
)(127); // 127 is Posix NOTFOUND
83 ret
= VG_(do_exec
)(exe_name
, info
);
85 VG_(printf
)("valgrind: could not execute '%s'\n", exe_name
);
89 // The client was successfully loaded! Continue.
91 /* Get hold of a file descriptor which refers to the client
92 executable. This is needed for attaching to GDB. */
93 res
= VG_(open
)(exe_name
, VKI_O_RDONLY
, VKI_S_IRUSR
);
95 VG_(cl_exec_fd
) = sr_Res(res
);
97 /* Copy necessary bits of 'info' that were filled in */
98 *client_ip
= info
->init_ip
;
99 *client_toc
= info
->init_toc
;
100 VG_(brk_base
) = VG_(brk_limit
) = VG_PGROUNDUP(info
->brkbase
);
104 /*====================================================================*/
105 /*=== Setting up the client's environment ===*/
106 /*====================================================================*/
108 /* Prepare the client's environment. This is basically a copy of our
111 LD_PRELOAD=$VALGRIND_LIB/vgpreload_core-PLATFORM.so:
112 ($VALGRIND_LIB/vgpreload_TOOL-PLATFORM.so:)?
115 If this is missing, then it is added.
117 Also, remove any binding for VALGRIND_LAUNCHER=. The client should
118 not be able to see this.
120 If this needs to handle any more variables it should be hacked
121 into something table driven. The copy is VG_(malloc)'d space.
123 static HChar
** setup_client_env ( HChar
** origenv
, const HChar
* toolname
, Bool use_stack_cache_tunable
)
128 const HChar
* preload_core
= "vgpreload_core";
129 const HChar
* ld_preload
= "LD_PRELOAD=";
130 const HChar
* v_launcher
= VALGRIND_LAUNCHER
"=";
131 Int ld_preload_len
= VG_(strlen
)( ld_preload
);
132 Int v_launcher_len
= VG_(strlen
)( v_launcher
);
133 Bool ld_preload_done
= False
;
134 Int vglib_len
= VG_(strlen
)(VG_(libdir
));
139 HChar
* preload_tool_path
;
142 /* Alloc space for the vgpreload_core.so path and vgpreload_<tool>.so
143 paths. We might not need the space for vgpreload_<tool>.so, but it
144 doesn't hurt to over-allocate briefly. The 16s are just cautious
146 Int preload_core_path_len
= vglib_len
+ sizeof(preload_core
)
147 + sizeof(VG_PLATFORM
) + 16;
148 Int preload_tool_path_len
= vglib_len
+ VG_(strlen
)(toolname
)
149 + sizeof(VG_PLATFORM
) + 16;
150 Int preload_string_len
= preload_core_path_len
+ preload_tool_path_len
;
151 HChar
* preload_string
= VG_(malloc
)("initimg-linux.sce.1",
153 /* Determine if there's a vgpreload_<tool>_<platform>.so file, and setup
155 preload_tool_path
= VG_(malloc
)("initimg-linux.sce.2", preload_tool_path_len
);
156 VG_(snprintf
)(preload_tool_path
, preload_tool_path_len
,
157 "%s/vgpreload_%s-%s.so", VG_(libdir
), toolname
, VG_PLATFORM
);
158 if (VG_(access
)(preload_tool_path
, True
/*r*/, False
/*w*/, False
/*x*/) == 0) {
159 VG_(snprintf
)(preload_string
, preload_string_len
, "%s/%s-%s.so:%s",
160 VG_(libdir
), preload_core
, VG_PLATFORM
, preload_tool_path
);
162 VG_(snprintf
)(preload_string
, preload_string_len
, "%s/%s-%s.so",
163 VG_(libdir
), preload_core
, VG_PLATFORM
);
165 VG_(free
)(preload_tool_path
);
167 VG_(debugLog
)(2, "initimg", "preload_string:\n");
168 VG_(debugLog
)(2, "initimg", " \"%s\"\n", preload_string
);
170 /* Count the original size of the env */
171 if (debug
) VG_(printf
)("\n\n");
173 for (cpp
= origenv
; cpp
&& *cpp
; cpp
++) {
175 if (debug
) VG_(printf
)("XXXXXXXXX: BEFORE %s\n", *cpp
);
178 /* Allocate a new space
179 * Size is envc + 1 new entry + maybe one for GLIBC_TUNABLES + NULL */
180 ret
= VG_(malloc
) ("initimg-linux.sce.3",
181 sizeof(HChar
*) * (envc
+1+1+(use_stack_cache_tunable
? 1 : 0)));
184 for (cpp
= ret
; *origenv
; ) {
185 if (debug
) VG_(printf
)("XXXXXXXXX: COPY %s\n", *origenv
);
190 vg_assert(envc
== (cpp
- ret
));
192 /* Walk over the new environment, mashing as we go */
193 for (cpp
= ret
; cpp
&& *cpp
; cpp
++) {
194 if (VG_(memcmp
)(*cpp
, ld_preload
, ld_preload_len
) == 0) {
195 Int len
= VG_(strlen
)(*cpp
) + preload_string_len
;
196 HChar
*cp
= VG_(malloc
)("initimg-linux.sce.4", len
);
198 VG_(snprintf
)(cp
, len
, "%s%s:%s",
199 ld_preload
, preload_string
, (*cpp
)+ld_preload_len
);
203 ld_preload_done
= True
;
205 if (use_stack_cache_tunable
) {
206 /* overwrite value found with zeroes */
207 const HChar
* search_string
= "glibc.pthread.stack_cache_size=";
209 if ((val
= VG_(strstr
)(*cpp
, search_string
))) {
210 val
+= VG_(strlen
)(search_string
);
211 while (*val
!= '\0' && *val
!= ':') {
214 use_stack_cache_tunable
= False
;
217 if (debug
) VG_(printf
)("XXXXXXXXX: MASH %s\n", *cpp
);
220 /* Add the missing bits */
221 if (!ld_preload_done
) {
222 Int len
= ld_preload_len
+ preload_string_len
;
223 HChar
*cp
= VG_(malloc
) ("initimg-linux.sce.5", len
);
225 VG_(snprintf
)(cp
, len
, "%s%s", ld_preload
, preload_string
);
228 if (debug
) VG_(printf
)("XXXXXXXXX: ADD %s\n", cp
);
231 if (use_stack_cache_tunable
) {
232 ret
[envc
++] = VG_(strdup
)("initimg-linux.sce.6", "GLIBC_TUNABLES=glibc.pthread.stack_cache_size=0");
235 /* ret[0 .. envc-1] is live now. */
236 /* Find and remove a binding for VALGRIND_LAUNCHER. */
237 for (i
= 0; i
< envc
; i
++)
238 if (0 == VG_(memcmp
)(ret
[i
], v_launcher
, v_launcher_len
))
242 for (; i
< envc
-1; i
++)
247 VG_(free
)(preload_string
);
250 for (i
= 0; i
< envc
; i
++) {
251 if (debug
) VG_(printf
)("XXXXXXXXX: FINAL %s\n", ret
[i
]);
258 /*====================================================================*/
259 /*=== Setting up the client's stack ===*/
260 /*====================================================================*/
262 #ifndef AT_DCACHEBSIZE
263 #define AT_DCACHEBSIZE 19
264 #endif /* AT_DCACHEBSIZE */
266 #ifndef AT_ICACHEBSIZE
267 #define AT_ICACHEBSIZE 20
268 #endif /* AT_ICACHEBSIZE */
270 #ifndef AT_UCACHEBSIZE
271 #define AT_UCACHEBSIZE 21
272 #endif /* AT_UCACHEBSIZE */
274 #ifndef AT_BASE_PLATFORM
275 #define AT_BASE_PLATFORM 24
276 #endif /* AT_BASE_PLATFORM */
280 #endif /* AT_RANDOM */
284 #endif /* AT_HWCAP2 */
288 #endif /* AT_EXECFN */
291 #define AT_SYSINFO 32
292 #endif /* AT_SYSINFO */
294 #ifndef AT_SYSINFO_EHDR
295 #define AT_SYSINFO_EHDR 33
296 #endif /* AT_SYSINFO_EHDR */
299 #define AT_SECURE 23 /* secure mode boolean */
300 #endif /* AT_SECURE */
302 /* Add a string onto the string table, and return its address */
303 static HChar
*copy_str(HChar
**tab
, const HChar
*str
)
313 VG_(printf
)("copied %p \"%s\" len %lld\n", orig
, orig
, (Long
)(cp
-orig
));
321 /* ----------------------------------------------------------------
323 This sets up the client's initial stack, containing the args,
324 environment and aux vector.
326 The format of the stack is:
328 higher address +-----------------+ <- clstack_end
346 lower address +-----------------+ <- sp
350 Allocate and create the initial client stack. It is allocated down
351 from clstack_end, which was previously determined by the address
352 space manager. The returned value is the SP value for the client.
354 The client's auxv is created by copying and modifying our own one.
355 As a side effect of scanning our own auxv, some important bits of
358 VG_(cache_line_size_ppc32) // ppc32 only -- cache line size
359 VG_(have_altivec_ppc32) // ppc32 only -- is Altivec supported?
361 ---------------------------------------------------------------- */
373 struct auxv
*find_auxv(UWord
* sp
)
375 sp
++; // skip argc (Nb: is word-sized, not int-sized!)
377 while (*sp
!= 0) // skip argv
381 while (*sp
!= 0) // skip env
385 #if defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le)
386 # if defined AT_IGNOREPPC
387 while (*sp
== AT_IGNOREPPC
) // skip AT_IGNOREPPC entries
392 return (struct auxv
*)sp
;
396 Addr
setup_client_stack( void* init_sp
,
401 SizeT clstack_max_size
,
402 const VexArchInfo
* vex_archinfo
)
404 /* The HW configuration setting (hwcaps) of the target can be
405 * checked against the Vex settings of the host platform as given
406 * by the values in vex_archinfo.
411 HChar
*strtab
; /* string table */
415 const struct auxv
*orig_auxv
;
416 const struct auxv
*cauxv
;
417 unsigned stringsize
; /* total size of strings in bytes */
418 unsigned auxsize
; /* total size of auxv in bytes */
419 Int argc
; /* total argc */
420 Int envc
; /* total number of env vars */
421 unsigned stacksize
; /* total client stack size */
422 Addr client_SP
; /* client stack base (initial SP) */
426 vg_assert(VG_IS_PAGE_ALIGNED(clstack_end
+1));
427 vg_assert( VG_(args_for_client
) );
429 /* use our own auxv as a prototype */
430 orig_auxv
= find_auxv(init_sp
);
432 /* ==================== compute sizes ==================== */
434 /* first of all, work out how big the client stack will be */
437 /* paste on the extra args if the loader needs them (ie, the #!
438 interpreter and its argument) */
440 if (info
->interp_name
!= NULL
) {
442 stringsize
+= VG_(strlen
)(info
->interp_name
) + 1;
444 if (info
->interp_args
!= NULL
) {
446 stringsize
+= VG_(strlen
)(info
->interp_args
) + 1;
449 /* now scan the args we're given... */
450 stringsize
+= VG_(strlen
)( VG_(args_the_exename
) ) + 1;
452 for (i
= 0; i
< VG_(sizeXA
)( VG_(args_for_client
) ); i
++) {
454 stringsize
+= VG_(strlen
)( * (HChar
**)
455 VG_(indexXA
)( VG_(args_for_client
), i
))
459 /* ...and the environment */
461 for (cpp
= orig_envp
; cpp
&& *cpp
; cpp
++) {
463 stringsize
+= VG_(strlen
)(*cpp
) + 1;
466 /* now, how big is the auxv? */
467 auxsize
= sizeof(*auxv
); /* there's always at least one entry: AT_NULL */
468 for (cauxv
= orig_auxv
; cauxv
->a_type
!= AT_NULL
; cauxv
++) {
469 if (cauxv
->a_type
== AT_PLATFORM
||
470 cauxv
->a_type
== AT_BASE_PLATFORM
)
471 stringsize
+= VG_(strlen
)(cauxv
->u
.a_ptr
) + 1;
472 else if (cauxv
->a_type
== AT_RANDOM
)
474 else if (cauxv
->a_type
== AT_EXECFN
)
475 stringsize
+= VG_(strlen
)(VG_(args_the_exename
)) + 1;
476 auxsize
+= sizeof(*cauxv
);
479 # if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
480 || defined(VGP_ppc64le_linux)
481 auxsize
+= 2 * sizeof(*cauxv
);
484 /* OK, now we know how big the client stack is */
486 sizeof(Word
) + /* argc */
487 sizeof(HChar
**) + /* argc[0] == exename */
488 sizeof(HChar
**)*argc
+ /* argv */
489 sizeof(HChar
**) + /* terminal NULL */
490 sizeof(HChar
**)*envc
+ /* envp */
491 sizeof(HChar
**) + /* terminal NULL */
493 VG_ROUNDUP(stringsize
, sizeof(Word
)); /* strings (aligned) */
495 if (0) VG_(printf
)("stacksize = %u\n", stacksize
);
497 /* client_SP is the client's stack pointer */
498 client_SP
= clstack_end
- stacksize
;
499 client_SP
= VG_ROUNDDN(client_SP
, 16); /* make stack 16 byte aligned */
501 /* base of the string table (aligned) */
502 stringbase
= strtab
= (HChar
*)clstack_end
503 - VG_ROUNDUP(stringsize
, sizeof(int));
505 clstack_start
= VG_PGROUNDDN(client_SP
);
507 /* The max stack size */
508 clstack_max_size
= VG_PGROUNDUP(clstack_max_size
);
511 VG_(printf
)("stringsize=%u auxsize=%u stacksize=%u maxsize=0x%lx\n"
514 stringsize
, auxsize
, stacksize
, clstack_max_size
,
515 (void*)clstack_start
, (void*)clstack_end
);
517 /* ==================== allocate space ==================== */
519 { SizeT anon_size
= clstack_end
- clstack_start
+ 1;
520 SizeT resvn_size
= clstack_max_size
- anon_size
;
521 Addr anon_start
= clstack_start
;
522 Addr resvn_start
= anon_start
- resvn_size
;
523 SizeT inner_HACK
= 0;
526 /* So far we've only accounted for space requirements down to the
527 stack pointer. If this target's ABI requires a redzone below
528 the stack pointer, we need to allocate an extra page, to
529 handle the worst case in which the stack pointer is almost at
530 the bottom of a page, and so there is insufficient room left
531 over to put the redzone in. In this case the simple thing to
532 do is allocate an extra page, by shrinking the reservation by
533 one page and growing the anonymous area by a corresponding
535 vg_assert(VG_STACK_REDZONE_SZB
>= 0);
536 vg_assert(VG_STACK_REDZONE_SZB
< VKI_PAGE_SIZE
);
537 if (VG_STACK_REDZONE_SZB
> 0) {
538 vg_assert(resvn_size
> VKI_PAGE_SIZE
);
539 resvn_size
-= VKI_PAGE_SIZE
;
540 anon_start
-= VKI_PAGE_SIZE
;
541 anon_size
+= VKI_PAGE_SIZE
;
544 vg_assert(VG_IS_PAGE_ALIGNED(anon_size
));
545 vg_assert(VG_IS_PAGE_ALIGNED(resvn_size
));
546 vg_assert(VG_IS_PAGE_ALIGNED(anon_start
));
547 vg_assert(VG_IS_PAGE_ALIGNED(resvn_start
));
548 vg_assert(resvn_start
== clstack_end
+ 1 - clstack_max_size
);
551 inner_HACK
= 1024*1024; // create 1M non-fault-extending stack
555 VG_(printf
)("%#lx 0x%lx %#lx 0x%lx\n",
556 resvn_start
, resvn_size
, anon_start
, anon_size
);
558 /* Create a shrinkable reservation followed by an anonymous
559 segment. Together these constitute a growdown stack. */
560 res
= VG_(mk_SysRes_Error
)(0);
561 ok
= VG_(am_create_reservation
)(
563 resvn_size
-inner_HACK
,
565 anon_size
+inner_HACK
568 /* allocate a stack - mmap enough space for the stack */
569 res
= VG_(am_mmap_anon_fixed_client
)(
570 anon_start
-inner_HACK
,
571 anon_size
+inner_HACK
,
575 if ((!ok
) || sr_isError(res
)) {
576 /* Allocation of the stack failed. We have to stop. */
577 VG_(printf
)("valgrind: "
578 "I failed to allocate space for the application's stack.\n");
579 VG_(printf
)("valgrind: "
580 "This may be the result of a very large --main-stacksize=\n");
581 VG_(printf
)("valgrind: setting. Cannot continue. Sorry.\n\n");
586 vg_assert(!sr_isError(res
));
588 /* Record stack extent -- needed for stack-change code. */
589 VG_(clstk_start_base
) = anon_start
-inner_HACK
;
590 VG_(clstk_end
) = VG_(clstk_start_base
) + anon_size
+inner_HACK
-1;
594 /* ==================== create client stack ==================== */
596 ptr
= (Addr
*)client_SP
;
598 /* --- client argc --- */
601 /* --- client argv --- */
602 if (info
->interp_name
)
603 *ptr
++ = (Addr
)copy_str(&strtab
, info
->interp_name
);
604 if (info
->interp_args
)
605 *ptr
++ = (Addr
)copy_str(&strtab
, info
->interp_args
);
607 *ptr
++ = (Addr
)copy_str(&strtab
, VG_(args_the_exename
));
609 for (i
= 0; i
< VG_(sizeXA
)( VG_(args_for_client
) ); i
++) {
610 *ptr
++ = (Addr
)copy_str(
612 * (HChar
**) VG_(indexXA
)( VG_(args_for_client
), i
)
618 VG_(client_envp
) = (HChar
**)ptr
;
619 for (cpp
= orig_envp
; cpp
&& *cpp
; ptr
++, cpp
++)
620 *ptr
= (Addr
)copy_str(&strtab
, *cpp
);
624 auxv
= (struct auxv
*)ptr
;
625 *client_auxv
= (UInt
*)auxv
;
626 VG_(client_auxv
) = (UWord
*)*client_auxv
;
627 // ??? According to 'man proc', auxv is a array of unsigned long
628 // terminated by two zeros. Why is valgrind working with UInt ?
629 // We do not take ULong* (as ULong 8 bytes on a 32 bits),
632 # if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
633 || defined(VGP_ppc64le_linux)
634 auxv
[0].a_type
= AT_IGNOREPPC
;
635 auxv
[0].u
.a_val
= AT_IGNOREPPC
;
636 auxv
[1].a_type
= AT_IGNOREPPC
;
637 auxv
[1].u
.a_val
= AT_IGNOREPPC
;
641 for (; orig_auxv
->a_type
!= AT_NULL
; auxv
++, orig_auxv
++) {
643 /* copy the entry... */
646 /* ...and fix up / examine the copy */
647 switch(auxv
->a_type
) {
659 # if !defined(VGPV_arm_linux_android) \
660 && !defined(VGPV_x86_linux_android) \
661 && !defined(VGPV_mips32_linux_android) \
662 && !defined(VGPV_arm64_linux_android)
663 case AT_FPUCW
: /* missing on android */
665 /* All these are pointerless, so we don't need to do
666 anything about them. */
671 auxv
->a_type
= AT_IGNORE
;
673 auxv
->u
.a_val
= info
->phdr
;
678 auxv
->a_type
= AT_IGNORE
;
680 auxv
->u
.a_val
= info
->phnum
;
684 auxv
->u
.a_val
= info
->interp_offset
;
688 case AT_BASE_PLATFORM
:
689 /* points to a platform description string */
690 auxv
->u
.a_ptr
= copy_str(&strtab
, orig_auxv
->u
.a_ptr
);
694 auxv
->u
.a_val
= info
->entry
;
698 # if defined(VGP_arm_linux)
699 { Bool has_neon
= (auxv
->u
.a_val
& VKI_HWCAP_NEON
) > 0;
700 VG_(debugLog
)(2, "initimg",
701 "ARM has-neon from-auxv: %s\n",
702 has_neon
? "YES" : "NO");
703 VG_(machine_arm_set_has_NEON
)( has_neon
);
704 # define VKI_HWCAP_TLS 32768
705 Bool has_tls
= (auxv
->u
.a_val
& VKI_HWCAP_TLS
) > 0;
706 # undef VKI_HWCAP_TLS
707 VG_(debugLog
)(2, "initimg",
708 "ARM has-tls from-auxv: %s\n",
709 has_tls
? "YES" : "NO");
710 /* If real hw sets properly HWCAP_TLS, we might
711 use this info to decide to really execute set_tls syscall
712 in syswrap-arm-linux.c rather than to base this on
713 conditional compilation. */
715 # elif defined(VGP_s390x_linux)
717 /* Out of the hardware features available on the platform,
718 advertise those "below" TE, as well as the ones explicitly
719 ORed in the expression below. Anything else, such as TE
720 itself, is not supported by Valgrind. */
721 auxv
->u
.a_val
&= ((VKI_HWCAP_S390_TE
- 1)
722 | VKI_HWCAP_S390_VXRS
723 | VKI_HWCAP_S390_VXRS_EXT
724 | VKI_HWCAP_S390_VXRS_EXT2
);
726 # elif defined(VGP_arm64_linux)
728 /* Limit the AT_HWCAP to just those features we explicitly
730 #define ARM64_SUPPORTED_HWCAP (VKI_HWCAP_ATOMICS \
738 auxv
->u
.a_val
&= ARM64_SUPPORTED_HWCAP
;
742 # if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
744 Bool auxv_2_07
, hw_caps_2_07
;
745 Bool auxv_3_0
, hw_caps_3_0
;
746 Bool auxv_3_1
, hw_caps_3_1
;
747 Bool auxv_scv_supported
;
749 /* The HWCAP2 field may contain an arch_2_07 entry that indicates
750 * if the processor is compliant with the 2.07 ISA. (i.e. Power 8
751 * or beyond). The Valgrind vai.hwcaps value
752 * (coregrind/m_machine.c) has the VEX_HWCAPS_PPC64_ISA2_07
753 * flag set so Valgrind knows about Power8. Need to pass the
754 * HWCAP2 value along so the user level programs can detect that
755 * the processor supports ISA 2.07 and beyond.
757 /* Power Architecture 64-Bit ELF V2 ABI Specification
758 July 21, 2014, version 1.0, Page 124
759 www-03.ibm.com/technologyconnect/tgcm/TGCMServlet.wss?alias=OpenPOWER&linkid=1n0000
762 The a_val member of this entry is a bit map of hardware
763 capabilities. Some bit mask values include:
765 PPC_FEATURE2_ARCH_2_07 0x80000000
766 PPC_FEATURE2_HAS_HTM 0x40000000
767 PPC_FEATURE2_HAS_DSCR 0x20000000
768 PPC_FEATURE2_HAS_EBB 0x10000000
769 PPC_FEATURE2_HAS_ISEL 0x08000000
770 PPC_FEATURE2_HAS_TAR 0x04000000
771 PPC_FEATURE2_HAS_VCRYPTO 0x02000000
772 PPC_FEATURE2_HTM_NOSC 0x01000000
773 PPC_FEATURE2_ARCH_3_00 0x00800000
774 PPC_FEATURE2_HAS_IEEE128 0x00400000
775 PPC_FEATURE2_DARN 0x00200000
776 PPC_FEATURE2_SCV 0x00100000
777 PPC_FEATURE2_HTM_NO_SUSPEND 0x00080000
778 PPC_FEATURE2_ARCH_3_1 0x00040000
779 PPC_FEATURE2_MMA 0x00020000
781 auxv_2_07
= (auxv
->u
.a_val
& 0x80000000ULL
) == 0x80000000ULL
;
782 hw_caps_2_07
= (vex_archinfo
->hwcaps
& VEX_HWCAPS_PPC64_ISA2_07
)
783 == VEX_HWCAPS_PPC64_ISA2_07
;
785 /* Verify the PPC_FEATURE2_ARCH_2_07 setting in HWCAP2
786 * matches the setting in VEX HWCAPS.
788 vg_assert(auxv_2_07
== hw_caps_2_07
);
790 /* Power ISA version 3.0B
792 https://ibm.ent.box.com/s/1hzcwkwf8rbju5h9iyf44wm94amnlcrv
794 https://openpowerfoundation.org/technical/resource-catalog/
795 http://openpowerfoundation.org/wp-content/uploads/resources/leabi/leabi-20170510.pdf
796 64-bit ELF V2 ABI specification for Power. HWCAP2 bit pattern
797 for ISA 3.0, page 112.
801 auxv_3_0
= (auxv
->u
.a_val
& 0x00800000ULL
) == 0x00800000ULL
;
802 hw_caps_3_0
= (vex_archinfo
->hwcaps
& VEX_HWCAPS_PPC64_ISA3_0
)
803 == VEX_HWCAPS_PPC64_ISA3_0
;
805 /* Verify the PPC_FEATURE2_ARCH_3_00 setting in HWCAP2
806 * matches the setting in VEX HWCAPS.
808 vg_assert(auxv_3_0
== hw_caps_3_0
);
810 /* Power ISA version 3.1
811 https://ibm.ent.box.com/s/hhjfw0x0lrbtyzmiaffnbxh2fuo0fog0
813 64-bit ELF V? ABI specification for Power. HWCAP2 bit pattern
816 ADD PUBLIC LINK WHEN AVAILABLE
819 /* Check for SCV support, Can not test scv instruction to see
820 if the system supports scv. Issuing an scv intruction on a
821 system that does not have scv in the HWCAPS results in a
822 message in dmsg "Facility 'SCV' unavailable (12), exception".
823 Will have to just use the scv setting from HWCAPS2 to determine
824 if the host supports scv. */
825 auxv_scv_supported
= (auxv
->u
.a_val
& 0x00100000ULL
)
828 VG_(machine_ppc64_set_scv_support
)(auxv_scv_supported
);
831 auxv_3_1
= (auxv
->u
.a_val
& 0x00040000ULL
) == 0x00040000ULL
;
832 hw_caps_3_1
= (vex_archinfo
->hwcaps
& VEX_HWCAPS_PPC64_ISA3_1
)
833 == VEX_HWCAPS_PPC64_ISA3_1
;
835 /* Verify the PPC_FEATURE2_ARCH_3_1 setting in HWCAP2
836 * matches the setting in VEX HWCAPS.
838 vg_assert(auxv_3_1
== hw_caps_3_1
);
840 /* Mask unrecognized HWCAP bits. Only keep the bits that have
841 * explicit support in VEX. Filter out HTM bits since the
842 * transaction begin instruction (tbegin) is always failed in
843 * Valgrind causing the code to execute the failure path.
844 * The DARN random number (bug #411189) and the SCV syscall
845 * (bug #431157) have been fixed. Can now include them in the
848 auxv
->u
.a_val
&= (0x80000000ULL
/* ARCH_2_07 */
849 | 0x20000000ULL
/* DSCR */
850 | 0x10000000ULL
/* EBB */
851 | 0x08000000ULL
/* ISEL */
852 | 0x04000000ULL
/* TAR */
853 | 0x04000000ULL
/* VEC_CRYPTO */
854 | 0x00800000ULL
/* ARCH_3_00 */
855 | 0x00100000ULL
/* PPC_FEATURE2_SCV */
856 | 0x00400000ULL
/* HAS_IEEE128 */
857 | 0x00200000ULL
/* PPC_FEATURE2_DARN */
858 | 0x00040000ULL
/* ARCH_3_1 */
859 | 0x00020000ULL
); /* MMA instruction support */
868 # if defined(VGP_ppc32_linux)
869 /* acquire cache info */
870 if (auxv
->u
.a_val
> 0) {
871 VG_(machine_ppc32_set_clszB
)( auxv
->u
.a_val
);
872 VG_(debugLog
)(2, "initimg",
873 "PPC32 icache line size %u (type %u)\n",
874 (UInt
)auxv
->u
.a_val
, (UInt
)auxv
->a_type
);
876 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
877 /* acquire cache info */
878 if (auxv
->u
.a_val
> 0) {
879 VG_(machine_ppc64_set_clszB
)( auxv
->u
.a_val
);
880 VG_(debugLog
)(2, "initimg",
881 "PPC64 icache line size %u (type %u)\n",
882 (UInt
)auxv
->u
.a_val
, (UInt
)auxv
->a_type
);
887 # if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
888 || defined(VGP_ppc64le_linux)
894 /* If this is 1, then it means that this program is
895 running suid, and therefore the dynamic linker should
896 be careful about LD_PRELOAD, etc. However, since
897 stage1 (the thing the kernel actually execve's) should
898 never be SUID, and we need LD_PRELOAD to work for the
899 client, we set AT_SECURE to 0. */
904 /* Trash this, because we don't reproduce it */
905 auxv
->a_type
= AT_IGNORE
;
908 # if !defined(VGP_ppc32_linux) && !defined(VGP_ppc64be_linux) \
909 && !defined(VGP_ppc64le_linux) \
910 && !defined(VGP_mips32_linux) && !defined(VGP_mips64_linux) \
911 && !defined(VGP_nanomips_linux) \
912 && !defined(VGP_s390x_linux)
913 case AT_SYSINFO_EHDR
: {
914 /* Trash this, because we don't reproduce it */
915 const NSegment
* ehdrseg
= VG_(am_find_nsegment
)((Addr
)auxv
->u
.a_ptr
);
917 VG_(am_munmap_valgrind
)(ehdrseg
->start
, ehdrseg
->end
- ehdrseg
->start
);
918 auxv
->a_type
= AT_IGNORE
;
924 /* points to 16 random bytes - we need to ensure this is
925 propagated to the client as glibc will assume it is
926 present if it is built for kernel 2.6.29 or later */
927 auxv
->u
.a_ptr
= strtab
;
928 VG_(memcpy
)(strtab
, orig_auxv
->u
.a_ptr
, 16);
933 /* points to the executable filename */
934 auxv
->u
.a_ptr
= copy_str(&strtab
, VG_(args_the_exename
));
938 /* stomp out anything we don't know about */
939 VG_(debugLog
)(2, "initimg",
940 "stomping auxv entry %llu\n",
941 (ULong
)auxv
->a_type
);
942 auxv
->a_type
= AT_IGNORE
;
947 vg_assert(auxv
->a_type
== AT_NULL
);
949 vg_assert((strtab
-stringbase
) == stringsize
);
951 /* client_SP is pointing at client's argc/argv */
953 if (0) VG_(printf
)("startup SP = %#lx\n", client_SP
);
958 /* Allocate the client data segment. It is an expandable anonymous
959 mapping abutting a shrinkable reservation of size max_dseg_size.
960 The data segment starts at VG_(brk_base), which is page-aligned,
961 and runs up to VG_(brk_limit), which isn't. */
963 static void setup_client_dataseg ( SizeT max_size
)
967 Addr anon_start
= VG_(brk_base
);
968 SizeT anon_size
= VKI_PAGE_SIZE
;
969 Addr resvn_start
= anon_start
+ anon_size
;
970 SizeT resvn_size
= max_size
- anon_size
;
972 vg_assert(VG_IS_PAGE_ALIGNED(anon_size
));
973 vg_assert(VG_IS_PAGE_ALIGNED(resvn_size
));
974 vg_assert(VG_IS_PAGE_ALIGNED(anon_start
));
975 vg_assert(VG_IS_PAGE_ALIGNED(resvn_start
));
977 /* Because there's been no brk activity yet: */
978 vg_assert(VG_(brk_base
) == VG_(brk_limit
));
980 /* Try to create the data seg and associated reservation where
981 VG_(brk_base) says. */
982 ok
= VG_(am_create_reservation
)(
990 /* Hmm, that didn't work. Well, let aspacem suggest an address
991 it likes better, and try again with that. */
992 anon_start
= VG_(am_get_advisory_client_simple
)
993 ( 0/*floating*/, anon_size
+resvn_size
, &ok
);
995 resvn_start
= anon_start
+ anon_size
;
996 ok
= VG_(am_create_reservation
)(
1003 VG_(brk_base
) = VG_(brk_limit
) = anon_start
;
1005 /* that too might have failed, but if it has, we're hosed: there
1010 /* We make the data segment (heap) executable because LinuxThreads on
1011 ppc32 creates trampolines in this area. Also, on x86/Linux the data
1012 segment is RWX natively, at least according to /proc/self/maps.
1013 Also, having a non-executable data seg would kill any program which
1014 tried to create code in the data seg and then run it. */
1015 sres
= VG_(am_mmap_anon_fixed_client
)(
1018 VKI_PROT_READ
|VKI_PROT_WRITE
|VKI_PROT_EXEC
1020 vg_assert(!sr_isError(sres
));
1021 vg_assert(sr_Res(sres
) == anon_start
);
1025 * In glibc 2.34 we need to use the TUNABLE mechanism to
1026 * disable stack cache when --sim-hints=no-nptl-pthread-stackcache
1027 * is specified. This needs to be done in the same manner
1030 * See https://bugs.kde.org/show_bug.cgi?id=444488
1032 static Bool
need_stack_cache_tunable(HChar
** argv
)
1034 while (argv
&& *argv
) {
1035 if (VG_(strncmp
)(*argv
, "--sim-hints=", VG_(strlen
)("--sim-hints=")) == 0) {
1036 if (VG_(strstr
)(*argv
, "no-nptl-pthread-stackcache")) {
1045 /*====================================================================*/
1046 /*=== TOP-LEVEL: VG_(setup_client_initial_image) ===*/
1047 /*====================================================================*/
1049 /* Create the client's initial memory image. */
1050 IIFinaliseImageInfo
VG_(ii_create_image
)( IICreateImageInfo iicii
,
1051 const VexArchInfo
* vex_archinfo
)
1056 IIFinaliseImageInfo iifii
= {
1057 .clstack_max_size
= 0,
1058 .initial_client_SP
= 0,
1059 .initial_client_IP
= 0,
1060 .initial_client_TOC
= 0,
1061 .client_auxv
= NULL
,
1062 .arch_elf_state
= VKI_INIT_ARCH_ELF_STATE
,
1065 //--------------------------------------------------------------
1066 // Load client executable, finding in $PATH if necessary
1067 // p: get_helprequest_and_toolname() [for 'exec', 'need_help']
1068 // p: layout_remaining_space [so there's space]
1069 //--------------------------------------------------------------
1070 VG_(debugLog
)(1, "initimg", "Loading client\n");
1072 if (VG_(args_the_exename
) == NULL
)
1073 VG_(err_missing_prog
)();
1075 VG_(memset
)(&info
, 0, sizeof(info
));
1076 info
.arch_elf_state
= &iifii
.arch_elf_state
;
1078 load_client(&info
, &iifii
.initial_client_IP
, &iifii
.initial_client_TOC
);
1080 //--------------------------------------------------------------
1081 // Set up client's environment
1082 // p: set-libdir [for VG_(libdir)]
1083 // p: get_helprequest_and_toolname [for toolname]
1084 //--------------------------------------------------------------
1085 VG_(debugLog
)(1, "initimg", "Setup client env\n");
1086 env
= setup_client_env(iicii
.envp
, iicii
.toolname
, need_stack_cache_tunable(iicii
.argv
));
1088 //--------------------------------------------------------------
1089 // Setup client stack, eip, and VG_(client_arg[cv])
1090 // p: load_client() [for 'info']
1091 // p: fix_environment() [for 'env']
1092 //--------------------------------------------------------------
1094 /* When allocating space for the client stack on Linux, take
1095 notice of the --main-stacksize value. This makes it possible
1096 to run programs with very large (primary) stack requirements
1097 simply by specifying --main-stacksize. */
1098 /* Logic is as follows:
1099 - by default, use the client's current stack rlimit
1100 - if that exceeds 16M, clamp to 16M
1101 - if a larger --main-stacksize value is specified, use that instead
1102 - in all situations, the minimum allowed stack size is 1M
1104 void* init_sp
= iicii
.argv
- 1;
1105 SizeT m1
= 1024 * 1024;
1106 SizeT m16
= 16 * m1
;
1107 SizeT szB
= (SizeT
)VG_(client_rlimit_stack
).rlim_cur
;
1108 if (szB
< m1
) szB
= m1
;
1109 if (szB
> m16
) szB
= m16
;
1110 if (VG_(clo_main_stacksize
) > 0) szB
= VG_(clo_main_stacksize
);
1111 if (szB
< m1
) szB
= m1
;
1112 szB
= VG_PGROUNDUP(szB
);
1113 VG_(debugLog
)(1, "initimg",
1114 "Setup client stack: size will be %lu\n", szB
);
1116 iifii
.clstack_max_size
= szB
;
1118 iifii
.initial_client_SP
1119 = setup_client_stack( init_sp
, env
,
1120 &info
, &iifii
.client_auxv
,
1121 iicii
.clstack_end
, iifii
.clstack_max_size
,
1126 VG_(debugLog
)(2, "initimg",
1128 "initial_IP=%p initial_TOC=%p brk_base=%p\n",
1129 (void*)(iifii
.initial_client_IP
),
1130 (void*)(iifii
.initial_client_TOC
),
1131 (void*)VG_(brk_base
) );
1132 VG_(debugLog
)(2, "initimg",
1134 "initial_SP=%p max_stack_size=%lu\n",
1135 (void*)(iifii
.initial_client_SP
),
1136 iifii
.clstack_max_size
);
1139 //--------------------------------------------------------------
1140 // Setup client data (brk) segment. Initially a 1-page segment
1141 // which abuts a shrinkable reservation.
1142 // p: load_client() [for 'info' and hence VG_(brk_base)]
1143 //--------------------------------------------------------------
1145 SizeT m1
= 1024 * 1024;
1147 SizeT dseg_max_size
= (SizeT
)VG_(client_rlimit_data
).rlim_cur
;
1148 VG_(debugLog
)(1, "initimg", "Setup client data (brk) segment\n");
1149 if (dseg_max_size
< m1
) dseg_max_size
= m1
;
1150 if (dseg_max_size
> m8
) dseg_max_size
= m8
;
1151 dseg_max_size
= VG_PGROUNDUP(dseg_max_size
);
1153 setup_client_dataseg( dseg_max_size
);
1156 VG_(free
)(info
.interp_name
); info
.interp_name
= NULL
;
1157 VG_(free
)(info
.interp_args
); info
.interp_args
= NULL
;
1162 /*====================================================================*/
1163 /*=== TOP-LEVEL: VG_(finalise_thread1state) ===*/
1164 /*====================================================================*/
1166 /* Just before starting the client, we may need to make final
1167 adjustments to its initial image. Also we need to set up the VEX
1168 guest state for thread 1 (the root thread) and copy in essential
1169 starting values. This is handed the IIFinaliseImageInfo created by
1170 VG_(ii_create_image).
1172 void VG_(ii_finalise_image
)( IIFinaliseImageInfo iifii
)
1174 ThreadArchState
* arch
= &VG_(threads
)[1].arch
;
1176 /* On Linux we get client_{ip/sp/toc}, and start the client with
1177 all other registers zeroed. */
1179 # if defined(VGP_x86_linux)
1180 vg_assert(0 == sizeof(VexGuestX86State
) % LibVEX_GUEST_STATE_ALIGN
);
1182 /* Zero out the initial state, and set up the simulated FPU in a
1184 LibVEX_GuestX86_initialise(&arch
->vex
);
1186 /* Zero out the shadow areas. */
1187 VG_(memset
)(&arch
->vex_shadow1
, 0, sizeof(VexGuestX86State
));
1188 VG_(memset
)(&arch
->vex_shadow2
, 0, sizeof(VexGuestX86State
));
1190 /* Put essential stuff into the new state. */
1191 arch
->vex
.guest_ESP
= iifii
.initial_client_SP
;
1192 arch
->vex
.guest_EIP
= iifii
.initial_client_IP
;
1194 /* initialise %cs, %ds and %ss to point at the operating systems
1195 default code, data and stack segments. Also %es (see #291253). */
1196 asm volatile("movw %%cs, %0" : : "m" (arch
->vex
.guest_CS
));
1197 asm volatile("movw %%ds, %0" : : "m" (arch
->vex
.guest_DS
));
1198 asm volatile("movw %%ss, %0" : : "m" (arch
->vex
.guest_SS
));
1199 asm volatile("movw %%es, %0" : : "m" (arch
->vex
.guest_ES
));
1201 # elif defined(VGP_amd64_linux)
1202 vg_assert(0 == sizeof(VexGuestAMD64State
) % LibVEX_GUEST_STATE_ALIGN
);
1204 /* Zero out the initial state, and set up the simulated FPU in a
1206 LibVEX_GuestAMD64_initialise(&arch
->vex
);
1208 /* Zero out the shadow areas. */
1209 VG_(memset
)(&arch
->vex_shadow1
, 0, sizeof(VexGuestAMD64State
));
1210 VG_(memset
)(&arch
->vex_shadow2
, 0, sizeof(VexGuestAMD64State
));
1212 /* Put essential stuff into the new state. */
1213 arch
->vex
.guest_RSP
= iifii
.initial_client_SP
;
1214 arch
->vex
.guest_RIP
= iifii
.initial_client_IP
;
1216 # elif defined(VGP_ppc32_linux)
1217 vg_assert(0 == sizeof(VexGuestPPC32State
) % LibVEX_GUEST_STATE_ALIGN
);
1219 /* Zero out the initial state, and set up the simulated FPU in a
1221 LibVEX_GuestPPC32_initialise(&arch
->vex
);
1223 /* Zero out the shadow areas. */
1224 VG_(memset
)(&arch
->vex_shadow1
, 0, sizeof(VexGuestPPC32State
));
1225 VG_(memset
)(&arch
->vex_shadow2
, 0, sizeof(VexGuestPPC32State
));
1227 /* Put essential stuff into the new state. */
1228 arch
->vex
.guest_GPR1
= iifii
.initial_client_SP
;
1229 arch
->vex
.guest_CIA
= iifii
.initial_client_IP
;
1231 # elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux)
1232 vg_assert(0 == sizeof(VexGuestPPC64State
) % LibVEX_GUEST_STATE_ALIGN
);
1234 /* Zero out the initial state, and set up the simulated FPU in a
1236 LibVEX_GuestPPC64_initialise(&arch
->vex
);
1238 /* Zero out the shadow areas. */
1239 VG_(memset
)(&arch
->vex_shadow1
, 0, sizeof(VexGuestPPC64State
));
1240 VG_(memset
)(&arch
->vex_shadow2
, 0, sizeof(VexGuestPPC64State
));
1242 /* Put essential stuff into the new state. */
1243 arch
->vex
.guest_GPR1
= iifii
.initial_client_SP
;
1244 arch
->vex
.guest_GPR2
= iifii
.initial_client_TOC
;
1245 arch
->vex
.guest_CIA
= iifii
.initial_client_IP
;
1246 #if defined(VGP_ppc64le_linux)
1247 arch
->vex
.guest_GPR12
= iifii
.initial_client_IP
;
1250 # elif defined(VGP_arm_linux)
1251 /* Zero out the initial state, and set up the simulated FPU in a
1253 LibVEX_GuestARM_initialise(&arch
->vex
);
1255 /* Zero out the shadow areas. */
1256 VG_(memset
)(&arch
->vex_shadow1
, 0, sizeof(VexGuestARMState
));
1257 VG_(memset
)(&arch
->vex_shadow2
, 0, sizeof(VexGuestARMState
));
1259 arch
->vex
.guest_R13
= iifii
.initial_client_SP
;
1260 arch
->vex
.guest_R15T
= iifii
.initial_client_IP
;
1262 /* This is just EABI stuff. */
1263 // FIXME jrs: what's this for?
1264 arch
->vex
.guest_R1
= iifii
.initial_client_SP
;
1266 # elif defined(VGP_arm64_linux)
1267 /* Zero out the initial state. */
1268 LibVEX_GuestARM64_initialise(&arch
->vex
);
1270 /* Zero out the shadow areas. */
1271 VG_(memset
)(&arch
->vex_shadow1
, 0, sizeof(VexGuestARM64State
));
1272 VG_(memset
)(&arch
->vex_shadow2
, 0, sizeof(VexGuestARM64State
));
1274 arch
->vex
.guest_XSP
= iifii
.initial_client_SP
;
1275 arch
->vex
.guest_PC
= iifii
.initial_client_IP
;
1277 # elif defined(VGP_s390x_linux)
1278 vg_assert(0 == sizeof(VexGuestS390XState
) % LibVEX_GUEST_STATE_ALIGN
);
1280 /* Zero out the initial state. This also sets the guest_fpc to 0, which
1281 is also done by the kernel for the fpc during execve. */
1282 LibVEX_GuestS390X_initialise(&arch
->vex
);
1284 /* Mark all registers as undefined ... */
1285 VG_(memset
)(&arch
->vex_shadow1
, 0xFF, sizeof(VexGuestS390XState
));
1286 VG_(memset
)(&arch
->vex_shadow2
, 0x00, sizeof(VexGuestS390XState
));
1287 /* ... except SP, FPC, and IA */
1288 arch
->vex_shadow1
.guest_SP
= 0;
1289 arch
->vex_shadow1
.guest_fpc
= 0;
1290 arch
->vex_shadow1
.guest_IA
= 0;
1292 /* Put essential stuff into the new state. */
1293 arch
->vex
.guest_SP
= iifii
.initial_client_SP
;
1294 arch
->vex
.guest_IA
= iifii
.initial_client_IP
;
1295 /* See sys_execve in <linux>/arch/s390/kernel/process.c */
1296 arch
->vex
.guest_fpc
= 0;
1298 /* Tell the tool about the registers we just wrote */
1299 VG_TRACK(post_reg_write
, Vg_CoreStartup
, /*tid*/1, VG_O_STACK_PTR
, 8);
1300 VG_TRACK(post_reg_write
, Vg_CoreStartup
, /*tid*/1, VG_O_FPC_REG
, 4);
1301 VG_TRACK(post_reg_write
, Vg_CoreStartup
, /*tid*/1, VG_O_INSTR_PTR
, 8);
1303 /* At the end of this function there is code to mark all guest state
1304 registers as defined. For s390 that would be wrong, because the ABI
1305 says that all registers except SP, IA, and FPC are undefined upon
1307 #define PRECISE_GUEST_REG_DEFINEDNESS_AT_STARTUP 1
1309 # elif defined(VGP_mips32_linux) || defined(VGP_nanomips_linux)
1310 vg_assert(0 == sizeof(VexGuestMIPS32State
) % LibVEX_GUEST_STATE_ALIGN
);
1311 /* Zero out the initial state, and set up the simulated FPU in a
1313 LibVEX_GuestMIPS32_initialise(&arch
->vex
);
1315 /* Zero out the shadow areas. */
1316 VG_(memset
)(&arch
->vex_shadow1
, 0, sizeof(VexGuestMIPS32State
));
1317 VG_(memset
)(&arch
->vex_shadow2
, 0, sizeof(VexGuestMIPS32State
));
1319 arch
->vex
.guest_r29
= iifii
.initial_client_SP
;
1320 arch
->vex
.guest_PC
= iifii
.initial_client_IP
;
1321 arch
->vex
.guest_r31
= iifii
.initial_client_SP
;
1323 # if !defined(VGP_nanomips_linux)
1324 if (iifii
.arch_elf_state
.overall_fp_mode
== VKI_FP_FR1
) {
1325 arch
->vex
.guest_CP0_status
|= MIPS_CP0_STATUS_FR
;
1329 # elif defined(VGP_mips64_linux)
1330 vg_assert(0 == sizeof(VexGuestMIPS64State
) % LibVEX_GUEST_STATE_ALIGN
);
1331 /* Zero out the initial state, and set up the simulated FPU in a
1333 LibVEX_GuestMIPS64_initialise(&arch
->vex
);
1335 /* Zero out the shadow areas. */
1336 VG_(memset
)(&arch
->vex_shadow1
, 0, sizeof(VexGuestMIPS64State
));
1337 VG_(memset
)(&arch
->vex_shadow2
, 0, sizeof(VexGuestMIPS64State
));
1339 arch
->vex
.guest_r29
= iifii
.initial_client_SP
;
1340 arch
->vex
.guest_PC
= iifii
.initial_client_IP
;
1341 arch
->vex
.guest_r31
= iifii
.initial_client_SP
;
1344 # error Unknown platform
1347 # if !defined(PRECISE_GUEST_REG_DEFINEDNESS_AT_STARTUP)
1348 /* Tell the tool that we just wrote to the registers. */
1349 VG_TRACK( post_reg_write
, Vg_CoreStartup
, /*tid*/1, /*offset*/0,
1350 sizeof(VexGuestArchState
));
1353 /* Tell the tool about the client data segment and then kill it which will
1354 make it inaccessible/unaddressable. */
1355 const NSegment
*seg
= VG_(am_find_nsegment
)(VG_(brk_base
));
1357 vg_assert(seg
->kind
== SkAnonC
);
1358 VG_TRACK(new_mem_brk
, VG_(brk_base
), seg
->end
+ 1 - VG_(brk_base
),
1360 VG_TRACK(die_mem_brk
, VG_(brk_base
), seg
->end
+ 1 - VG_(brk_base
));
1363 #endif // defined(VGO_linux)
1365 /*--------------------------------------------------------------------*/
1367 /*--------------------------------------------------------------------*/