~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to coregrind/m_initimg/initimg-linux.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrés Roldán
  • Date: 2008-06-13 02:31:40 UTC
  • mto: (1.4.1 upstream) (2.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20080613023140-iwk33rz9rhvfkr96
Import upstream version 3.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*--------------------------------------------------------------------*/
 
3
/*--- Startup: create initial process image on Linux               ---*/
 
4
/*---                                              initimg-linux.c ---*/
 
5
/*--------------------------------------------------------------------*/
 
6
 
 
7
/*
 
8
   This file is part of Valgrind, a dynamic binary instrumentation
 
9
   framework.
 
10
 
 
11
   Copyright (C) 2000-2007 Julian Seward
 
12
      jseward@acm.org
 
13
 
 
14
   This program is free software; you can redistribute it and/or
 
15
   modify it under the terms of the GNU General Public License as
 
16
   published by the Free Software Foundation; either version 2 of the
 
17
   License, or (at your option) any later version.
 
18
 
 
19
   This program is distributed in the hope that it will be useful, but
 
20
   WITHOUT ANY WARRANTY; without even the implied warranty of
 
21
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
22
   General Public License for more details.
 
23
 
 
24
   You should have received a copy of the GNU General Public License
 
25
   along with this program; if not, write to the Free Software
 
26
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 
27
   02111-1307, USA.
 
28
 
 
29
   The GNU General Public License is contained in the file COPYING.
 
30
*/
 
31
 
 
32
#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 */
 
50
 
 
51
/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
 
52
#define _GNU_SOURCE
 
53
#define _FILE_OFFSET_BITS 64
 
54
/* This is for ELF types etc, and also the AT_ constants. */
 
55
#include <elf.h>
 
56
/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
 
57
 
 
58
 
 
59
/*====================================================================*/
 
60
/*=== Find executable                                              ===*/
 
61
/*====================================================================*/
 
62
 
 
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.
 
67
 
 
68
   This routine will return True if (*func) returns True and False if
 
69
   it reaches the end of the list without that happening.
 
70
*/
 
71
static Bool scan_colsep(char *colsep, Bool (*func)(const char *))
 
72
{
 
73
   char *cp, *entry;
 
74
   int end;
 
75
 
 
76
   if (colsep == NULL ||
 
77
       *colsep == '\0')
 
78
      return False;
 
79
 
 
80
   entry = cp = colsep;
 
81
 
 
82
   do {
 
83
      end = (*cp == '\0');
 
84
 
 
85
      if (*cp == ':' || *cp == '\0') {
 
86
         char save = *cp;
 
87
 
 
88
         *cp = '\0';
 
89
         if ((*func)(entry)) {
 
90
            *cp = save;
 
91
            return True;
 
92
         }
 
93
         *cp = save;
 
94
         entry = cp+1;
 
95
      }
 
96
      cp++;
 
97
   } while(!end);
 
98
 
 
99
   return False;
 
100
}
 
101
 
 
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];
 
105
 
 
106
static Bool match_executable(const char *entry) 
 
107
{
 
108
   HChar buf[VG_(strlen)(entry) + VG_(strlen)(executable_name_in) + 3];
 
109
 
 
110
   /* empty PATH element means '.' */
 
111
   if (*entry == '\0')
 
112
      entry = ".";
 
113
 
 
114
   VG_(snprintf)(buf, sizeof(buf), "%s/%s", entry, executable_name_in);
 
115
 
 
116
   // Don't match directories
 
117
   if (VG_(is_dir)(buf))
 
118
      return False;
 
119
 
 
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, "")) 
 
129
   {
 
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
 
133
   } else { 
 
134
      return False;     // Keep looking
 
135
   }
 
136
}
 
137
 
 
138
// Returns NULL if it wasn't found.
 
139
static HChar* find_executable ( HChar* exec )
 
140
{
 
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 );
 
145
   } else {
 
146
      // No '/' - we need to search the path
 
147
      HChar* 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);
 
152
   }
 
153
   return VG_STREQ(executable_name_out, "") ? NULL : executable_name_out;
 
154
}
 
155
 
 
156
 
 
157
/*====================================================================*/
 
158
/*=== Loading the client                                           ===*/
 
159
/*====================================================================*/
 
160
 
 
161
/* Load the client whose name is VG_(argv_the_exename). */
 
162
 
 
163
static void load_client ( /*OUT*/ExeInfo* info, 
 
164
                          /*OUT*/Addr*    client_ip,
 
165
                          /*OUT*/Addr*    client_toc)
 
166
{
 
167
   HChar* exe_name;
 
168
   Int    ret;
 
169
   SysRes res;
 
170
 
 
171
   vg_assert( VG_(args_the_exename) != NULL);
 
172
   exe_name = find_executable( VG_(args_the_exename) );
 
173
 
 
174
   if (!exe_name) {
 
175
      VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename));
 
176
      VG_(exit)(127);      // 127 is Posix NOTFOUND
 
177
   }
 
178
 
 
179
   VG_(memset)(info, 0, sizeof(*info));
 
180
   info->exe_base = VG_(client_base);
 
181
   info->exe_end  = VG_(client_end);
 
182
 
 
183
   ret = VG_(do_exec)(exe_name, info);
 
184
 
 
185
   // The client was successfully loaded!  Continue.
 
186
 
 
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);
 
190
   if (!res.isError)
 
191
      VG_(cl_exec_fd) = res.res;
 
192
 
 
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);
 
197
}
 
198
 
 
199
 
 
200
/*====================================================================*/
 
201
/*=== Setting up the client's environment                          ===*/
 
202
/*====================================================================*/
 
203
 
 
204
/* Prepare the client's environment.  This is basically a copy of our
 
205
   environment, except:
 
206
 
 
207
     LD_PRELOAD=$VALGRIND_LIB/PLATFORM/vgpreload_core.so:
 
208
                ($VALGRIND_LIB/PLATFORM/vgpreload_TOOL.so:)?
 
209
                $LD_PRELOAD
 
210
 
 
211
   If this is missing, then it is added.
 
212
 
 
213
   Also, remove any binding for VALGRIND_LAUNCHER=.  The client should
 
214
   not be able to see this.
 
215
 
 
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.
 
218
*/
 
219
static HChar** setup_client_env ( HChar** origenv, const HChar* toolname)
 
220
{
 
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));
 
228
 
 
229
   HChar** cpp;
 
230
   HChar** ret;
 
231
   HChar*  preload_tool_path;
 
232
   Int     envc, i;
 
233
 
 
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
 
237
      slop. */
 
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);
 
245
 
 
246
   /* Determine if there's a vgpreload_<tool>.so file, and setup
 
247
      preload_string. */
 
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);
 
255
   } else {
 
256
      VG_(snprintf)(preload_string, preload_string_len, "%s/%s/%s.so", 
 
257
                    VG_(libdir), VG_PLATFORM, preload_core);
 
258
   }
 
259
   VG_(free)(preload_tool_path);
 
260
 
 
261
   VG_(debugLog)(2, "initimg", "preload_string:\n");
 
262
   VG_(debugLog)(2, "initimg", "  \"%s\"\n", preload_string);
 
263
 
 
264
   /* Count the original size of the env */
 
265
   envc = 0;
 
266
   for (cpp = origenv; cpp && *cpp; cpp++)
 
267
      envc++;
 
268
 
 
269
   /* Allocate a new space */
 
270
   ret = VG_(malloc) (sizeof(HChar *) * (envc+1+1)); /* 1 new entry + NULL */
 
271
   vg_assert(ret);
 
272
 
 
273
   /* copy it over */
 
274
   for (cpp = ret; *origenv; )
 
275
      *cpp++ = *origenv++;
 
276
   *cpp = NULL;
 
277
   
 
278
   vg_assert(envc == (cpp - ret));
 
279
 
 
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);
 
285
         vg_assert(cp);
 
286
 
 
287
         VG_(snprintf)(cp, len, "%s%s:%s",
 
288
                       ld_preload, preload_string, (*cpp)+ld_preload_len);
 
289
 
 
290
         *cpp = cp;
 
291
 
 
292
         ld_preload_done = True;
 
293
      }
 
294
   }
 
295
 
 
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);
 
300
      vg_assert(cp);
 
301
 
 
302
      VG_(snprintf)(cp, len, "%s%s", ld_preload, preload_string);
 
303
 
 
304
      ret[envc++] = cp;
 
305
   }
 
306
 
 
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)))
 
311
         break;
 
312
 
 
313
   if (i < envc) {
 
314
      for (; i < envc-1; i++)
 
315
         ret[i] = ret[i+1];
 
316
      envc--;
 
317
   }
 
318
 
 
319
   VG_(free)(preload_string);
 
320
   ret[envc] = NULL;
 
321
 
 
322
   return ret;
 
323
}
 
324
 
 
325
 
 
326
/*====================================================================*/
 
327
/*=== Setting up the client's stack                                ===*/
 
328
/*====================================================================*/
 
329
 
 
330
#ifndef AT_DCACHEBSIZE
 
331
#define AT_DCACHEBSIZE          19
 
332
#endif /* AT_DCACHEBSIZE */
 
333
 
 
334
#ifndef AT_ICACHEBSIZE
 
335
#define AT_ICACHEBSIZE          20
 
336
#endif /* AT_ICACHEBSIZE */
 
337
 
 
338
#ifndef AT_UCACHEBSIZE
 
339
#define AT_UCACHEBSIZE          21
 
340
#endif /* AT_UCACHEBSIZE */
 
341
 
 
342
#ifndef AT_SYSINFO
 
343
#define AT_SYSINFO              32
 
344
#endif /* AT_SYSINFO */
 
345
 
 
346
#ifndef AT_SYSINFO_EHDR
 
347
#define AT_SYSINFO_EHDR         33
 
348
#endif /* AT_SYSINFO_EHDR */
 
349
 
 
350
#ifndef AT_SECURE
 
351
#define AT_SECURE 23   /* secure mode boolean */
 
352
#endif  /* AT_SECURE */
 
353
 
 
354
/* Add a string onto the string table, and return its address */
 
355
static char *copy_str(char **tab, const char *str)
 
356
{
 
357
   char *cp = *tab;
 
358
   char *orig = cp;
 
359
 
 
360
   while(*str)
 
361
      *cp++ = *str++;
 
362
   *cp++ = '\0';
 
363
 
 
364
   if (0)
 
365
      VG_(printf)("copied %p \"%s\" len %lld\n", orig, orig, (Long)(cp-orig));
 
366
 
 
367
   *tab = cp;
 
368
 
 
369
   return orig;
 
370
}
 
371
 
 
372
 
 
373
/* ----------------------------------------------------------------
 
374
 
 
375
   This sets up the client's initial stack, containing the args,
 
376
   environment and aux vector.
 
377
 
 
378
   The format of the stack is:
 
379
 
 
380
   higher address +-----------------+ <- clstack_end
 
381
                  |                 |
 
382
                  : string table    :
 
383
                  |                 |
 
384
                  +-----------------+
 
385
                  | AT_NULL         |
 
386
                  -                 -
 
387
                  | auxv            |
 
388
                  +-----------------+
 
389
                  | NULL            |
 
390
                  -                 -
 
391
                  | envp            |
 
392
                  +-----------------+
 
393
                  | NULL            |
 
394
                  -                 -
 
395
                  | argv            |
 
396
                  +-----------------+
 
397
                  | argc            |
 
398
   lower address  +-----------------+ <- sp
 
399
                  | undefined       |
 
400
                  :                 :
 
401
 
 
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.
 
405
 
 
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
 
408
   info are collected:
 
409
 
 
410
      VG_(cache_line_size_ppc32) // ppc32 only -- cache line size
 
411
      VG_(have_altivec_ppc32)    // ppc32 only -- is Altivec supported?
 
412
 
 
413
   ---------------------------------------------------------------- */
 
414
 
 
415
static 
 
416
Addr setup_client_stack( void*  init_sp,
 
417
                         char** orig_envp, 
 
418
                         const ExeInfo* info,
 
419
                         UInt** client_auxv,
 
420
                         Addr   clstack_end,
 
421
                         SizeT  clstack_max_size )
 
422
{
 
423
   SysRes res;
 
424
   char **cpp;
 
425
   char *strtab;                /* string table */
 
426
   char *stringbase;
 
427
   Addr *ptr;
 
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) */
 
437
   Addr clstack_start;
 
438
   Int i;
 
439
   Bool have_exename;
 
440
 
 
441
   vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1));
 
442
   vg_assert( VG_(args_for_client) );
 
443
 
 
444
   /* use our own auxv as a prototype */
 
445
   orig_auxv = VG_(find_auxv)(init_sp);
 
446
 
 
447
   /* ==================== compute sizes ==================== */
 
448
 
 
449
   /* first of all, work out how big the client stack will be */
 
450
   stringsize   = 0;
 
451
   have_exename = VG_(args_the_exename) != NULL;
 
452
 
 
453
   /* paste on the extra args if the loader needs them (ie, the #! 
 
454
      interpreter and its argument) */
 
455
   argc = 0;
 
456
   if (info->interp_name != NULL) {
 
457
      argc++;
 
458
      stringsize += VG_(strlen)(info->interp_name) + 1;
 
459
   }
 
460
   if (info->interp_args != NULL) {
 
461
      argc++;
 
462
      stringsize += VG_(strlen)(info->interp_args) + 1;
 
463
   }
 
464
 
 
465
   /* now scan the args we're given... */
 
466
   if (have_exename)
 
467
      stringsize += VG_(strlen)( VG_(args_the_exename) ) + 1;
 
468
 
 
469
   for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
 
470
      argc++;
 
471
      stringsize += VG_(strlen)( * (HChar**) 
 
472
                                   VG_(indexXA)( VG_(args_for_client), i ))
 
473
                    + 1;
 
474
   }
 
475
 
 
476
   /* ...and the environment */
 
477
   envc = 0;
 
478
   for (cpp = orig_envp; cpp && *cpp; cpp++) {
 
479
      envc++;
 
480
      stringsize += VG_(strlen)(*cpp) + 1;
 
481
   }
 
482
 
 
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);
 
489
   }
 
490
 
 
491
#  if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
 
492
   auxsize += 2 * sizeof(*cauxv);
 
493
#  endif
 
494
 
 
495
   /* OK, now we know how big the client stack is */
 
496
   stacksize =
 
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 */
 
503
      auxsize +                               /* auxv */
 
504
      VG_ROUNDUP(stringsize, sizeof(Word));   /* strings (aligned) */
 
505
 
 
506
   if (0) VG_(printf)("stacksize = %d\n", stacksize);
 
507
 
 
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 */
 
511
 
 
512
   /* base of the string table (aligned) */
 
513
   stringbase = strtab = (char *)clstack_end 
 
514
                         - VG_ROUNDUP(stringsize, sizeof(int));
 
515
 
 
516
   clstack_start = VG_PGROUNDDN(client_SP);
 
517
 
 
518
   /* The max stack size */
 
519
   clstack_max_size = VG_PGROUNDUP(clstack_max_size);
 
520
 
 
521
   /* Record stack extent -- needed for stack-change code. */
 
522
   VG_(clstk_base) = clstack_start;
 
523
   VG_(clstk_end)  = clstack_end;
 
524
 
 
525
   if (0)
 
526
      VG_(printf)("stringsize=%d auxsize=%d stacksize=%d maxsize=0x%x\n"
 
527
                  "clstack_start %p\n"
 
528
                  "clstack_end   %p\n",
 
529
                  stringsize, auxsize, stacksize, (Int)clstack_max_size,
 
530
                  (void*)clstack_start, (void*)clstack_end);
 
531
 
 
532
   /* ==================== allocate space ==================== */
 
533
 
 
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;
 
539
     Bool  ok;
 
540
 
 
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
 
549
        page. */
 
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;
 
557
     }
 
558
 
 
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);
 
564
 
 
565
#    ifdef ENABLE_INNER
 
566
     inner_HACK = 1024*1024; // create 1M non-fault-extending stack
 
567
#    endif
 
568
 
 
569
     if (0)
 
570
        VG_(printf)("%p 0x%x  %p 0x%x\n", 
 
571
                    resvn_start, resvn_size, anon_start, anon_size);
 
572
 
 
573
     /* Create a shrinkable reservation followed by an anonymous
 
574
        segment.  Together these constitute a growdown stack. */
 
575
     ok = VG_(am_create_reservation)(
 
576
             resvn_start,
 
577
             resvn_size -inner_HACK,
 
578
             SmUpper, 
 
579
             anon_size +inner_HACK
 
580
          );
 
581
     vg_assert(ok);
 
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
 
587
           );
 
588
     vg_assert(!res.isError); 
 
589
   }
 
590
 
 
591
   /* ==================== create client stack ==================== */
 
592
 
 
593
   ptr = (Addr*)client_SP;
 
594
 
 
595
   /* --- client argc --- */
 
596
   *ptr++ = argc + (have_exename ? 1 : 0);
 
597
 
 
598
   /* --- client argv --- */
 
599
   if (info->interp_name) {
 
600
      *ptr++ = (Addr)copy_str(&strtab, info->interp_name);
 
601
      VG_(free)(info->interp_name);
 
602
   }
 
603
   if (info->interp_args) {
 
604
      *ptr++ = (Addr)copy_str(&strtab, info->interp_args);
 
605
      VG_(free)(info->interp_args);
 
606
   }
 
607
 
 
608
   if (have_exename)
 
609
      *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename));
 
610
 
 
611
   for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
 
612
      *ptr++ = (Addr)copy_str(
 
613
                       &strtab, 
 
614
                       * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
 
615
                     );
 
616
   }
 
617
   *ptr++ = 0;
 
618
 
 
619
   /* --- envp --- */
 
620
   VG_(client_envp) = (Char **)ptr;
 
621
   for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++)
 
622
      *ptr = (Addr)copy_str(&strtab, *cpp);
 
623
   *ptr++ = 0;
 
624
 
 
625
   /* --- auxv --- */
 
626
   auxv = (struct ume_auxv *)ptr;
 
627
   *client_auxv = (UInt *)auxv;
 
628
 
 
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;
 
634
   auxv += 2;
 
635
#  endif
 
636
 
 
637
   for (; orig_auxv->a_type != AT_NULL; auxv++, orig_auxv++) {
 
638
 
 
639
      /* copy the entry... */
 
640
      *auxv = *orig_auxv;
 
641
 
 
642
      /* ...and fix up / examine the copy */
 
643
      switch(auxv->a_type) {
 
644
 
 
645
         case AT_IGNORE:
 
646
         case AT_PHENT:
 
647
         case AT_PAGESZ:
 
648
         case AT_FLAGS:
 
649
         case AT_NOTELF:
 
650
         case AT_UID:
 
651
         case AT_EUID:
 
652
         case AT_GID:
 
653
         case AT_EGID:
 
654
         case AT_CLKTCK:
 
655
         case AT_FPUCW:
 
656
            /* All these are pointerless, so we don't need to do
 
657
               anything about them. */
 
658
            break;
 
659
 
 
660
         case AT_PHDR:
 
661
            if (info->phdr == 0)
 
662
               auxv->a_type = AT_IGNORE;
 
663
            else
 
664
               auxv->u.a_val = info->phdr;
 
665
            break;
 
666
 
 
667
         case AT_PHNUM:
 
668
            if (info->phdr == 0)
 
669
               auxv->a_type = AT_IGNORE;
 
670
            else
 
671
               auxv->u.a_val = info->phnum;
 
672
            break;
 
673
 
 
674
         case AT_BASE:
 
675
            auxv->u.a_val = info->interp_base;
 
676
            break;
 
677
 
 
678
         case AT_PLATFORM:
 
679
            /* points to a platform description string */
 
680
            auxv->u.a_ptr = copy_str(&strtab, orig_auxv->u.a_ptr);
 
681
            break;
 
682
 
 
683
         case AT_ENTRY:
 
684
            auxv->u.a_val = info->entry;
 
685
            break;
 
686
 
 
687
         case AT_HWCAP:
 
688
            break;
 
689
 
 
690
         case AT_DCACHEBSIZE:
 
691
         case AT_ICACHEBSIZE:
 
692
         case AT_UCACHEBSIZE:
 
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 );
 
700
            }
 
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 );
 
708
            }
 
709
#           endif
 
710
            break;
 
711
 
 
712
#        if defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux)
 
713
         case AT_IGNOREPPC:
 
714
            break;
 
715
#        endif
 
716
 
 
717
         case AT_SECURE:
 
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. */
 
724
            auxv->u.a_val = 0;
 
725
            break;
 
726
 
 
727
         case AT_SYSINFO:
 
728
#        if !defined(VGP_ppc32_linux) && !defined(VGP_ppc64_linux)
 
729
         case AT_SYSINFO_EHDR:
 
730
#        endif
 
731
            /* Trash this, because we don't reproduce it */
 
732
            auxv->a_type = AT_IGNORE;
 
733
            break;
 
734
 
 
735
         default:
 
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;
 
741
            break;
 
742
      }
 
743
   }
 
744
   *auxv = *orig_auxv;
 
745
   vg_assert(auxv->a_type == AT_NULL);
 
746
 
 
747
   vg_assert((strtab-stringbase) == stringsize);
 
748
 
 
749
   /* client_SP is pointing at client's argc/argv */
 
750
 
 
751
   if (0) VG_(printf)("startup SP = %p\n", client_SP);
 
752
   return client_SP;
 
753
}
 
754
 
 
755
 
 
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. */
 
760
 
 
761
static void setup_client_dataseg ( SizeT max_size )
 
762
{
 
763
   Bool   ok;
 
764
   SysRes sres;
 
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;
 
769
 
 
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));
 
774
 
 
775
   /* Because there's been no brk activity yet: */
 
776
   vg_assert(VG_(brk_base) == VG_(brk_limit));
 
777
 
 
778
   /* Try to create the data seg and associated reservation where
 
779
      VG_(brk_base) says. */
 
780
   ok = VG_(am_create_reservation)( 
 
781
           resvn_start, 
 
782
           resvn_size, 
 
783
           SmLower, 
 
784
           anon_size
 
785
        );
 
786
 
 
787
   if (!ok) {
 
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 );
 
792
      if (ok) {
 
793
         resvn_start = anon_start + anon_size;
 
794
         ok = VG_(am_create_reservation)( 
 
795
                 resvn_start, 
 
796
                 resvn_size, 
 
797
                 SmLower, 
 
798
                 anon_size
 
799
              );
 
800
         if (ok)
 
801
            VG_(brk_base) = VG_(brk_limit) = anon_start;
 
802
      }
 
803
      /* that too might have failed, but if it has, we're hosed: there
 
804
         is no Plan C. */
 
805
   }
 
806
   vg_assert(ok);
 
807
 
 
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)( 
 
814
             anon_start, 
 
815
             anon_size, 
 
816
             VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC
 
817
          );
 
818
   vg_assert(!sres.isError);
 
819
   vg_assert(sres.res == anon_start);
 
820
}
 
821
 
 
822
 
 
823
/*====================================================================*/
 
824
/*=== TOP-LEVEL: VG_(setup_client_initial_image)                   ===*/
 
825
/*====================================================================*/
 
826
 
 
827
/* Create the client's initial memory image. */
 
828
IIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii )
 
829
{
 
830
   ExeInfo info;
 
831
   HChar** env = NULL;
 
832
 
 
833
   IIFinaliseImageInfo iifii;
 
834
   VG_(memset)( &iifii, 0, sizeof(iifii) );
 
835
 
 
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");
 
842
 
 
843
   if (VG_(args_the_exename) == NULL)
 
844
      VG_(err_missing_prog)();
 
845
 
 
846
   load_client(&info, &iifii.initial_client_IP, &iifii.initial_client_TOC);
 
847
 
 
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);
 
855
 
 
856
   //--------------------------------------------------------------
 
857
   // Setup client stack, eip, and VG_(client_arg[cv])
 
858
   //   p: load_client()     [for 'info']
 
859
   //   p: fix_environment() [for 'env']
 
860
   //--------------------------------------------------------------
 
861
   {
 
862
      void* init_sp = iicii.argv - 1;
 
863
      SizeT m1  = 1024 * 1024;
 
864
      SizeT m16 = 16 * m1;
 
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);
 
870
 
 
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 );
 
875
 
 
876
      VG_(free)(env);
 
877
 
 
878
      VG_(debugLog)(2, "initimg",
 
879
                       "Client info: "
 
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) );
 
885
   }
 
886
 
 
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
   //--------------------------------------------------------------
 
892
   { 
 
893
      SizeT m1 = 1024 * 1024;
 
894
      SizeT m8 = 8 * m1;
 
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);
 
900
 
 
901
      setup_client_dataseg( dseg_max_size );
 
902
   }
 
903
 
 
904
   return iifii;
 
905
}
 
906
 
 
907
 
 
908
/*====================================================================*/
 
909
/*=== TOP-LEVEL: VG_(finalise_thread1state)                        ===*/
 
910
/*====================================================================*/
 
911
 
 
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).
 
917
*/
 
918
void VG_(ii_finalise_image)( IIFinaliseImageInfo iifii )
 
919
{
 
920
   ThreadArchState* arch = &VG_(threads)[1].arch;
 
921
 
 
922
   /* On Linux we get client_{ip/sp/toc}, and start the client with
 
923
      all other registers zeroed. */
 
924
 
 
925
#  if defined(VGP_x86_linux)
 
926
   vg_assert(0 == sizeof(VexGuestX86State) % 8);
 
927
 
 
928
   /* Zero out the initial state, and set up the simulated FPU in a
 
929
      sane way. */
 
930
   LibVEX_GuestX86_initialise(&arch->vex);
 
931
 
 
932
   /* Zero out the shadow area. */
 
933
   VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestX86State));
 
934
 
 
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;
 
938
 
 
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));
 
944
 
 
945
#  elif defined(VGP_amd64_linux)
 
946
   vg_assert(0 == sizeof(VexGuestAMD64State) % 8);
 
947
 
 
948
   /* Zero out the initial state, and set up the simulated FPU in a
 
949
      sane way. */
 
950
   LibVEX_GuestAMD64_initialise(&arch->vex);
 
951
 
 
952
   /* Zero out the shadow area. */
 
953
   VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestAMD64State));
 
954
 
 
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;
 
958
 
 
959
#  elif defined(VGP_ppc32_linux)
 
960
   vg_assert(0 == sizeof(VexGuestPPC32State) % 8);
 
961
 
 
962
   /* Zero out the initial state, and set up the simulated FPU in a
 
963
      sane way. */
 
964
   LibVEX_GuestPPC32_initialise(&arch->vex);
 
965
 
 
966
   /* Zero out the shadow area. */
 
967
   VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC32State));
 
968
 
 
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;
 
972
 
 
973
#  elif defined(VGP_ppc64_linux)
 
974
   vg_assert(0 == sizeof(VexGuestPPC64State) % 16);
 
975
 
 
976
   /* Zero out the initial state, and set up the simulated FPU in a
 
977
      sane way. */
 
978
   LibVEX_GuestPPC64_initialise(&arch->vex);
 
979
 
 
980
   /* Zero out the shadow area. */
 
981
   VG_(memset)(&arch->vex_shadow, 0, sizeof(VexGuestPPC64State));
 
982
 
 
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;
 
987
 
 
988
#  else
 
989
#    error Unknown platform
 
990
#  endif
 
991
 
 
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));
 
995
}
 
996
 
 
997
 
 
998
/*--------------------------------------------------------------------*/
 
999
/*---                                              initimg-linux.c ---*/
 
1000
/*--------------------------------------------------------------------*/