• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*--------------------------------------------------------------------*/
3 /*--- Startup: create initial process image on Solaris             ---*/
4 /*---                                            initimg-solaris.c ---*/
5 /*--------------------------------------------------------------------*/
6 
7 /*
8    This file is part of Valgrind, a dynamic binary instrumentation
9    framework.
10 
11    Copyright (C) 2011-2017 Petr Pavlu
12       setup@dagobah.cz
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 /* Copyright 2013-2017, Ivo Raisr <ivosh@ivosh.net>. */
33 
34 #if defined(VGO_solaris)
35 
36 /* Note: This file is based on initimg-linux.c. */
37 
38 #include "pub_core_basics.h"
39 #include "pub_core_vki.h"
40 #include "pub_core_debuglog.h"
41 #include "pub_core_libcbase.h"
42 #include "pub_core_libcassert.h"
43 #include "pub_core_libcfile.h"
44 #include "pub_core_libcproc.h"
45 #include "pub_core_libcprint.h"
46 #include "pub_core_xarray.h"
47 #include "pub_core_clientstate.h"
48 #include "pub_core_aspacemgr.h"
49 #include "pub_core_mallocfree.h"
50 #include "pub_core_machine.h"
51 #include "pub_core_ume.h"
52 #include "pub_core_options.h"
53 #include "pub_core_syswrap.h"
54 #include "pub_core_tooliface.h"       /* VG_TRACK */
55 #include "pub_core_threadstate.h"     /* ThreadArchState */
56 #include "priv_initimg_pathscan.h"
57 #include "pub_core_initimg.h"         /* self */
58 
59 
60 /*====================================================================*/
61 /*=== Loading the client                                           ===*/
62 /*====================================================================*/
63 
64 /* Load the client whose name is VG_(argv_the_exename). */
load_client(ExeInfo * info,HChar * out_exe_name,SizeT out_exe_name_size)65 static void load_client(/*OUT*/ExeInfo *info,
66                         /*OUT*/HChar *out_exe_name, SizeT out_exe_name_size)
67 {
68    const HChar *exe_name;
69    Int ret;
70    SysRes res;
71 
72    vg_assert(VG_(args_the_exename));
73    exe_name = ML_(find_executable)(VG_(args_the_exename));
74 
75    if (!exe_name) {
76       VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename));
77       /* Return POSIX's NOTFOUND. */
78       VG_(exit)(127);
79       /*NOTREACHED*/
80    }
81 
82    VG_(memset)(info, 0, sizeof(*info));
83    ret = VG_(do_exec)(exe_name, info);
84    if (ret < 0) {
85       VG_(printf)("valgrind: could not execute '%s'\n", exe_name);
86       VG_(exit)(1);
87       /*NOTREACHED*/
88    }
89 
90    /* The client was successfully loaded!  Continue. */
91 
92    /* Save resolved exename. */
93    if (VG_(strlen)(exe_name) + 1 > out_exe_name_size) {
94       /* This should not really happen. */
95       VG_(printf)("valgrind: execname %s is too long\n", exe_name);
96       VG_(exit)(1);
97       /*NOTREACHED*/
98    }
99    VG_(strcpy)(out_exe_name, exe_name);
100 
101    /* Get hold of a file descriptor which refers to the client executable.
102       This is needed for attaching to GDB. */
103    res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR);
104    if (!sr_isError(res))
105       VG_(cl_exec_fd) = sr_Res(res);
106 
107    /* Set initial brk values. */
108    if (info->ldsoexec) {
109       VG_(brk_base) = VG_(brk_limit) = -1;
110    } else {
111       VG_(brk_base) = VG_(brk_limit) = info->brkbase;
112    }
113 }
114 
115 
116 /*====================================================================*/
117 /*=== Setting up the client's environment                          ===*/
118 /*====================================================================*/
119 
120 /* Prepare the client's environment.  This is basically a copy of our
121    environment, except:
122 
123      LD_PRELOAD=$VALGRIND_LIB/vgpreload_core-PLATFORM.so:
124                 ($VALGRIND_LIB/vgpreload_TOOL-PLATFORM.so:)?
125                 $LD_PRELOAD
126 
127    If this is missing, then it is added.
128 
129    Also, remove any binding for VALGRIND_LAUNCHER=.  The client should not be
130    able to see this.
131 
132    If this needs to handle any more variables it should be hacked into
133    something table driven.  The copy is VG_(malloc)'d space.
134 */
setup_client_env(HChar ** origenv,const HChar * toolname)135 static HChar **setup_client_env(HChar **origenv, const HChar *toolname)
136 {
137    const HChar *ld_preload = "LD_PRELOAD=";
138    SizeT ld_preload_len = VG_(strlen)(ld_preload);
139    Bool ld_preload_done = False;
140    SizeT vglib_len = VG_(strlen)(VG_(libdir));
141 
142    HChar **cpp;
143    HChar **ret;
144    HChar *preload_tool_path;
145    SizeT envc, i;
146 
147    /* Alloc space for the
148         <path>/vgpreload_core-<platform>.so and
149         <path>/vgpreload_<tool>-<platform>.so
150       paths.  We might not need the space for the tool path, but it doesn't
151       hurt to over-allocate briefly.  */
152    SizeT preload_core_path_size = vglib_len + sizeof("/vgpreload_core-") - 1
153                                             + sizeof(VG_PLATFORM) - 1
154                                             + sizeof(".so");
155    SizeT preload_tool_path_size = vglib_len + sizeof("/vgpreload_") - 1
156                                             + VG_(strlen)(toolname) + 1 /*-*/
157                                             + sizeof(VG_PLATFORM) - 1
158                                             + sizeof(".so");
159    SizeT preload_string_size = preload_core_path_size
160                                + preload_tool_path_size;
161    HChar *preload_string = VG_(malloc)("initimg-solaris.sce.1",
162                                        preload_string_size);
163 
164    /* Check that the parameters are sane. */
165    vg_assert(origenv);
166    vg_assert(toolname);
167 
168    /* Determine if there's a vgpreload_<tool>-<platform>.so file, and setup
169       preload_string. */
170    preload_tool_path = VG_(malloc)("initimg-solaris.sce.2",
171                                    preload_tool_path_size);
172    VG_(sprintf)(preload_tool_path, "%s/vgpreload_%s-%s.so", VG_(libdir),
173                 toolname, VG_PLATFORM);
174    if (!VG_(access)(preload_tool_path, True/*r*/, False/*w*/, False/*x*/)) {
175       /* The tool's .so exists, put it into LD_PRELOAD with the core's so. */
176       VG_(sprintf)(preload_string, "%s/vgpreload_core-%s.so:%s", VG_(libdir),
177                    VG_PLATFORM, preload_tool_path);
178    }
179    else {
180       /* The tool's .so doesn't exist, put only the core's .so into
181          LD_PRELOAD. */
182       VG_(sprintf)(preload_string, "%s/vgpreload_core-%s.so", VG_(libdir),
183                    VG_PLATFORM);
184    }
185    VG_(free)(preload_tool_path);
186 
187    VG_(debugLog)(2, "initimg", "preload_string:\n");
188    VG_(debugLog)(2, "initimg", "  \"%s\"\n", preload_string);
189 
190    /* Count the original size of the env. */
191    envc = 0;
192    for (cpp = origenv; *cpp; cpp++)
193       envc++;
194 
195    /* Allocate a new space, envc + 1 new entry + NULL. */
196    ret = VG_(malloc)("initimg-solaris.sce.3", sizeof(HChar*) * (envc + 1 + 1));
197 
198    /* Copy it over. */
199    for (cpp = ret; *origenv; )
200       *cpp++ = *origenv++;
201    *cpp = NULL;
202 
203    vg_assert(envc == cpp - ret);
204 
205    /* Walk over the new environment, mashing as we go. */
206    for (cpp = ret; *cpp; cpp++) {
207       if (VG_(memcmp)(*cpp, ld_preload, ld_preload_len))
208          continue;
209 
210       /* LD_PRELOAD entry found, smash it. */
211       SizeT size = VG_(strlen)(*cpp) + 1 /*:*/
212                                      + preload_string_size;
213       HChar *cp = VG_(malloc)("initimg-solaris.sce.4", size);
214 
215       VG_(sprintf)(cp, "%s%s:%s", ld_preload, preload_string,
216                    (*cpp) + ld_preload_len);
217       *cpp = cp;
218 
219       ld_preload_done = True;
220    }
221 
222    /* Add the missing bits. */
223    if (!ld_preload_done) {
224       SizeT size = ld_preload_len + preload_string_size;
225       HChar *cp = VG_(malloc)("initimg-solaris.sce.5", size);
226 
227       VG_(sprintf)(cp, "%s%s", ld_preload, preload_string);
228       ret[envc++] = cp;
229    }
230 
231    /* We've got ret[0 .. envc-1] live now. */
232 
233    /* Find and remove a binding for VALGRIND_LAUNCHER. */
234    {
235       const HChar *v_launcher = VALGRIND_LAUNCHER "=";
236       SizeT v_launcher_len = VG_(strlen)(v_launcher);
237 
238       for (i = 0; i < envc; i++)
239          if (!VG_(memcmp)(ret[i], v_launcher, v_launcher_len)) {
240             /* VALGRIND_LAUNCHER was found. */
241             break;
242          }
243 
244       if (i < envc) {
245          /* VALGRIND_LAUNCHER was found, remove it. */
246          for (; i < envc - 1; i++)
247             ret[i] = ret[i + 1];
248          envc--;
249       }
250    }
251 
252    VG_(free)(preload_string);
253    ret[envc] = NULL;
254 
255    return ret;
256 }
257 
258 
259 /*====================================================================*/
260 /*=== Setting up the client's stack                                ===*/
261 /*====================================================================*/
262 
263 /* Add a string onto the string table, and return its address. */
copy_str(HChar ** tab,const HChar * str)264 static HChar *copy_str(HChar **tab, const HChar *str)
265 {
266    HChar *cp = *tab;
267    HChar *orig = cp;
268 
269    while (*str)
270       *cp++ = *str++;
271    *cp++ = '\0';
272 
273    *tab = cp;
274 
275    return orig;
276 }
277 
278 #if defined(SOLARIS_RESERVE_SYSSTAT_ADDR) || \
279     defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR)
280 #define ORIG_AUXV_PRESENT 1
281 #endif
282 
283 #if defined(ORIG_AUXV_PRESENT)
284 /* The auxiliary vector might not be present. So we cross-check pointers from
285    argv and envp pointing to the string table. */
find_original_auxv(Addr init_sp)286 static vki_auxv_t *find_original_auxv(Addr init_sp)
287 {
288    HChar **sp = (HChar **) init_sp;
289    HChar *lowest_str_ptr = (HChar *) UINTPTR_MAX; // lowest ptr to string table
290 
291    sp++; // skip argc
292 
293    while (*sp != NULL) { // skip argv
294       if (*sp < lowest_str_ptr)
295          lowest_str_ptr = *sp;
296       sp++;
297    }
298    sp++;
299 
300    while (*sp != 0) { // skip env
301       if (*sp < lowest_str_ptr)
302          lowest_str_ptr = *sp;
303       sp++;
304    }
305    sp++;
306 
307    if ((Addr) sp < (Addr) lowest_str_ptr) {
308       return (vki_auxv_t *) sp;
309    } else {
310       return NULL;
311    }
312 }
313 
copy_auxv_entry(const vki_auxv_t * orig_auxv,Int type,const HChar * type_name,vki_auxv_t * auxv)314 static void copy_auxv_entry(const vki_auxv_t *orig_auxv, Int type,
315                             const HChar *type_name, vki_auxv_t *auxv)
316 {
317    vg_assert(auxv != NULL);
318 
319    if (orig_auxv == NULL) {
320       VG_(printf)("valgrind: Cannot locate auxiliary vector.\n");
321       VG_(printf)("valgrind: Cannot continue. Sorry.\n\n");
322       VG_(exit)(1);
323    }
324 
325    for ( ; orig_auxv->a_type != VKI_AT_NULL; orig_auxv++) {
326       if (orig_auxv->a_type == type) {
327          auxv->a_type = type;
328          auxv->a_un.a_val = orig_auxv->a_un.a_val;
329          return;
330       }
331    }
332 
333    VG_(printf)("valgrind: Cannot locate %s in the aux\n", type_name);
334    VG_(printf)("valgrind: vector. Cannot continue. Sorry.\n\n");
335    VG_(exit)(1);
336 }
337 #endif /* ORIG_AUXV_PRESENT */
338 
339 /* This sets up the client's initial stack, containing the args,
340    environment and aux vector.
341 
342    The format of the stack is:
343 
344    higher address +-----------------+ <- clstack_end
345                   |                 |
346                   : string table    :
347                   |                 |
348                   +-----------------+
349                   | AT_NULL         |
350                   -                 -
351                   | auxv            |
352                   +-----------------+
353                   | NULL            |
354                   -                 -
355                   | envp            |
356                   +-----------------+
357                   | NULL            |
358                   -                 -
359                   | argv            |
360                   +-----------------+
361                   | argc            |
362    lower address  +-----------------+ <- sp
363                   | undefined       |
364                   :                 :
365 
366    Allocate and create the initial client stack.  It is allocated down from
367    clstack_end, which was previously determined by the address space manager.
368    The returned value is the SP value for the client.
369 
370    Note that auxiliary vector is *not* created by kernel on illumos and
371    Solaris 11 if the program is statically linked (which is our case).
372    Although we now taught Solaris 12 to create the auxiliary vector, we still
373    have to build auxv from scratch, to make the code consistent. */
374 
setup_client_stack(Addr init_sp,HChar ** orig_envp,const ExeInfo * info,Addr clstack_end,SizeT clstack_max_size,const HChar * resolved_exe_name)375 static Addr setup_client_stack(Addr init_sp,
376                                HChar **orig_envp,
377                                const ExeInfo *info,
378                                Addr clstack_end,
379                                SizeT clstack_max_size,
380                                const HChar *resolved_exe_name)
381 {
382    SysRes res;
383    HChar **cpp;
384    HChar *strtab;       /* string table */
385    HChar *stringbase;
386    Addr *ptr;
387    vki_auxv_t *auxv;
388    SizeT stringsize;    /* total size of strings in bytes */
389    SizeT auxsize;       /* total size of auxv in bytes */
390    Int argc;            /* total argc */
391    Int envc;            /* total number of env vars */
392    SizeT stacksize;     /* total client stack size */
393    Addr client_SP;      /* client stack base (initial SP) */
394    Addr clstack_start;
395    Int i;
396 
397    vg_assert(VG_IS_PAGE_ALIGNED(clstack_end + 1));
398    vg_assert(VG_(args_the_exename));
399    vg_assert(VG_(args_for_client));
400 
401 #  if defined(ORIG_AUXV_PRESENT)
402    /* Get the original auxv (if any). */
403    vki_auxv_t *orig_auxv = find_original_auxv(init_sp);
404 #  endif /* ORIG_AUXV_PRESENT */
405 
406    /* ==================== compute sizes ==================== */
407 
408    /* First of all, work out how big the client stack will be. */
409    stringsize = 0;
410 
411    /* Paste on the extra args if the loader needs them (i.e. the #!
412       interpreter and its argument). */
413    argc = 0;
414    if (info->interp_name) {
415       argc++;
416       stringsize += VG_(strlen)(info->interp_name) + 1;
417    }
418    if (info->interp_args) {
419       argc++;
420       stringsize += VG_(strlen)(info->interp_args) + 1;
421    }
422 
423    /* Now scan the args we're given... */
424    argc++;
425    stringsize += VG_(strlen)(VG_(args_the_exename)) + 1;
426    for (i = 0; i < VG_(sizeXA)(VG_(args_for_client)); i++) {
427       argc++;
428       stringsize += VG_(strlen)(*(HChar**)
429                                   VG_(indexXA)(VG_(args_for_client), i)) + 1;
430    }
431 
432    /* ...and the environment. */
433    envc = 0;
434    for (cpp = orig_envp; *cpp; cpp++) {
435       envc++;
436       stringsize += VG_(strlen)(*cpp) + 1;
437    }
438 
439    /* Now, how big is the auxv?
440 
441       AT_SUN_PLATFORM
442       AT_SUN_EXECNAME
443       AT_PHDR            (not for elfs with no PT_PHDR, such as ld.so.1)
444       AT_BASE
445       AT_ENTRY
446       AT_FLAGS
447       AT_PAGESZ
448       AT_SUN_AUXFLAFGS
449       AT_SUN_HWCAP
450       AT_SUN_SYSSTAT_ADDR      (if supported)
451       AT_SUN_SYSSTAT_ZONE_ADDR (if supported)
452       AT_NULL
453 
454       It would be possible to also add AT_PHENT, AT_PHNUM, AT_SUN_LDDATA,
455       but they don't seem to be so important. */
456    auxsize = 10 * sizeof(*auxv);
457 #  if defined(SOLARIS_RESERVE_SYSSTAT_ADDR)
458    auxsize += sizeof(*auxv);
459 #  endif
460 #  if defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR)
461    auxsize += sizeof(*auxv);
462 #  endif
463 
464 #  if defined(VGA_x86) || defined(VGA_amd64)
465    /* AT_SUN_PLATFORM string. */
466    stringsize += VG_(strlen)("i86pc") + 1;
467 #  else
468 #    error "Unknown architecture"
469 #  endif
470    /* AT_SUN_EXECNAME string. */
471    stringsize += VG_(strlen)(resolved_exe_name) + 1;
472 
473    /* Calculate how big the client stack is. */
474    stacksize =
475       sizeof(Word) +                            /* argc */
476       sizeof(HChar**) +                         /* argc[0] == exename */
477       sizeof(HChar**) * argc +                  /* argv */
478       sizeof(HChar**) +                         /* terminal NULL */
479       sizeof(HChar**) * envc +                  /* envp */
480       sizeof(HChar**) +                         /* terminal NULL */
481       auxsize +                                 /* auxv */
482       VG_ROUNDUP(stringsize, sizeof(Word));     /* strings (aligned) */
483 
484    /* The variable client_SP is the client's stack pointer. */
485    client_SP = clstack_end - stacksize;
486    client_SP = VG_ROUNDDN(client_SP, 16); /* Make stack 16 byte aligned. */
487 
488    /* Calculate base of the string table (aligned). */
489    stringbase = (HChar*)clstack_end - VG_ROUNDUP(stringsize, sizeof(Int));
490    strtab = stringbase;
491 
492    clstack_start = VG_PGROUNDDN(client_SP);
493 
494    /* Calculate the max stack size. */
495    clstack_max_size = VG_PGROUNDUP(clstack_max_size);
496 
497    /* Record stack extent -- needed for stack-change code. */
498    VG_(clstk_start_base) = clstack_start;
499    VG_(clstk_end) = clstack_end;
500    VG_(clstk_max_size) = clstack_max_size;
501 
502    if (0)
503       VG_(printf)("stringsize=%lu, auxsize=%lu, stacksize=%lu, maxsize=%#lx\n"
504                   "clstack_start %#lx\n"
505                   "clstack_end   %#lx\n",
506                   stringsize, auxsize, stacksize, clstack_max_size,
507                   clstack_start, clstack_end);
508 
509    /* ==================== allocate space ==================== */
510 
511    {
512       SizeT anon_size = clstack_end - clstack_start + 1;
513       SizeT resvn_size = clstack_max_size - anon_size;
514       Addr anon_start = clstack_start;
515       Addr resvn_start = anon_start - resvn_size;
516       SizeT inner_HACK = 0;
517       Bool ok;
518 
519       /* So far we've only accounted for space requirements down to the stack
520          pointer.  If this target's ABI requires a redzone below the stack
521          pointer, we need to allocate an extra page, to handle the worst case
522          in which the stack pointer is almost at the bottom of a page, and so
523          there is insufficient room left over to put the redzone in.  In this
524          case the simple thing to do is allocate an extra page, by shrinking
525          the reservation by one page and growing the anonymous area by a
526          corresponding page. */
527       vg_assert(VG_STACK_REDZONE_SZB >= 0);
528       vg_assert(VG_STACK_REDZONE_SZB < VKI_PAGE_SIZE);
529       if (VG_STACK_REDZONE_SZB > 0) {
530          vg_assert(resvn_size > VKI_PAGE_SIZE);
531          resvn_size -= VKI_PAGE_SIZE;
532          anon_start -= VKI_PAGE_SIZE;
533          anon_size += VKI_PAGE_SIZE;
534       }
535 
536       vg_assert(VG_IS_PAGE_ALIGNED(anon_size));
537       vg_assert(VG_IS_PAGE_ALIGNED(resvn_size));
538       vg_assert(VG_IS_PAGE_ALIGNED(anon_start));
539       vg_assert(VG_IS_PAGE_ALIGNED(resvn_start));
540       vg_assert(resvn_start == clstack_end + 1 - clstack_max_size);
541 
542 #     ifdef ENABLE_INNER
543       /* Create 1M non-fault-extending stack. */
544       inner_HACK = 1024 * 1024;
545 #     endif
546 
547       if (0)
548          VG_(printf)("resvn_start=%#lx, resvn_size=%#lx\n"
549                      "anon_start=%#lx, anon_size=%#lx\n",
550                      resvn_start, resvn_size, anon_start, anon_size);
551 
552       /* Create a shrinkable reservation followed by an anonymous segment.
553          Together these constitute a growdown stack. */
554       ok = VG_(am_create_reservation)(resvn_start,
555                                       resvn_size - inner_HACK,
556                                       SmUpper,
557                                       anon_size + inner_HACK);
558       if (ok) {
559          /* Allocate a stack - mmap enough space for the stack. */
560          res = VG_(am_mmap_anon_fixed_client)(anon_start - inner_HACK,
561                                               anon_size + inner_HACK,
562                                               info->stack_prot);
563       }
564       if (!ok || sr_isError(res)) {
565          /* Allocation of the stack failed.  We have to stop. */
566          VG_(printf)("valgrind: "
567                      "I failed to allocate space for the application's stack.\n");
568          VG_(printf)("valgrind: "
569                      "This may be the result of a very large --main-stacksize=\n");
570          VG_(printf)("valgrind: setting.  Cannot continue.  Sorry.\n\n");
571          VG_(exit)(1);
572          /*NOTREACHED*/
573       }
574    }
575 
576    /* ==================== create client stack ==================== */
577 
578    ptr = (Addr*)client_SP;
579 
580    /* Copy-out client argc. */
581    *ptr++ = argc;
582 
583    /* Copy-out client argv. */
584    if (info->interp_name)
585       *ptr++ = (Addr)copy_str(&strtab, info->interp_name);
586    if (info->interp_args)
587       *ptr++ = (Addr)copy_str(&strtab, info->interp_args);
588 
589    *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename));
590    for (i = 0; i < VG_(sizeXA)(VG_(args_for_client)); i++)
591       *ptr++ = (Addr)copy_str(
592                   &strtab, *(HChar**) VG_(indexXA)(VG_(args_for_client), i));
593    *ptr++ = 0;
594 
595    /* Copy-out envp. */
596    VG_(client_envp) = (HChar**)ptr;
597    for (cpp = orig_envp; *cpp; ptr++, cpp++)
598       *ptr = (Addr)copy_str(&strtab, *cpp);
599    *ptr++ = 0;
600 
601    /* Create aux vector. */
602    auxv = (auxv_t*)ptr;
603    VG_(client_auxv) = (UWord*)ptr;
604 
605    /* AT_SUN_PLATFORM */
606    auxv->a_type = VKI_AT_SUN_PLATFORM;
607 #  if defined(VGA_x86) || defined(VGA_amd64)
608    auxv->a_un.a_ptr = copy_str(&strtab, "i86pc");
609 #  else
610 #    error "Unknown architecture"
611 #  endif
612    auxv++;
613 
614    /* AT_SUN_EXECNAME */
615    auxv->a_type = VKI_AT_SUN_EXECNAME;
616    auxv->a_un.a_ptr = copy_str(&strtab, resolved_exe_name);
617    auxv++;
618 
619    /* AT_PHDR */
620    if ((info->real_phdr_present) && (info->phdr != 0)) {
621       auxv->a_type = VKI_AT_PHDR;
622       auxv->a_un.a_val = info->phdr;
623       auxv++;
624    }
625 
626    /* AT_BASE */
627    auxv->a_type = VKI_AT_BASE;
628    auxv->a_un.a_val = info->interp_offset;
629    auxv++;
630 
631    /* AT_ENTRY */
632    auxv->a_type = VKI_AT_ENTRY;
633    auxv->a_un.a_val = info->entry;
634    auxv++;
635 
636    /* AT_FLAGS */
637    auxv->a_type = VKI_AT_FLAGS;
638 #  if defined(VGA_x86) || defined(VGA_amd64)
639    auxv->a_un.a_val = 0; /* 0 on i86pc */
640 #  else
641 #    error "Unknown architecture"
642 #  endif
643    auxv++;
644 
645    /* AT_PAGESZ */
646    auxv->a_type = VKI_AT_PAGESZ;
647    auxv->a_un.a_val = VKI_PAGE_SIZE;
648    auxv++;
649 
650    /* AT_SUN_AUXFLAFGS */
651    auxv->a_type = VKI_AT_SUN_AUXFLAGS;
652    /* XXX Handle AF_SUN_SETUGID? */
653    auxv->a_un.a_val = VKI_AF_SUN_HWCAPVERIFY;
654    auxv++;
655 
656    /* AT_SUN_HWCAP */
657    {
658       VexArch vex_arch;
659       VexArchInfo vex_archinfo;
660       UInt hwcaps;
661 
662       VG_(machine_get_VexArchInfo)(&vex_arch, &vex_archinfo);
663 
664 #     if defined(VGA_x86)
665       vg_assert(vex_arch == VexArchX86);
666 
667       /* Set default hwcaps. */
668       hwcaps =
669            VKI_AV_386_FPU       /* x87-style floating point */
670          | VKI_AV_386_TSC       /* rdtsc insn */
671          | VKI_AV_386_CX8       /* cmpxchg8b insn */
672          | VKI_AV_386_SEP       /* sysenter and sysexit */
673          | VKI_AV_386_AMD_SYSC  /* AMD's syscall and sysret */
674          | VKI_AV_386_CMOV      /* conditional move insns */
675          | VKI_AV_386_MMX       /* MMX insn */
676          | VKI_AV_386_AHF;      /* lahf/sahf insns */
677 
678       /* Handle additional hwcaps. */
679       if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE1)
680          hwcaps |=
681               VKI_AV_386_FXSR   /* fxsave and fxrstor */
682             | VKI_AV_386_SSE;   /* SSE insns and regs  */
683       if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE2) {
684          vg_assert(vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE1);
685          hwcaps |=
686               VKI_AV_386_SSE2;  /* SSE2 insns and regs */
687       }
688       if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE3) {
689          vg_assert(vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE2);
690          hwcaps |=
691               VKI_AV_386_SSE3   /* SSE3 insns and regs */
692             | VKI_AV_386_SSSE3; /* Intel SSSE3 insns */
693       }
694       if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_LZCNT)
695          hwcaps |=
696               VKI_AV_386_AMD_LZCNT; /* AMD's LZCNT insn */
697 
698       /* No support for:
699          AV_386_AMD_MMX         AMD's MMX insns
700          AV_386_AMD_3DNow       AMD's 3Dnow! insns
701          AV_386_AMD_3DNowx      AMD's 3Dnow! extended insns
702          AV_386_CX16            cmpxchg16b insn
703          AV_386_TSCP            rdtscp instruction
704          AV_386_AMD_SSE4A       AMD's SSE4A insns
705          AV_386_POPCNT          POPCNT insn
706          AV_386_SSE4_1          Intel SSE4.1 insns
707          AV_386_SSE4_2          Intel SSE4.2 insns
708          AV_386_MOVBE           Intel MOVBE insns
709          AV_386_AES             Intel AES insns
710          AV_386_PCLMULQDQ       Intel PCLMULQDQ insn
711          AV_386_XSAVE           Intel XSAVE/XRSTOR insns
712          AV_386_AVX             Intel AVX insns
713          illumos only:
714             AV_386_VMX          Intel VMX support
715             AV_386_AMD_SVM      AMD SVM support
716          solaris only:
717             AV_386_AMD_XOP      AMD XOP insns
718             AV_386_AMD_FMA4     AMD FMA4 insns */
719 
720 #     elif defined(VGA_amd64)
721       vg_assert(vex_arch == VexArchAMD64);
722 
723       /* Set default hwcaps. */
724       hwcaps =
725            VKI_AV_386_FPU       /* x87-style floating point */
726          | VKI_AV_386_TSC       /* rdtsc insn */
727          | VKI_AV_386_CX8       /* cmpxchg8b insn */
728          | VKI_AV_386_AMD_SYSC  /* AMD's syscall and sysret */
729          | VKI_AV_386_CMOV      /* conditional move insns */
730          | VKI_AV_386_MMX       /* MMX insn */
731          | VKI_AV_386_AHF       /* lahf/sahf insns */
732          | VKI_AV_386_FXSR      /* fxsave and fxrstor */
733          | VKI_AV_386_SSE       /* SSE insns and regs  */
734          | VKI_AV_386_SSE2;     /* SSE2 insns and regs */
735 
736       /* Handle additional hwcaps. */
737       if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3)
738          hwcaps |=
739               VKI_AV_386_SSE3   /* SSE3 insns and regs */
740             | VKI_AV_386_SSSE3; /* Intel SSSE3 insns */
741       if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16)
742          hwcaps |=
743               VKI_AV_386_CX16;  /* cmpxchg16b insn */
744       if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_LZCNT)
745          hwcaps |=
746               VKI_AV_386_AMD_LZCNT; /* AMD's LZCNT insn */
747       if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_RDTSCP)
748          hwcaps |=
749               VKI_AV_386_TSCP;  /* rdtscp instruction */
750       if ((vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3) &&
751           (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16)) {
752          /* The CPUID simulation provided by VEX claims to have POPCNT, AES
753             and SSE4 (SSE4.1/SSE4.2) in the SSE3+CX16 configuration. */
754          hwcaps |=
755               VKI_AV_386_POPCNT /* POPCNT insn */
756             | VKI_AV_386_AES    /* Intel AES insns */
757             | VKI_AV_386_SSE4_1 /* Intel SSE4.1 insns */
758             | VKI_AV_386_SSE4_2; /* Intel SSE4.2 insns */
759       }
760       if ((vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3) &&
761           (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16) &&
762           (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_AVX)) {
763          /* The CPUID simulation provided by VEX claims to have PCLMULQDQ and
764             XSAVE in the SSE3+CX16+AVX configuration. */
765          hwcaps |=
766               VKI_AV_386_PCLMULQDQ /* Intel PCLMULQDQ insn */
767             | VKI_AV_386_XSAVE; /* Intel XSAVE/XRSTOR insns */
768       }
769       /* No support for:
770          AV_386_SEP             sysenter and sysexit
771          AV_386_AMD_MMX         AMD's MMX insns
772          AV_386_AMD_3DNow       AMD's 3Dnow! insns
773          AV_386_AMD_3DNowx      AMD's 3Dnow! extended insns
774          AV_386_AMD_SSE4A       AMD's SSE4A insns
775          AV_386_MOVBE           Intel MOVBE insns
776          AV_386_AVX             Intel AVX insns
777          illumos only:
778             AV_386_VMX          Intel VMX support
779             AV_386_AMD_SVM      AMD SVM support
780          solaris only:
781             AV_386_AMD_XOP      AMD XOP insns
782             AV_386_AMD_FMA4     AMD FMA4 insns
783 
784          TODO VEX supports AVX, BMI and AVX2. Investigate if they can be
785          enabled on Solaris/illumos.
786        */
787 
788 #     else
789 #       error "Unknown architecture"
790 #     endif
791 
792       auxv->a_type = VKI_AT_SUN_HWCAP;
793       auxv->a_un.a_val = hwcaps;
794       auxv++;
795    }
796 
797    /* AT_SUN_HWCAP2 */
798    {
799       /* No support for:
800          illumos only:
801             AV_386_2_F16C       F16C half percision extensions
802             AV_386_2_RDRAND     RDRAND insn
803          solaris only:
804             AV2_386_RDRAND      Intel RDRAND insns
805             AV2_386_FMA         Intel FMA insn
806             AV2_386_F16C        IEEE half precn(float) insn
807             AV2_386_AMD_TBM     AMD TBM insn
808             AV2_386_BMI1        Intel BMI1 insn
809             AV2_386_FSGSBASE    Intel RD/WR FS/GSBASE insn
810             AV2_386_AVX2        Intel AVX2 insns
811             AV2_386_BMI2        Intel BMI2 insns
812             AV2_386_HLE         Intel HLE insns
813             AV2_386_RTM         Intel RTM insns
814             AV2_386_EFS         Intel Enhanced Fast String
815             AV2_386_RDSEED      Intel RDSEED insn
816             AV2_386_ADX         Intel ADX insns
817             AV2_386_PRFCHW      Intel PREFETCHW hint
818        */
819    }
820 
821 #  if defined(SOLARIS_RESERVE_SYSSTAT_ADDR)
822    /* AT_SUN_SYSSTAT_ADDR */
823    copy_auxv_entry(orig_auxv, VKI_AT_SUN_SYSSTAT_ADDR,
824                    "AT_SUN_SYSSTAT_ADDR", auxv);
825    VG_(change_mapping_ownership)(auxv->a_un.a_val, True);
826    auxv++;
827 #  endif
828 
829 #  if defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR)
830    /* AT_SUN_SYSSTAT_ZONE_ADDR */
831    copy_auxv_entry(orig_auxv, VKI_AT_SUN_SYSSTAT_ZONE_ADDR,
832                    "AT_SUN_SYSSTAT_ZONE_ADDR", auxv);
833    VG_(change_mapping_ownership)(auxv->a_un.a_val, True);
834    auxv++;
835 #  endif
836 
837    /* AT_NULL */
838    auxv->a_type = VKI_AT_NULL;
839    auxv->a_un.a_val = 0;
840 
841    vg_assert(strtab - stringbase == stringsize);
842 
843    /* The variable client_SP is now pointing at client's argc/argv. */
844 
845    if (0)
846       VG_(printf)("startup SP = %#lx\n", client_SP);
847    return client_SP;
848 }
849 
850 /*====================================================================*/
851 /*=== TOP-LEVEL: VG_(setup_client_initial_image)                   ===*/
852 /*====================================================================*/
853 
854 /* Create the client's initial memory image. */
VG_(ii_create_image)855 IIFinaliseImageInfo VG_(ii_create_image)(IICreateImageInfo iicii,
856                                          const VexArchInfo *vex_archinfo)
857 {
858    ExeInfo info;
859    HChar **env = NULL;
860    HChar resolved_exe_name[VKI_PATH_MAX];
861 
862    IIFinaliseImageInfo iifii;
863    VG_(memset)(&iifii, 0, sizeof(iifii));
864 
865    //--------------------------------------------------------------
866    // Load client executable, finding in $PATH if necessary
867    //   p: early_process_cmd_line_options()  [for 'exec', 'need_help']
868    //   p: layout_remaining_space            [so there's space]
869    //--------------------------------------------------------------
870    VG_(debugLog)(1, "initimg", "Loading client\n");
871 
872    if (!VG_(args_the_exename)) {
873       VG_(err_missing_prog)();
874       /*NOTREACHED*/
875    }
876 
877    load_client(&info, resolved_exe_name, sizeof(resolved_exe_name));
878    iifii.initial_client_IP = info.init_ip;
879    /* Note: TOC isn't available on Solaris. */
880    iifii.initial_client_TOC = info.init_toc;
881    iifii.initial_client_TP = info.init_thrptr;
882    /* Note that iifii.client_auxv is never set on Solaris, because it isn't
883       necessary to have this value in VG_(ii_finalise_image). */
884 
885    //--------------------------------------------------------------
886    // Set up client's environment
887    //   p: set-libdir                       [for VG_(libdir)]
888    //   p: early_process_cmd_line_options() [for toolname]
889    //--------------------------------------------------------------
890    VG_(debugLog)(1, "initimg", "Setup client env\n");
891    env = setup_client_env(iicii.envp, iicii.toolname);
892 
893    //--------------------------------------------------------------
894    // Setup client stack and EIP
895    //   p: load_client()     [for 'info']
896    //   p: fix_environment() [for 'env']
897    //--------------------------------------------------------------
898    {
899       /* When allocating space for the client stack, take notice of the
900          --main-stacksize value.  This makes it possible to run programs with
901          very large (primary) stack requirements simply by specifying
902          --main-stacksize. */
903       /* Logic is as follows:
904          - By default, use the client's current stack rlimit.
905          - If that exceeds 16M, clamp to 16M.
906          - If a larger --main-stacksize value is specified, use that instead.
907          - In all situations, the minimum allowed stack size is 1M.
908       */
909       Addr init_sp = (Addr) (iicii.argv - 1);
910       SizeT m1  = 1024 * 1024;
911       SizeT m16 = 16 * m1;
912       SizeT szB = (SizeT)VG_(client_rlimit_stack).rlim_cur;
913       if (szB < m1)
914          szB = m1;
915       if (szB > m16)
916          szB = m16;
917 
918       if (VG_(clo_main_stacksize) > 0)
919          szB = VG_(clo_main_stacksize);
920       if (szB < m1)
921          szB = m1;
922 
923       szB = VG_PGROUNDUP(szB);
924       VG_(debugLog)(1, "initimg",
925                        "Setup client stack: size will be %ld\n", szB);
926 
927       iifii.clstack_max_size = szB;
928       iifii.initial_client_SP = setup_client_stack(init_sp, env, &info,
929                                                    iicii.clstack_end,
930                                                    iifii.clstack_max_size,
931                                                    resolved_exe_name);
932       VG_(free)(env);
933 
934       VG_(debugLog)(2, "initimg", "Client info: "
935                        "initial_IP=%#lx, initial_TOC=%#lx, brk_base=%#lx\n",
936                        iifii.initial_client_IP, iifii.initial_client_TOC,
937                        VG_(brk_base));
938       VG_(debugLog)(2, "initimg", "Client info: "
939                        "initial_SP=%#lx, max_stack_size=%lu\n",
940                        iifii.initial_client_SP,
941                        iifii.clstack_max_size);
942    }
943 
944    if (info.ldsoexec) {
945       /* We are executing the runtime linker itself.
946          Initial data (brk) segment is setup on demand, after the target dynamic
947          executable has been loaded or when a first brk() syscall is made.
948          It cannot be established now because it would conflict with a temporary
949          stack which ld.so.1 (when executed directly) uses for loading the
950          target dynamic executable. See PRE(sys_brk) in syswrap-solaris.c. */
951    } else {
952       if (!VG_(setup_client_dataseg)()) {
953          VG_(printf)("valgrind: cannot initialize data segment (brk).\n");
954          VG_(exit)(1);
955       }
956    }
957 
958    VG_(free)(info.interp_name);
959    VG_(free)(info.interp_args);
960    return iifii;
961 }
962 
963 
964 /*====================================================================*/
965 /*=== TOP-LEVEL: VG_(finalise_image)                               ===*/
966 /*====================================================================*/
967 
968 /* Just before starting the client, we may need to make final adjustments to
969    its initial image.  Also we need to set up the VEX guest state for thread 1
970    (the root thread) and copy in essential starting values.  This is handed
971    the IIFinaliseImageInfo created by VG_(ii_create_image).
972 */
VG_(ii_finalise_image)973 void VG_(ii_finalise_image)(IIFinaliseImageInfo iifii)
974 {
975    ThreadArchState *arch = &VG_(threads)[1].arch;
976 
977 #  if defined(VGA_x86)
978    vg_assert(0 == sizeof(VexGuestX86State) % LibVEX_GUEST_STATE_ALIGN);
979 
980    /* Zero out the initial state, and set up the simulated FPU in a sane
981       way. */
982    LibVEX_GuestX86_initialise(&arch->vex);
983 
984    /* Zero out the shadow areas. */
985    VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State));
986    VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State));
987 
988    /* Put essential stuff into the new state. */
989    arch->vex.guest_ESP = iifii.initial_client_SP;
990    arch->vex.guest_EIP = iifii.initial_client_IP;
991    LibVEX_GuestX86_put_eflags(VKI_PSL_USER, &arch->vex);
992 
993    /* Set %cs, %ds, %ss and %es to default values. */
994    __asm__ __volatile__ ("movw %%cs, %[cs]" : [cs] "=m" (arch->vex.guest_CS));
995    __asm__ __volatile__ ("movw %%ds, %[ds]" : [ds] "=m" (arch->vex.guest_DS));
996    __asm__ __volatile__ ("movw %%ss, %[ss]" : [ss] "=m" (arch->vex.guest_SS));
997    __asm__ __volatile__ ("movw %%es, %[es]" : [es] "=m" (arch->vex.guest_ES));
998 
999    {
1000       /* Initial thread pointer value will be saved in GDT when the thread is
1001          started in the syswrap module and a thread's GDT is allocated. */
1002       ThreadOSstate *os = &VG_(threads)[1].os_state;
1003       os->thrptr = iifii.initial_client_TP;
1004    }
1005 
1006 #  elif defined(VGA_amd64)
1007    vg_assert(0 == sizeof(VexGuestAMD64State) % LibVEX_GUEST_STATE_ALIGN);
1008 
1009    /* Zero out the initial state, and set up the simulated FPU in a sane
1010       way. */
1011    LibVEX_GuestAMD64_initialise(&arch->vex);
1012 
1013    /* Zero out the shadow areas. */
1014    VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestAMD64State));
1015    VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State));
1016 
1017    /* Put essential stuff into the new state. */
1018    arch->vex.guest_RSP = iifii.initial_client_SP;
1019    arch->vex.guest_RIP = iifii.initial_client_IP;
1020    arch->vex.guest_FS_CONST = iifii.initial_client_TP;
1021    LibVEX_GuestAMD64_put_rflags(VKI_PSL_USER, &arch->vex);
1022 
1023 #  else
1024 #    error "Unknown platform"
1025 #  endif
1026 
1027    /* Tell the tool that we just wrote to the registers. */
1028    VG_TRACK(post_reg_write, Vg_CoreStartup, 1/*tid*/, 0/*offset*/,
1029             sizeof(VexGuestArchState));
1030 
1031    if (VG_(brk_base) != -1 ) {
1032       /* Make inaccessible/unaddressable the end of the client data segment.
1033          See PRE(sys_brk) in syswrap-solaris.c for details. */
1034       VG_(track_client_dataseg)(1 /* tid */);
1035    }
1036 }
1037 
1038 #endif // defined(VGO_solaris)
1039 
1040 /*--------------------------------------------------------------------*/
1041 /*---                                                              ---*/
1042 /*--------------------------------------------------------------------*/
1043