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-2009 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, write to the Free Software
26 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 The GNU General Public License is contained in the file COPYING.
32 #if defined(VGO_linux) || defined(VGO_l4re)
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 */
55 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
57 #define _FILE_OFFSET_BITS 64
58 /* This is for ELF types etc, and also the AT_ constants. */
60 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
63 /*====================================================================*/
64 /*=== Loading the client ===*/
65 /*====================================================================*/
67 /* Load the client whose name is VG_(argv_the_exename). */
69 static void load_client ( /*OUT*/ExeInfo* info,
70 /*OUT*/Addr* client_ip,
71 /*OUT*/Addr* client_toc)
77 #if !defined(VGO_l4re)
78 vg_assert( VG_(args_the_exename) != NULL);
79 exe_name = ML_(find_executable)( VG_(args_the_exename) );
82 VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename));
83 VG_(exit)(127); // 127 is Posix NOTFOUND
86 exe_name = VG_(args_the_exename);
89 VG_(memset)(info, 0, sizeof(*info));
90 ret = VG_(do_exec)(exe_name, info);
91 VG_(debugLog)(1, "initimg", "do_exec = %d\n", ret);
93 VG_(printf)("valgrind: could not execute '%s'\n", exe_name);
97 // The client was successfully loaded! Continue.
99 /* Get hold of a file descriptor which refers to the client
100 executable. This is needed for attaching to GDB. */
101 res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR);
102 if (!sr_isError(res))
103 VG_(cl_exec_fd) = sr_Res(res);
105 /* Copy necessary bits of 'info' that were filled in */
106 *client_ip = info->init_ip;
107 *client_toc = info->init_toc;
108 VG_(brk_base) = VG_(brk_limit) = VG_PGROUNDUP(info->brkbase);
112 /*====================================================================*/
113 /*=== Setting up the client's environment ===*/
114 /*====================================================================*/
116 /* Prepare the client's environment. This is basically a copy of our
119 LD_PRELOAD=$VALGRIND_LIB/vgpreload_core-PLATFORM.so:
120 ($VALGRIND_LIB/vgpreload_TOOL-PLATFORM.so:)?
123 If this is missing, then it is added.
125 Also, remove any binding for VALGRIND_LAUNCHER=. The client should
126 not be able to see this.
128 If this needs to handle any more variables it should be hacked
129 into something table driven. The copy is VG_(malloc)'d space.
131 static HChar** setup_client_env ( HChar** origenv, const HChar* toolname)
133 HChar* preload_core = "vgpreload_core";
134 HChar* ld_preload = "LD_PRELOAD=";
135 HChar* v_launcher = VALGRIND_LAUNCHER "=";
136 Int ld_preload_len = VG_(strlen)( ld_preload );
137 Int v_launcher_len = VG_(strlen)( v_launcher );
138 Bool ld_preload_done = False;
139 Int vglib_len = VG_(strlen)(VG_(libdir));
144 HChar* preload_tool_path;
147 /* Alloc space for the vgpreload_core.so path and vgpreload_<tool>.so
148 paths. We might not need the space for vgpreload_<tool>.so, but it
149 doesn't hurt to over-allocate briefly. The 16s are just cautious
151 Int preload_core_path_len = vglib_len + sizeof(preload_core)
152 + sizeof(VG_PLATFORM) + 16;
153 Int preload_tool_path_len = vglib_len + VG_(strlen)(toolname)
154 + sizeof(VG_PLATFORM) + 16;
155 Int preload_string_len = preload_core_path_len + preload_tool_path_len;
156 HChar* preload_string = VG_(malloc)("initimg-linux.sce.1",
160 vg_assert(preload_string);
162 /* Determine if there's a vgpreload_<tool>_<platform>.so file, and setup
164 preload_tool_path = VG_(malloc)("initimg-linux.sce.2", preload_tool_path_len);
165 vg_assert(preload_tool_path);
166 VG_(snprintf)(preload_tool_path, preload_tool_path_len,
167 "%s/vgpreload_%s-%s.so", "rom" /*VG_(libdir)*/, toolname, VG_PLATFORM);
169 if (VG_(access)(preload_tool_path, True/*r*/, False/*w*/, False/*x*/) == 0) {
170 VG_(snprintf)(preload_string, preload_string_len, "%s/%s-%s.so:%s",
171 "rom" /*VG_(libdir)*/, preload_core, VG_PLATFORM, preload_tool_path);
173 VG_(snprintf)(preload_string, preload_string_len, "%s/%s-%s.so",
174 "rom" /*VG_(libdir)*/, preload_core, VG_PLATFORM);
176 VG_(free)(preload_tool_path);
178 VG_(debugLog)(2, "initimg", "preload_string:\n");
179 VG_(debugLog)(2, "initimg", " \"%s\"\n", preload_string);
181 /* Count the original size of the env */
182 if (debug) VG_(printf)("\n\n");
184 for (cpp = origenv; cpp && *cpp; cpp++) {
186 if (debug) VG_(printf)("XXXXXXXXX: BEFORE %s\n", *cpp);
189 /* Allocate a new space */
190 ret = VG_(malloc) ("initimg-linux.sce.3",
191 sizeof(HChar *) * (envc+1+1)); /* 1 new entry + NULL */
195 for (cpp = ret; *origenv; ) {
196 if (debug) VG_(printf)("XXXXXXXXX: COPY %s\n", *origenv);
201 vg_assert(envc == (cpp - ret));
203 /* Walk over the new environment, mashing as we go */
204 for (cpp = ret; cpp && *cpp; cpp++) {
205 if (VG_(memcmp)(*cpp, ld_preload, ld_preload_len) == 0) {
206 Int len = VG_(strlen)(*cpp) + preload_string_len;
207 HChar *cp = VG_(malloc)("initimg-linux.sce.4", len);
210 VG_(snprintf)(cp, len, "%s%s:%s",
211 ld_preload, preload_string, (*cpp)+ld_preload_len);
215 ld_preload_done = True;
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);
226 VG_(snprintf)(cp, len, "%s%s", ld_preload, preload_string);
229 if (debug) VG_(printf)("XXXXXXXXX: ADD %s\n", cp);
232 /* ret[0 .. envc-1] is live now. */
233 /* Find and remove a binding for VALGRIND_LAUNCHER. */
234 for (i = 0; i < envc; i++)
235 if (0 == VG_(memcmp(ret[i], v_launcher, v_launcher_len)))
239 for (; i < envc-1; i++)
244 VG_(free)(preload_string);
247 for (i = 0; i < envc; i++) {
248 if (debug) VG_(printf)("XXXXXXXXX: FINAL %s\n", ret[i]);
251 //enter_kdebug("preload");
256 /*====================================================================*/
257 /*=== Setting up the client's stack ===*/
258 /*====================================================================*/
260 #ifndef AT_DCACHEBSIZE
261 #define AT_DCACHEBSIZE 19
262 #endif /* AT_DCACHEBSIZE */
264 #ifndef AT_ICACHEBSIZE
265 #define AT_ICACHEBSIZE 20
266 #endif /* AT_ICACHEBSIZE */
268 #ifndef AT_UCACHEBSIZE
269 #define AT_UCACHEBSIZE 21
270 #endif /* AT_UCACHEBSIZE */
272 #ifndef AT_BASE_PLATFORM
273 #define AT_BASE_PLATFORM 24
274 #endif /* AT_BASE_PLATFORM */
278 #endif /* AT_RANDOM */
282 #endif /* AT_EXECFN */
285 #define AT_SYSINFO 32
286 #endif /* AT_SYSINFO */
288 #ifndef AT_SYSINFO_EHDR
289 #define AT_SYSINFO_EHDR 33
290 #endif /* AT_SYSINFO_EHDR */
293 #define AT_SECURE 23 /* secure mode boolean */
294 #endif /* AT_SECURE */
296 #if defined(VGO_l4re) && !defined(AT_L4RE_ENVPAGE)
297 #define AT_L4RE_ENVPAGE 0xf1
300 /* Add a string onto the string table, and return its address */
301 static char *copy_str(char **tab, const char *str)
311 VG_(printf)("copied %p \"%s\" len %lld\n", orig, orig, (Long)(cp-orig));
319 /* ----------------------------------------------------------------
321 This sets up the client's initial stack, containing the args,
322 environment and aux vector.
324 The format of the stack is:
326 higher address +-----------------+ <- clstack_end
344 lower address +-----------------+ <- sp
348 Allocate and create the initial client stack. It is allocated down
349 from clstack_end, which was previously determined by the address
350 space manager. The returned value is the SP value for the client.
352 The client's auxv is created by copying and modifying our own one.
353 As a side effect of scanning our own auxv, some important bits of
356 VG_(cache_line_size_ppc32) // ppc32 only -- cache line size
357 VG_(have_altivec_ppc32) // ppc32 only -- is Altivec supported?
359 ---------------------------------------------------------------- */
371 struct auxv *find_auxv(UWord* sp)
373 sp++; // skip argc (Nb: is word-sized, not int-sized!)
375 while (*sp != 0) // skip argv
379 while (*sp != 0) // skip env
383 #if defined(VGA_ppc32) || defined(VGA_ppc64)
384 # if defined AT_IGNOREPPC
385 while (*sp == AT_IGNOREPPC) // skip AT_IGNOREPPC entries
390 return (struct auxv *)sp;
394 Addr setup_client_stack( void* init_sp,
399 SizeT clstack_max_size )
403 char *strtab; /* string table */
407 const struct auxv *orig_auxv;
408 const struct auxv *cauxv;
409 unsigned stringsize; /* total size of strings in bytes */
410 unsigned auxsize; /* total size of auxv in bytes */
411 Int argc; /* total argc */
412 Int envc; /* total number of env vars */
413 unsigned stacksize; /* total client stack size */
414 Addr client_SP; /* client stack base (initial SP) */
418 #if defined(VGO_l4re)
419 Addr client_l4re_env_addr;
422 VG_(debugLog)(2, "initimg", "%s sp %p env %p info %p stack_end %p size %lx\n",
423 __func__, init_sp, orig_envp, info, clstack_end, clstack_max_size);
424 vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1));
425 vg_assert( VG_(args_for_client) );
427 /* use our own auxv as a prototype */
428 orig_auxv = find_auxv(init_sp);
430 /* ==================== compute sizes ==================== */
432 /* first of all, work out how big the client stack will be */
434 have_exename = VG_(args_the_exename) != NULL;
436 /* paste on the extra args if the loader needs them (ie, the #!
437 interpreter and its argument) */
439 if (info->interp_name != NULL) {
441 stringsize += VG_(strlen)(info->interp_name) + 1;
443 if (info->interp_args != NULL) {
445 stringsize += VG_(strlen)(info->interp_args) + 1;
448 /* 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_ppc64_linux)
480 auxsize += 2 * sizeof(*cauxv);
482 # if defined(VGO_l4re)
483 auxsize += 4 * sizeof(*cauxv);
486 /* OK, now we know how big the client stack is */
488 sizeof(Word) + /* argc */
489 (have_exename ? sizeof(char **) : 0) + /* argc[0] == exename */
490 sizeof(char **)*argc + /* argv */
491 sizeof(char **) + /* terminal NULL */
492 sizeof(char **)*envc + /* envp */
493 sizeof(char **) + /* terminal NULL */
495 #if defined(VGO_l4re)
496 l4re_env_env_size() + /* L4Re Env object */
498 VG_ROUNDUP(stringsize, sizeof(Word)); /* strings (aligned) */
500 if (0) VG_(printf)("stacksize = %d\n", stacksize);
502 /* client_SP is the client's stack pointer */
503 client_SP = clstack_end - stacksize;
504 client_SP = VG_ROUNDDN(client_SP, 16); /* make stack 16 byte aligned */
506 /* base of the string table (aligned) */
507 stringbase = strtab = (char *)clstack_end
508 - VG_ROUNDUP(stringsize, sizeof(int));
510 client_l4re_env_addr = stringbase - l4re_env_env_size();
512 clstack_start = VG_PGROUNDDN(client_SP);
514 /* The max stack size */
515 clstack_max_size = VG_PGROUNDUP(clstack_max_size);
517 /* Record stack extent -- needed for stack-change code. */
518 VG_(clstk_base) = clstack_start;
519 VG_(clstk_end) = clstack_end;
522 VG_(printf)("stringsize=%d auxsize=%d stacksize=%d maxsize=0x%x\n"
525 stringsize, auxsize, stacksize, (Int)clstack_max_size,
526 (void*)clstack_start, (void*)clstack_end);
528 /* ==================== allocate space ==================== */
530 { SizeT anon_size = clstack_end - clstack_start + 1;
531 SizeT resvn_size = clstack_max_size - anon_size;
532 Addr anon_start = clstack_start;
533 Addr resvn_start = anon_start - resvn_size;
534 SizeT inner_HACK = 0;
537 /* So far we've only accounted for space requirements down to the
538 stack pointer. If this target's ABI requires a redzone below
539 the stack pointer, we need to allocate an extra page, to
540 handle the worst case in which the stack pointer is almost at
541 the bottom of a page, and so there is insufficient room left
542 over to put the redzone in. In this case the simple thing to
543 do is allocate an extra page, by shrinking the reservation by
544 one page and growing the anonymous area by a corresponding
546 vg_assert(VG_STACK_REDZONE_SZB >= 0);
547 vg_assert(VG_STACK_REDZONE_SZB < VKI_PAGE_SIZE);
548 if (VG_STACK_REDZONE_SZB > 0) {
549 vg_assert(resvn_size > VKI_PAGE_SIZE);
550 resvn_size -= VKI_PAGE_SIZE;
551 anon_start -= VKI_PAGE_SIZE;
552 anon_size += VKI_PAGE_SIZE;
555 vg_assert(VG_IS_PAGE_ALIGNED(anon_size));
556 vg_assert(VG_IS_PAGE_ALIGNED(resvn_size));
557 vg_assert(VG_IS_PAGE_ALIGNED(anon_start));
558 vg_assert(VG_IS_PAGE_ALIGNED(resvn_start));
559 vg_assert(resvn_start == clstack_end + 1 - clstack_max_size);
562 inner_HACK = 1024*1024; // create 1M non-fault-extending stack
566 VG_(printf)("%#lx 0x%lx %#lx 0x%lx\n",
567 resvn_start, resvn_size, anon_start, anon_size);
569 /* Create a shrinkable reservation followed by an anonymous
570 segment. Together these constitute a growdown stack. */
571 res = VG_(mk_SysRes_Error)(0);
572 ok = VG_(am_create_reservation)(
575 resvn_size - inner_HACK,
577 resvn_size - L4RE_STACKSIZE - inner_HACK,
581 anon_size + inner_HACK
583 anon_size + L4RE_STACKSIZE + inner_HACK
587 /* allocate a stack - mmap enough space for the stack */
588 res = VG_(am_mmap_anon_fixed_client)(
589 #if !defined(VGO_l4re)
590 anon_start -inner_HACK,
591 anon_size +inner_HACK,
593 anon_start - L4RE_STACKSIZE - inner_HACK,
594 anon_size + L4RE_STACKSIZE + inner_HACK,
596 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC
599 if ((!ok) || sr_isError(res)) {
600 /* Allocation of the stack failed. We have to stop. */
601 VG_(printf)("valgrind: "
602 "I failed to allocate space for the application's stack.\n");
603 VG_(printf)("valgrind: "
604 "This may be the result of a very large --main-stacksize=\n");
605 VG_(printf)("valgrind: setting. Cannot continue. Sorry.\n\n");
610 vg_assert(!sr_isError(res));
613 /* ==================== create client stack ==================== */
615 ptr = (Addr*)client_SP;
617 /* --- client argc --- */
618 *ptr++ = argc + (have_exename ? 1 : 0);
620 /* --- client argv --- */
621 if (info->interp_name) {
622 *ptr++ = (Addr)copy_str(&strtab, info->interp_name);
623 VG_(free)(info->interp_name);
625 if (info->interp_args) {
626 *ptr++ = (Addr)copy_str(&strtab, info->interp_args);
627 VG_(free)(info->interp_args);
631 *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename));
633 for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
634 *ptr++ = (Addr)copy_str(
636 * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
642 VG_(client_envp) = (Char **)ptr;
643 for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++) {
644 *ptr = (Addr)copy_str(&strtab, *cpp);
645 VG_(printf)("env %s\n", *cpp);
650 auxv = (struct auxv *)ptr;
651 *client_auxv = (UInt *)auxv;
653 # if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
654 auxv[0].a_type = AT_IGNOREPPC;
655 auxv[0].u.a_val = AT_IGNOREPPC;
656 auxv[1].a_type = AT_IGNOREPPC;
657 auxv[1].u.a_val = AT_IGNOREPPC;
662 /* http://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_zSeries.html */
663 if (info->phdr != 0) {
665 /* AT_PHDR tells the interpreter where to find the program header table in the memory image */
666 auxv->a_type = AT_PHDR;
667 auxv->u.a_val = info->phdr;
670 /* AT_PHNUM number of entries in the program header table at which the AT_PHDR entry points */
671 if (0) VG_(printf)("info->phnum = %p\n", info->phnum);
672 auxv->a_type = AT_PHNUM;
673 auxv->u.a_val = info->phnum;
676 /* AT_BASE base address at which the interpreter program was loaded into memory */
677 if (0) VG_(printf)("info->interp_base = %p\n", info->interp_base);
678 auxv->a_type = AT_BASE;
679 auxv->u.a_val = info->interp_base;
682 /* AT_ENTRY entry point of the application program to which the interpreter program should transfer control */
683 if (0) VG_(printf)("info->entry = %p\n", info->entry);
684 auxv->a_type= AT_ENTRY;
685 auxv->u.a_val = info->entry;
690 for (; orig_auxv->a_type != AT_NULL; auxv++, orig_auxv++) {
691 const NSegment *ehdrseg;
693 /* copy the entry... */
696 /* ...and fix up / examine the copy */
697 switch(auxv->a_type) {
710 /* All these are pointerless, so we don't need to do
711 anything about them. */
716 auxv->a_type = AT_IGNORE;
718 auxv->u.a_val = info->phdr;
723 auxv->a_type = AT_IGNORE;
725 auxv->u.a_val = info->phnum;
729 auxv->u.a_val = info->interp_base;
733 case AT_BASE_PLATFORM:
734 /* points to a platform description string */
735 auxv->u.a_ptr = copy_str(&strtab, orig_auxv->u.a_ptr);
739 auxv->u.a_val = info->entry;
748 # if defined(VGP_ppc32_linux)
749 /* acquire cache info */
750 if (auxv->u.a_val > 0) {
751 VG_(machine_ppc32_set_clszB)( auxv->u.a_val );
752 VG_(debugLog)(2, "initimg",
753 "PPC32 cache line size %u (type %u)\n",
754 (UInt)auxv->u.a_val, (UInt)auxv->a_type );
756 # elif defined(VGP_ppc64_linux)
757 /* acquire cache info */
758 if (auxv->u.a_val > 0) {
759 VG_(machine_ppc64_set_clszB)( auxv->u.a_val );
760 VG_(debugLog)(2, "initimg",
761 "PPC64 cache line size %u (type %u)\n",
762 (UInt)auxv->u.a_val, (UInt)auxv->a_type );
767 # if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
773 /* If this is 1, then it means that this program is
774 running suid, and therefore the dynamic linker should
775 be careful about LD_PRELOAD, etc. However, since
776 stage1 (the thing the kernel actually execve's) should
777 never be SUID, and we need LD_PRELOAD to work for the
778 client, we set AT_SECURE to 0. */
783 /* Trash this, because we don't reproduce it */
784 auxv->a_type = AT_IGNORE;
787 # if !defined(VGP_ppc32_linux) && !defined(VGP_ppc64_linux)
788 case AT_SYSINFO_EHDR:
789 /* Trash this, because we don't reproduce it */
790 ehdrseg = VG_(am_find_nsegment)((Addr)auxv->u.a_ptr);
792 VG_(am_munmap_valgrind)(ehdrseg->start, ehdrseg->end - ehdrseg->start);
793 auxv->a_type = AT_IGNORE;
798 /* points to 16 random bytes - we need to ensure this is
799 propagated to the client as glibc will assume it is
800 present if it is built for kernel 2.6.29 or later */
801 auxv->u.a_ptr = strtab;
802 VG_(memcpy)(strtab, orig_auxv->u.a_ptr, 16);
807 /* points to the executable filename */
808 auxv->u.a_ptr = copy_str(&strtab, VG_(args_the_exename));
811 #if defined(VGO_l4re)
812 case AT_L4RE_ENVPAGE:
814 * We found an aux pointer containing info about an
815 * L4Re env pointer. We modify the original env by
816 * replacing certain caps we are interested in with
817 * the cap of a vcap thread.
820 VG_(debugLog)(0, "initimg",
821 "\033[31ml4re_global_env found\033[0m\n");
823 // install modifications to
824 // global environment
826 auxv->u.a_val = (Word) l4re_vcap_modify_env(orig_auxv, client_l4re_env_addr);
833 /* stomp out anything we don't know about */
834 VG_(debugLog)(2, "initimg",
835 "stomping auxv entry %lld\n",
836 (ULong)auxv->a_type);
837 auxv->a_type = AT_IGNORE;
842 vg_assert(auxv->a_type == AT_NULL);
844 vg_assert((strtab-stringbase) == stringsize);
846 /* client_SP is pointing at client's argc/argv */
848 if (0) VG_(printf)("startup SP = %#lx\n", client_SP);
853 /* Allocate the client data segment. It is an expandable anonymous
854 mapping abutting a shrinkable reservation of size max_dseg_size.
855 The data segment starts at VG_(brk_base), which is page-aligned,
856 and runs up to VG_(brk_limit), which isn't. */
858 static void setup_client_dataseg ( SizeT max_size )
862 Addr anon_start = VG_(brk_base);
863 SizeT anon_size = VKI_PAGE_SIZE;
864 Addr resvn_start = anon_start + anon_size;
865 SizeT resvn_size = max_size - anon_size;
867 vg_assert(VG_IS_PAGE_ALIGNED(anon_size));
868 vg_assert(VG_IS_PAGE_ALIGNED(resvn_size));
869 vg_assert(VG_IS_PAGE_ALIGNED(anon_start));
870 vg_assert(VG_IS_PAGE_ALIGNED(resvn_start));
872 /* Because there's been no brk activity yet: */
873 vg_assert(VG_(brk_base) == VG_(brk_limit));
875 /* Try to create the data seg and associated reservation where
876 VG_(brk_base) says. */
877 ok = VG_(am_create_reservation)(
885 /* Hmm, that didn't work. Well, let aspacem suggest an address
886 it likes better, and try again with that. */
887 anon_start = VG_(am_get_advisory_client_simple)
888 ( 0/*floating*/, anon_size+resvn_size, &ok );
890 resvn_start = anon_start + anon_size;
891 ok = VG_(am_create_reservation)(
898 VG_(brk_base) = VG_(brk_limit) = anon_start;
900 /* that too might have failed, but if it has, we're hosed: there
905 /* We make the data segment (heap) executable because LinuxThreads on
906 ppc32 creates trampolines in this area. Also, on x86/Linux the data
907 segment is RWX natively, at least according to /proc/self/maps.
908 Also, having a non-executable data seg would kill any program which
909 tried to create code in the data seg and then run it. */
910 sres = VG_(am_mmap_anon_fixed_client)(
913 VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC
915 vg_assert(!sr_isError(sres));
916 vg_assert(sr_Res(sres) == anon_start);
920 /*====================================================================*/
921 /*=== TOP-LEVEL: VG_(setup_client_initial_image) ===*/
922 /*====================================================================*/
924 /* Create the client's initial memory image. */
925 IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii )
930 IIFinaliseImageInfo iifii;
931 VG_(memset)( &iifii, 0, sizeof(iifii) );
933 //--------------------------------------------------------------
934 // Load client executable, finding in $PATH if necessary
935 // p: get_helprequest_and_toolname() [for 'exec', 'need_help']
936 // p: layout_remaining_space [so there's space]
937 //--------------------------------------------------------------
938 VG_(debugLog)(1, "initimg", "\033[31;1mLoading client\033[0m\n");
940 if (VG_(args_the_exename) == NULL)
941 VG_(err_missing_prog)();
943 load_client(&info, &iifii.initial_client_IP, &iifii.initial_client_TOC);
945 vg_assert((void*)iifii.initial_client_IP != NULL);
948 //--------------------------------------------------------------
949 // Set up client's environment
950 // p: set-libdir [for VG_(libdir)]
951 // p: get_helprequest_and_toolname [for toolname]
952 //--------------------------------------------------------------
953 VG_(debugLog)(1, "initimg", "Setup client env\n");
954 env = setup_client_env(iicii.envp, iicii.toolname);
956 //--------------------------------------------------------------
957 // Setup client stack, eip, and VG_(client_arg[cv])
958 // p: load_client() [for 'info']
959 // p: fix_environment() [for 'env']
960 //--------------------------------------------------------------
962 /* When allocating space for the client stack on Linux, take
963 notice of the --main-stacksize value. This makes it possible
964 to run programs with very large (primary) stack requirements
965 simply by specifying --main-stacksize. */
966 /* Logic is as follows:
967 - by default, use the client's current stack rlimit
968 - if that exceeds 16M, clamp to 16M
969 - if a larger --main-stacksize value is specified, use that instead
970 - in all situations, the minimum allowed stack size is 1M
972 void* init_sp = iicii.argv - 1;
973 SizeT m1 = 1024 * 1024;
975 SizeT szB = (SizeT)VG_(client_rlimit_stack).rlim_cur;
976 if (szB < m1) szB = m1;
977 if (szB > m16) szB = m16;
978 if (VG_(clo_main_stacksize) > 0) szB = VG_(clo_main_stacksize);
979 if (szB < m1) szB = m1;
980 szB = VG_PGROUNDUP(szB);
981 VG_(debugLog)(1, "initimg",
982 "Setup client stack: size will be %ld\n", szB);
984 iifii.clstack_max_size = szB;
986 iifii.initial_client_SP
987 = setup_client_stack( init_sp, env,
988 &info, &iifii.client_auxv,
989 iicii.clstack_top, iifii.clstack_max_size );
993 VG_(debugLog)(2, "initimg",
995 "initial_IP=%p initial_TOC=%p brk_base=%p\n",
996 (void*)(iifii.initial_client_IP),
997 (void*)(iifii.initial_client_TOC),
998 (void*)VG_(brk_base) );
999 VG_(debugLog)(2, "initimg",
1001 "initial_SP=%p max_stack_size=%ld\n",
1002 (void*)(iifii.initial_client_SP),
1003 (SizeT)iifii.clstack_max_size );
1006 //--------------------------------------------------------------
1007 // Setup client data (brk) segment. Initially a 1-page segment
1008 // which abuts a shrinkable reservation.
1009 // p: load_client() [for 'info' and hence VG_(brk_base)]
1010 //--------------------------------------------------------------
1012 SizeT m1 = 1024 * 1024;
1014 SizeT dseg_max_size = (SizeT)VG_(client_rlimit_data).rlim_cur;
1015 VG_(debugLog)(1, "initimg", "Setup client data (brk) segment\n");
1016 if (dseg_max_size < m1) dseg_max_size = m1;
1017 if (dseg_max_size > m8) dseg_max_size = m8;
1018 dseg_max_size = VG_PGROUNDUP(dseg_max_size);
1020 setup_client_dataseg( dseg_max_size );
1027 /*====================================================================*/
1028 /*=== TOP-LEVEL: VG_(finalise_thread1state) ===*/
1029 /*====================================================================*/
1031 /* Just before starting the client, we may need to make final
1032 adjustments to its initial image. Also we need to set up the VEX
1033 guest state for thread 1 (the root thread) and copy in essential
1034 starting values. This is handed the IIFinaliseImageInfo created by
1035 VG_(ii_create_image).
1037 void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii )
1039 ThreadArchState* arch = &VG_(threads)[1].arch;
1041 /* On Linux we get client_{ip/sp/toc}, and start the client with
1042 all other registers zeroed. */
1044 # if defined(VGP_x86_linux)
1045 vg_assert(0 == sizeof(VexGuestX86State) % 16);
1047 /* Zero out the initial state, and set up the simulated FPU in a
1049 LibVEX_GuestX86_initialise(&arch->vex);
1051 /* Zero out the shadow areas. */
1052 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State));
1053 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State));
1055 /* Put essential stuff into the new state. */
1056 arch->vex.guest_ESP = iifii.initial_client_SP;
1057 arch->vex.guest_EIP = iifii.initial_client_IP;
1059 /* initialise %cs, %ds and %ss to point at the operating systems
1060 default code, data and stack segments */
1061 asm volatile("movw %%cs, %0" : : "m" (arch->vex.guest_CS));
1062 asm volatile("movw %%ds, %0" : : "m" (arch->vex.guest_DS));
1063 asm volatile("movw %%ss, %0" : : "m" (arch->vex.guest_SS));
1065 # elif defined(VGP_amd64_linux)
1066 vg_assert(0 == sizeof(VexGuestAMD64State) % 16);
1068 /* Zero out the initial state, and set up the simulated FPU in a
1070 LibVEX_GuestAMD64_initialise(&arch->vex);
1072 /* Zero out the shadow areas. */
1073 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestAMD64State));
1074 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State));
1076 /* Put essential stuff into the new state. */
1077 arch->vex.guest_RSP = iifii.initial_client_SP;
1078 arch->vex.guest_RIP = iifii.initial_client_IP;
1080 # elif defined(VGP_ppc32_linux)
1081 vg_assert(0 == sizeof(VexGuestPPC32State) % 16);
1083 /* Zero out the initial state, and set up the simulated FPU in a
1085 LibVEX_GuestPPC32_initialise(&arch->vex);
1087 /* Zero out the shadow areas. */
1088 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC32State));
1089 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC32State));
1091 /* Put essential stuff into the new state. */
1092 arch->vex.guest_GPR1 = iifii.initial_client_SP;
1093 arch->vex.guest_CIA = iifii.initial_client_IP;
1095 # elif defined(VGP_ppc64_linux)
1096 vg_assert(0 == sizeof(VexGuestPPC64State) % 16);
1098 /* Zero out the initial state, and set up the simulated FPU in a
1100 LibVEX_GuestPPC64_initialise(&arch->vex);
1102 /* Zero out the shadow areas. */
1103 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC64State));
1104 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC64State));
1106 /* Put essential stuff into the new state. */
1107 arch->vex.guest_GPR1 = iifii.initial_client_SP;
1108 arch->vex.guest_GPR2 = iifii.initial_client_TOC;
1109 arch->vex.guest_CIA = iifii.initial_client_IP;
1111 # elif defined(VGP_arm_linux)
1112 /* Zero out the initial state, and set up the simulated FPU in a
1114 LibVEX_GuestARM_initialise(&arch->vex);
1116 /* Zero out the shadow areas. */
1117 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestARMState));
1118 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestARMState));
1120 arch->vex.guest_R13 = iifii.initial_client_SP;
1121 arch->vex.guest_R15 = iifii.initial_client_IP;
1123 /* This is just EABI stuff. */
1124 // FIXME jrs: what's this for?
1125 arch->vex.guest_R1 = iifii.initial_client_SP;
1127 # elif defined(VGO_l4re)
1128 vg_assert(0 == sizeof(VexGuestX86State) % 16);
1130 /* Zero out the initial state, and set up the simulated FPU in a
1132 LibVEX_GuestX86_initialise(&arch->vex);
1134 /* Zero out the shadow areas. */
1135 VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State));
1136 VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State));
1138 /* Put essential stuff into the new state. */
1139 arch->vex.guest_ESP = iifii.initial_client_SP;
1140 arch->vex.guest_EIP = iifii.initial_client_IP;
1142 /* initialise %cs, %ds and %ss to point at the operating systems
1143 default code, data and stack segments */
1144 asm volatile("movw %%cs, %0" : : "m" (arch->vex.guest_CS));
1145 asm volatile("movw %%ds, %0" : : "m" (arch->vex.guest_DS));
1146 asm volatile("movw %%ss, %0" : : "m" (arch->vex.guest_SS));
1149 enum { GDT_ENTRY_SIZE = 2 * sizeof(long), GDT_NUM_ENTRIES = 11 };
1150 arch->vex.guest_GDT = VG_(malloc)("gdt", GDT_ENTRY_SIZE * GDT_NUM_ENTRIES);
1151 VG_(debugLog)(0, "sched", "GDT @ %p\n", arch->vex.guest_GDT);
1154 # error Unknown platform
1157 /* Tell the tool that we just wrote to the registers. */
1158 VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0,
1159 sizeof(VexGuestArchState));
1162 #endif // defined(VGO_linux)
1164 /*--------------------------------------------------------------------*/
1166 /*--------------------------------------------------------------------*/