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-2007 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
#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_tooliface.h" /* VG_TRACK */
48
#include "pub_core_threadstate.h" /* ThreadArchState */
49
#include "pub_core_initimg.h" /* self */
51
/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
53
#define _FILE_OFFSET_BITS 64
54
/* This is for ELF types etc, and also the AT_ constants. */
56
/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
59
/*====================================================================*/
60
/*=== Find executable ===*/
61
/*====================================================================*/
63
/* Scan a colon-separated list, and call a function on each element.
64
The string must be mutable, because we insert a temporary '\0', but
65
the string will end up unmodified. (*func) should return True if it
66
doesn't need to see any more.
68
This routine will return True if (*func) returns True and False if
69
it reaches the end of the list without that happening.
71
static Bool scan_colsep(char *colsep, Bool (*func)(const char *))
85
if (*cp == ':' || *cp == '\0') {
102
/* Need a static copy because can't use dynamic mem allocation yet */
103
static HChar executable_name_in [VKI_PATH_MAX];
104
static HChar executable_name_out[VKI_PATH_MAX];
106
static Bool match_executable(const char *entry)
108
HChar buf[VG_(strlen)(entry) + VG_(strlen)(executable_name_in) + 3];
110
/* empty PATH element means '.' */
114
VG_(snprintf)(buf, sizeof(buf), "%s/%s", entry, executable_name_in);
116
// Don't match directories
117
if (VG_(is_dir)(buf))
120
// If we match an executable, we choose that immediately. If we find a
121
// matching non-executable we remember it but keep looking for an
122
// matching executable later in the path.
123
if (VG_(access)(buf, True/*r*/, False/*w*/, True/*x*/) == 0) {
124
VG_(strncpy)( executable_name_out, buf, VKI_PATH_MAX-1 );
125
executable_name_out[VKI_PATH_MAX-1] = 0;
126
return True; // Stop looking
127
} else if (VG_(access)(buf, True/*r*/, False/*w*/, False/*x*/) == 0
128
&& VG_STREQ(executable_name_out, ""))
130
VG_(strncpy)( executable_name_out, buf, VKI_PATH_MAX-1 );
131
executable_name_out[VKI_PATH_MAX-1] = 0;
132
return False; // Keep looking
134
return False; // Keep looking
138
// Returns NULL if it wasn't found.
139
static HChar* find_executable ( HChar* exec )
141
vg_assert(NULL != exec);
142
if (VG_(strchr)(exec, '/')) {
143
// Has a '/' - use the name as is
144
VG_(strncpy)( executable_name_out, exec, VKI_PATH_MAX-1 );
146
// No '/' - we need to search the path
148
VG_(strncpy)( executable_name_in, exec, VKI_PATH_MAX-1 );
149
VG_(memset) ( executable_name_out, 0, VKI_PATH_MAX );
150
path = VG_(getenv)("PATH");
151
scan_colsep(path, match_executable);
153
return VG_STREQ(executable_name_out, "") ? NULL : executable_name_out;
157
/*====================================================================*/
158
/*=== Loading the client ===*/
159
/*====================================================================*/
161
/* Load the client whose name is VG_(argv_the_exename). */
163
static void load_client ( /*OUT*/ExeInfo* info,
164
/*OUT*/Addr* client_ip,
165
/*OUT*/Addr* client_toc)
171
vg_assert( VG_(args_the_exename) != NULL);
172
exe_name = find_executable( VG_(args_the_exename) );
175
VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename));
176
VG_(exit)(127); // 127 is Posix NOTFOUND
179
VG_(memset)(info, 0, sizeof(*info));
180
info->exe_base = VG_(client_base);
181
info->exe_end = VG_(client_end);
183
ret = VG_(do_exec)(exe_name, info);
185
// The client was successfully loaded! Continue.
187
/* Get hold of a file descriptor which refers to the client
188
executable. This is needed for attaching to GDB. */
189
res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR);
191
VG_(cl_exec_fd) = res.res;
193
/* Copy necessary bits of 'info' that were filled in */
194
*client_ip = info->init_ip;
195
*client_toc = info->init_toc;
196
VG_(brk_base) = VG_(brk_limit) = VG_PGROUNDUP(info->brkbase);
200
/*====================================================================*/
201
/*=== Setting up the client's environment ===*/
202
/*====================================================================*/
204
/* Prepare the client's environment. This is basically a copy of our
207
LD_PRELOAD=$VALGRIND_LIB/PLATFORM/vgpreload_core.so:
208
($VALGRIND_LIB/PLATFORM/vgpreload_TOOL.so:)?
211
If this is missing, then it is added.
213
Also, remove any binding for VALGRIND_LAUNCHER=. The client should
214
not be able to see this.
216
If this needs to handle any more variables it should be hacked
217
into something table driven. The copy is VG_(malloc)'d space.
219
static HChar** setup_client_env ( HChar** origenv, const HChar* toolname)
221
HChar* preload_core = "vgpreload_core";
222
HChar* ld_preload = "LD_PRELOAD=";
223
HChar* v_launcher = VALGRIND_LAUNCHER "=";
224
Int ld_preload_len = VG_(strlen)( ld_preload );
225
Int v_launcher_len = VG_(strlen)( v_launcher );
226
Bool ld_preload_done = False;
227
Int vglib_len = VG_(strlen)(VG_(libdir));
231
HChar* preload_tool_path;
234
/* Alloc space for the vgpreload_core.so path and vgpreload_<tool>.so
235
paths. We might not need the space for vgpreload_<tool>.so, but it
236
doesn't hurt to over-allocate briefly. The 16s are just cautious
238
Int preload_core_path_len = vglib_len + sizeof(preload_core)
239
+ sizeof(VG_PLATFORM) + 16;
240
Int preload_tool_path_len = vglib_len + VG_(strlen)(toolname)
241
+ sizeof(VG_PLATFORM) + 16;
242
Int preload_string_len = preload_core_path_len + preload_tool_path_len;
243
HChar* preload_string = VG_(malloc)(preload_string_len);
244
vg_assert(preload_string);
246
/* Determine if there's a vgpreload_<tool>.so file, and setup
248
preload_tool_path = VG_(malloc)(preload_tool_path_len);
249
vg_assert(preload_tool_path);
250
VG_(snprintf)(preload_tool_path, preload_tool_path_len,
251
"%s/%s/vgpreload_%s.so", VG_(libdir), VG_PLATFORM, toolname);
252
if (VG_(access)(preload_tool_path, True/*r*/, False/*w*/, False/*x*/) == 0) {
253
VG_(snprintf)(preload_string, preload_string_len, "%s/%s/%s.so:%s",
254
VG_(libdir), VG_PLATFORM, preload_core, preload_tool_path);
256
VG_(snprintf)(preload_string, preload_string_len, "%s/%s/%s.so",
257
VG_(libdir), VG_PLATFORM, preload_core);
259
VG_(free)(preload_tool_path);
261
VG_(debugLog)(2, "initimg", "preload_string:\n");
262
VG_(debugLog)(2, "initimg", " \"%s\"\n", preload_string);
264
/* Count the original size of the env */
266
for (cpp = origenv; cpp && *cpp; cpp++)
269
/* Allocate a new space */
270
ret = VG_(malloc) (sizeof(HChar *) * (envc+1+1)); /* 1 new entry + NULL */
274
for (cpp = ret; *origenv; )
278
vg_assert(envc == (cpp - ret));
280
/* Walk over the new environment, mashing as we go */
281
for (cpp = ret; cpp && *cpp; cpp++) {
282
if (VG_(memcmp)(*cpp, ld_preload, ld_preload_len) == 0) {
283
Int len = VG_(strlen)(*cpp) + preload_string_len;
284
HChar *cp = VG_(malloc)(len);
287
VG_(snprintf)(cp, len, "%s%s:%s",
288
ld_preload, preload_string, (*cpp)+ld_preload_len);
292
ld_preload_done = True;
296
/* Add the missing bits */
297
if (!ld_preload_done) {
298
Int len = ld_preload_len + preload_string_len;
299
HChar *cp = VG_(malloc) (len);
302
VG_(snprintf)(cp, len, "%s%s", ld_preload, preload_string);
307
/* ret[0 .. envc-1] is live now. */
308
/* Find and remove a binding for VALGRIND_LAUNCHER. */
309
for (i = 0; i < envc; i++)
310
if (0 == VG_(memcmp(ret[i], v_launcher, v_launcher_len)))
314
for (; i < envc-1; i++)
319
VG_(free)(preload_string);
326
/*====================================================================*/
327
/*=== Setting up the client's stack ===*/
328
/*====================================================================*/
330
#ifndef AT_DCACHEBSIZE
331
#define AT_DCACHEBSIZE 19
332
#endif /* AT_DCACHEBSIZE */
334
#ifndef AT_ICACHEBSIZE
335
#define AT_ICACHEBSIZE 20
336
#endif /* AT_ICACHEBSIZE */
338
#ifndef AT_UCACHEBSIZE
339
#define AT_UCACHEBSIZE 21
340
#endif /* AT_UCACHEBSIZE */
343
#define AT_SYSINFO 32
344
#endif /* AT_SYSINFO */
346
#ifndef AT_SYSINFO_EHDR
347
#define AT_SYSINFO_EHDR 33
348
#endif /* AT_SYSINFO_EHDR */
351
#define AT_SECURE 23 /* secure mode boolean */
352
#endif /* AT_SECURE */
354
/* Add a string onto the string table, and return its address */
355
static char *copy_str(char **tab, const char *str)
365
VG_(printf)("copied %p \"%s\" len %lld\n", orig, orig, (Long)(cp-orig));
373
/* ----------------------------------------------------------------
375
This sets up the client's initial stack, containing the args,
376
environment and aux vector.
378
The format of the stack is:
380
higher address +-----------------+ <- clstack_end
398
lower address +-----------------+ <- sp
402
Allocate and create the initial client stack. It is allocated down
403
from clstack_end, which was previously determined by the address
404
space manager. The returned value is the SP value for the client.
406
The client's auxv is created by copying and modifying our own one.
407
As a side effect of scanning our own auxv, some important bits of
410
VG_(cache_line_size_ppc32) // ppc32 only -- cache line size
411
VG_(have_altivec_ppc32) // ppc32 only -- is Altivec supported?
413
---------------------------------------------------------------- */
416
Addr setup_client_stack( void* init_sp,
421
SizeT clstack_max_size )
425
char *strtab; /* string table */
428
struct ume_auxv *auxv;
429
const struct ume_auxv *orig_auxv;
430
const struct ume_auxv *cauxv;
431
unsigned stringsize; /* total size of strings in bytes */
432
unsigned auxsize; /* total size of auxv in bytes */
433
Int argc; /* total argc */
434
Int envc; /* total number of env vars */
435
unsigned stacksize; /* total client stack size */
436
Addr client_SP; /* client stack base (initial SP) */
441
vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1));
442
vg_assert( VG_(args_for_client) );
444
/* use our own auxv as a prototype */
445
orig_auxv = VG_(find_auxv)(init_sp);
447
/* ==================== compute sizes ==================== */
449
/* first of all, work out how big the client stack will be */
451
have_exename = VG_(args_the_exename) != NULL;
453
/* paste on the extra args if the loader needs them (ie, the #!
454
interpreter and its argument) */
456
if (info->interp_name != NULL) {
458
stringsize += VG_(strlen)(info->interp_name) + 1;
460
if (info->interp_args != NULL) {
462
stringsize += VG_(strlen)(info->interp_args) + 1;
465
/* now scan the args we're given... */
467
stringsize += VG_(strlen)( VG_(args_the_exename) ) + 1;
469
for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
471
stringsize += VG_(strlen)( * (HChar**)
472
VG_(indexXA)( VG_(args_for_client), i ))
476
/* ...and the environment */
478
for (cpp = orig_envp; cpp && *cpp; cpp++) {
480
stringsize += VG_(strlen)(*cpp) + 1;
483
/* now, how big is the auxv? */
484
auxsize = sizeof(*auxv); /* there's always at least one entry: AT_NULL */
485
for (cauxv = orig_auxv; cauxv->a_type != AT_NULL; cauxv++) {
486
if (cauxv->a_type == AT_PLATFORM)
487
stringsize += VG_(strlen)(cauxv->u.a_ptr) + 1;
488
auxsize += sizeof(*cauxv);
491
# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
492
auxsize += 2 * sizeof(*cauxv);
495
/* OK, now we know how big the client stack is */
497
sizeof(Word) + /* argc */
498
(have_exename ? sizeof(char **) : 0) + /* argc[0] == exename */
499
sizeof(char **)*argc + /* argv */
500
sizeof(char **) + /* terminal NULL */
501
sizeof(char **)*envc + /* envp */
502
sizeof(char **) + /* terminal NULL */
504
VG_ROUNDUP(stringsize, sizeof(Word)); /* strings (aligned) */
506
if (0) VG_(printf)("stacksize = %d\n", stacksize);
508
/* client_SP is the client's stack pointer */
509
client_SP = clstack_end - stacksize;
510
client_SP = VG_ROUNDDN(client_SP, 16); /* make stack 16 byte aligned */
512
/* base of the string table (aligned) */
513
stringbase = strtab = (char *)clstack_end
514
- VG_ROUNDUP(stringsize, sizeof(int));
516
clstack_start = VG_PGROUNDDN(client_SP);
518
/* The max stack size */
519
clstack_max_size = VG_PGROUNDUP(clstack_max_size);
521
/* Record stack extent -- needed for stack-change code. */
522
VG_(clstk_base) = clstack_start;
523
VG_(clstk_end) = clstack_end;
526
VG_(printf)("stringsize=%d auxsize=%d stacksize=%d maxsize=0x%x\n"
529
stringsize, auxsize, stacksize, (Int)clstack_max_size,
530
(void*)clstack_start, (void*)clstack_end);
532
/* ==================== allocate space ==================== */
534
{ SizeT anon_size = clstack_end - clstack_start + 1;
535
SizeT resvn_size = clstack_max_size - anon_size;
536
Addr anon_start = clstack_start;
537
Addr resvn_start = anon_start - resvn_size;
538
SizeT inner_HACK = 0;
541
/* So far we've only accounted for space requirements down to the
542
stack pointer. If this target's ABI requires a redzone below
543
the stack pointer, we need to allocate an extra page, to
544
handle the worst case in which the stack pointer is almost at
545
the bottom of a page, and so there is insufficient room left
546
over to put the redzone in. In this case the simple thing to
547
do is allocate an extra page, by shrinking the reservation by
548
one page and growing the anonymous area by a corresponding
550
vg_assert(VG_STACK_REDZONE_SZB >= 0);
551
vg_assert(VG_STACK_REDZONE_SZB < VKI_PAGE_SIZE);
552
if (VG_STACK_REDZONE_SZB > 0) {
553
vg_assert(resvn_size > VKI_PAGE_SIZE);
554
resvn_size -= VKI_PAGE_SIZE;
555
anon_start -= VKI_PAGE_SIZE;
556
anon_size += VKI_PAGE_SIZE;
559
vg_assert(VG_IS_PAGE_ALIGNED(anon_size));
560
vg_assert(VG_IS_PAGE_ALIGNED(resvn_size));
561
vg_assert(VG_IS_PAGE_ALIGNED(anon_start));
562
vg_assert(VG_IS_PAGE_ALIGNED(resvn_start));
563
vg_assert(resvn_start == clstack_end + 1 - clstack_max_size);
566
inner_HACK = 1024*1024; // create 1M non-fault-extending stack
570
VG_(printf)("%p 0x%x %p 0x%x\n",
571
resvn_start, resvn_size, anon_start, anon_size);
573
/* Create a shrinkable reservation followed by an anonymous
574
segment. Together these constitute a growdown stack. */
575
ok = VG_(am_create_reservation)(
577
resvn_size -inner_HACK,
579
anon_size +inner_HACK
582
/* allocate a stack - mmap enough space for the stack */
583
res = VG_(am_mmap_anon_fixed_client)(
584
anon_start -inner_HACK,
585
anon_size +inner_HACK,
586
VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC
588
vg_assert(!res.isError);
591
/* ==================== create client stack ==================== */
593
ptr = (Addr*)client_SP;
595
/* --- client argc --- */
596
*ptr++ = argc + (have_exename ? 1 : 0);
598
/* --- client argv --- */
599
if (info->interp_name) {
600
*ptr++ = (Addr)copy_str(&strtab, info->interp_name);
601
VG_(free)(info->interp_name);
603
if (info->interp_args) {
604
*ptr++ = (Addr)copy_str(&strtab, info->interp_args);
605
VG_(free)(info->interp_args);
609
*ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename));
611
for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
612
*ptr++ = (Addr)copy_str(
614
* (HChar**) VG_(indexXA)( VG_(args_for_client), i )
620
VG_(client_envp) = (Char **)ptr;
621
for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++)
622
*ptr = (Addr)copy_str(&strtab, *cpp);
626
auxv = (struct ume_auxv *)ptr;
627
*client_auxv = (UInt *)auxv;
629
# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
630
auxv[0].a_type = AT_IGNOREPPC;
631
auxv[0].u.a_val = AT_IGNOREPPC;
632
auxv[1].a_type = AT_IGNOREPPC;
633
auxv[1].u.a_val = AT_IGNOREPPC;
637
for (; orig_auxv->a_type != AT_NULL; auxv++, orig_auxv++) {
639
/* copy the entry... */
642
/* ...and fix up / examine the copy */
643
switch(auxv->a_type) {
656
/* All these are pointerless, so we don't need to do
657
anything about them. */
662
auxv->a_type = AT_IGNORE;
664
auxv->u.a_val = info->phdr;
669
auxv->a_type = AT_IGNORE;
671
auxv->u.a_val = info->phnum;
675
auxv->u.a_val = info->interp_base;
679
/* points to a platform description string */
680
auxv->u.a_ptr = copy_str(&strtab, orig_auxv->u.a_ptr);
684
auxv->u.a_val = info->entry;
693
# if defined(VGP_ppc32_linux)
694
/* acquire cache info */
695
if (auxv->u.a_val > 0) {
696
VG_(machine_ppc32_set_clszB)( auxv->u.a_val );
697
VG_(debugLog)(2, "initimg",
698
"PPC32 cache line size %u (type %u)\n",
699
(UInt)auxv->u.a_val, (UInt)auxv->a_type );
701
# elif defined(VGP_ppc64_linux)
702
/* acquire cache info */
703
if (auxv->u.a_val > 0) {
704
VG_(machine_ppc64_set_clszB)( auxv->u.a_val );
705
VG_(debugLog)(2, "initimg",
706
"PPC64 cache line size %u (type %u)\n",
707
(UInt)auxv->u.a_val, (UInt)auxv->a_type );
712
# if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
718
/* If this is 1, then it means that this program is
719
running suid, and therefore the dynamic linker should
720
be careful about LD_PRELOAD, etc. However, since
721
stage1 (the thing the kernel actually execve's) should
722
never be SUID, and we need LD_PRELOAD to work for the
723
client, we set AT_SECURE to 0. */
728
# if !defined(VGP_ppc32_linux) && !defined(VGP_ppc64_linux)
729
case AT_SYSINFO_EHDR:
731
/* Trash this, because we don't reproduce it */
732
auxv->a_type = AT_IGNORE;
736
/* stomp out anything we don't know about */
737
VG_(debugLog)(2, "initimg",
738
"stomping auxv entry %lld\n",
739
(ULong)auxv->a_type);
740
auxv->a_type = AT_IGNORE;
745
vg_assert(auxv->a_type == AT_NULL);
747
vg_assert((strtab-stringbase) == stringsize);
749
/* client_SP is pointing at client's argc/argv */
751
if (0) VG_(printf)("startup SP = %p\n", client_SP);
756
/* Allocate the client data segment. It is an expandable anonymous
757
mapping abutting a shrinkable reservation of size max_dseg_size.
758
The data segment starts at VG_(brk_base), which is page-aligned,
759
and runs up to VG_(brk_limit), which isn't. */
761
static void setup_client_dataseg ( SizeT max_size )
765
Addr anon_start = VG_(brk_base);
766
SizeT anon_size = VKI_PAGE_SIZE;
767
Addr resvn_start = anon_start + anon_size;
768
SizeT resvn_size = max_size - anon_size;
770
vg_assert(VG_IS_PAGE_ALIGNED(anon_size));
771
vg_assert(VG_IS_PAGE_ALIGNED(resvn_size));
772
vg_assert(VG_IS_PAGE_ALIGNED(anon_start));
773
vg_assert(VG_IS_PAGE_ALIGNED(resvn_start));
775
/* Because there's been no brk activity yet: */
776
vg_assert(VG_(brk_base) == VG_(brk_limit));
778
/* Try to create the data seg and associated reservation where
779
VG_(brk_base) says. */
780
ok = VG_(am_create_reservation)(
788
/* Hmm, that didn't work. Well, let aspacem suggest an address
789
it likes better, and try again with that. */
790
anon_start = VG_(am_get_advisory_client_simple)
791
( 0/*floating*/, anon_size+resvn_size, &ok );
793
resvn_start = anon_start + anon_size;
794
ok = VG_(am_create_reservation)(
801
VG_(brk_base) = VG_(brk_limit) = anon_start;
803
/* that too might have failed, but if it has, we're hosed: there
808
/* We make the data segment (heap) executable because LinuxThreads on
809
ppc32 creates trampolines in this area. Also, on x86/Linux the data
810
segment is RWX natively, at least according to /proc/self/maps.
811
Also, having a non-executable data seg would kill any program which
812
tried to create code in the data seg and then run it. */
813
sres = VG_(am_mmap_anon_fixed_client)(
816
VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC
818
vg_assert(!sres.isError);
819
vg_assert(sres.res == anon_start);
823
/*====================================================================*/
824
/*=== TOP-LEVEL: VG_(setup_client_initial_image) ===*/
825
/*====================================================================*/
827
/* Create the client's initial memory image. */
828
IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii )
833
IIFinaliseImageInfo iifii;
834
VG_(memset)( &iifii, 0, sizeof(iifii) );
836
//--------------------------------------------------------------
837
// Load client executable, finding in $PATH if necessary
838
// p: get_helprequest_and_toolname() [for 'exec', 'need_help']
839
// p: layout_remaining_space [so there's space]
840
//--------------------------------------------------------------
841
VG_(debugLog)(1, "initimg", "Loading client\n");
843
if (VG_(args_the_exename) == NULL)
844
VG_(err_missing_prog)();
846
load_client(&info, &iifii.initial_client_IP, &iifii.initial_client_TOC);
848
//--------------------------------------------------------------
849
// Set up client's environment
850
// p: set-libdir [for VG_(libdir)]
851
// p: get_helprequest_and_toolname [for toolname]
852
//--------------------------------------------------------------
853
VG_(debugLog)(1, "initimg", "Setup client env\n");
854
env = setup_client_env(iicii.envp, iicii.toolname);
856
//--------------------------------------------------------------
857
// Setup client stack, eip, and VG_(client_arg[cv])
858
// p: load_client() [for 'info']
859
// p: fix_environment() [for 'env']
860
//--------------------------------------------------------------
862
void* init_sp = iicii.argv - 1;
863
SizeT m1 = 1024 * 1024;
865
VG_(debugLog)(1, "initimg", "Setup client stack\n");
866
iifii.clstack_max_size = (SizeT)VG_(client_rlimit_stack).rlim_cur;
867
if (iifii.clstack_max_size < m1) iifii.clstack_max_size = m1;
868
if (iifii.clstack_max_size > m16) iifii.clstack_max_size = m16;
869
iifii.clstack_max_size = VG_PGROUNDUP(iifii.clstack_max_size);
871
iifii.initial_client_SP
872
= setup_client_stack( init_sp, env,
873
&info, &iifii.client_auxv,
874
iicii.clstack_top, iifii.clstack_max_size );
878
VG_(debugLog)(2, "initimg",
880
"initial_IP=%p initial_SP=%p initial_TOC=%p brk_base=%p\n",
881
(void*)(iifii.initial_client_IP),
882
(void*)(iifii.initial_client_SP),
883
(void*)(iifii.initial_client_TOC),
884
(void*)VG_(brk_base) );
887
//--------------------------------------------------------------
888
// Setup client data (brk) segment. Initially a 1-page segment
889
// which abuts a shrinkable reservation.
890
// p: load_client() [for 'info' and hence VG_(brk_base)]
891
//--------------------------------------------------------------
893
SizeT m1 = 1024 * 1024;
895
SizeT dseg_max_size = (SizeT)VG_(client_rlimit_data).rlim_cur;
896
VG_(debugLog)(1, "initimg", "Setup client data (brk) segment\n");
897
if (dseg_max_size < m1) dseg_max_size = m1;
898
if (dseg_max_size > m8) dseg_max_size = m8;
899
dseg_max_size = VG_PGROUNDUP(dseg_max_size);
901
setup_client_dataseg( dseg_max_size );
908
/*====================================================================*/
909
/*=== TOP-LEVEL: VG_(finalise_thread1state) ===*/
910
/*====================================================================*/
912
/* Just before starting the client, we may need to make final
913
adjustments to its initial image. Also we need to set up the VEX
914
guest state for thread 1 (the root thread) and copy in essential
915
starting values. This is handed the IIFinaliseImageInfo created by
916
VG_(ii_create_image).
918
void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii )
920
ThreadArchState* arch = &VG_(threads)[1].arch;
922
/* On Linux we get client_{ip/sp/toc}, and start the client with
923
all other registers zeroed. */
925
# if defined(VGP_x86_linux)
926
vg_assert(0 == sizeof(VexGuestX86State) % 8);
928
/* Zero out the initial state, and set up the simulated FPU in a
930
LibVEX_GuestX86_initialise(&arch->vex);
932
/* Zero out the shadow area. */
933
VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestX86State));
935
/* Put essential stuff into the new state. */
936
arch->vex.guest_ESP = iifii.initial_client_SP;
937
arch->vex.guest_EIP = iifii.initial_client_IP;
939
/* initialise %cs, %ds and %ss to point at the operating systems
940
default code, data and stack segments */
941
asm volatile("movw %%cs, %0" : : "m" (arch->vex.guest_CS));
942
asm volatile("movw %%ds, %0" : : "m" (arch->vex.guest_DS));
943
asm volatile("movw %%ss, %0" : : "m" (arch->vex.guest_SS));
945
# elif defined(VGP_amd64_linux)
946
vg_assert(0 == sizeof(VexGuestAMD64State) % 8);
948
/* Zero out the initial state, and set up the simulated FPU in a
950
LibVEX_GuestAMD64_initialise(&arch->vex);
952
/* Zero out the shadow area. */
953
VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestAMD64State));
955
/* Put essential stuff into the new state. */
956
arch->vex.guest_RSP = iifii.initial_client_SP;
957
arch->vex.guest_RIP = iifii.initial_client_IP;
959
# elif defined(VGP_ppc32_linux)
960
vg_assert(0 == sizeof(VexGuestPPC32State) % 8);
962
/* Zero out the initial state, and set up the simulated FPU in a
964
LibVEX_GuestPPC32_initialise(&arch->vex);
966
/* Zero out the shadow area. */
967
VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC32State));
969
/* Put essential stuff into the new state. */
970
arch->vex.guest_GPR1 = iifii.initial_client_SP;
971
arch->vex.guest_CIA = iifii.initial_client_IP;
973
# elif defined(VGP_ppc64_linux)
974
vg_assert(0 == sizeof(VexGuestPPC64State) % 16);
976
/* Zero out the initial state, and set up the simulated FPU in a
978
LibVEX_GuestPPC64_initialise(&arch->vex);
980
/* Zero out the shadow area. */
981
VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC64State));
983
/* Put essential stuff into the new state. */
984
arch->vex.guest_GPR1 = iifii.initial_client_SP;
985
arch->vex.guest_GPR2 = iifii.initial_client_TOC;
986
arch->vex.guest_CIA = iifii.initial_client_IP;
989
# error Unknown platform
992
/* Tell the tool that we just wrote to the registers. */
993
VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0,
994
sizeof(VexGuestArchState));
998
/*--------------------------------------------------------------------*/
999
/*--- initimg-linux.c ---*/
1000
/*--------------------------------------------------------------------*/