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-2015 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-2015, 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). */
65static 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*/
135static 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. */
264static 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. */
286static 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
314static 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
375static 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_FLAGS
446      AT_PAGESZ
447      AT_SUN_AUXFLAFGS
448      AT_SUN_HWCAP
449      AT_SUN_SYSSTAT_ADDR      (if supported)
450      AT_SUN_SYSSTAT_ZONE_ADDR (if supported)
451      AT_NULL
452
453      It would be possible to also add AT_PHENT, AT_PHNUM, AT_ENTRY,
454      AT_SUN_LDDATA, but they don't seem to be so important. */
455   auxsize = 9 * sizeof(*auxv);
456#  if defined(SOLARIS_RESERVE_SYSSTAT_ADDR)
457   auxsize += sizeof(*auxv);
458#  endif
459#  if defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR)
460   auxsize += sizeof(*auxv);
461#  endif
462
463#  if defined(VGA_x86) || defined(VGA_amd64)
464   /* AT_SUN_PLATFORM string. */
465   stringsize += VG_(strlen)("i86pc") + 1;
466#  else
467#    error "Unknown architecture"
468#  endif
469   /* AT_SUN_EXECNAME string. */
470   stringsize += VG_(strlen)(resolved_exe_name) + 1;
471
472   /* Calculate how big the client stack is. */
473   stacksize =
474      sizeof(Word) +                            /* argc */
475      sizeof(HChar**) +                         /* argc[0] == exename */
476      sizeof(HChar**) * argc +                  /* argv */
477      sizeof(HChar**) +                         /* terminal NULL */
478      sizeof(HChar**) * envc +                  /* envp */
479      sizeof(HChar**) +                         /* terminal NULL */
480      auxsize +                                 /* auxv */
481      VG_ROUNDUP(stringsize, sizeof(Word));     /* strings (aligned) */
482
483   /* The variable client_SP is the client's stack pointer. */
484   client_SP = clstack_end - stacksize;
485   client_SP = VG_ROUNDDN(client_SP, 16); /* Make stack 16 byte aligned. */
486
487   /* Calculate base of the string table (aligned). */
488   stringbase = (HChar*)clstack_end - VG_ROUNDUP(stringsize, sizeof(Int));
489   strtab = stringbase;
490
491   clstack_start = VG_PGROUNDDN(client_SP);
492
493   /* Calculate the max stack size. */
494   clstack_max_size = VG_PGROUNDUP(clstack_max_size);
495
496   /* Record stack extent -- needed for stack-change code. */
497   VG_(clstk_start_base) = clstack_start;
498   VG_(clstk_end) = clstack_end;
499   VG_(clstk_max_size) = clstack_max_size;
500
501   if (0)
502      VG_(printf)("stringsize=%lu, auxsize=%lu, stacksize=%lu, maxsize=%#lx\n"
503                  "clstack_start %#lx\n"
504                  "clstack_end   %#lx\n",
505                  stringsize, auxsize, stacksize, clstack_max_size,
506                  clstack_start, clstack_end);
507
508   /* ==================== allocate space ==================== */
509
510   {
511      SizeT anon_size = clstack_end - clstack_start + 1;
512      SizeT resvn_size = clstack_max_size - anon_size;
513      Addr anon_start = clstack_start;
514      Addr resvn_start = anon_start - resvn_size;
515      SizeT inner_HACK = 0;
516      Bool ok;
517
518      /* So far we've only accounted for space requirements down to the stack
519         pointer.  If this target's ABI requires a redzone below the stack
520         pointer, we need to allocate an extra page, to handle the worst case
521         in which the stack pointer is almost at the bottom of a page, and so
522         there is insufficient room left over to put the redzone in.  In this
523         case the simple thing to do is allocate an extra page, by shrinking
524         the reservation by one page and growing the anonymous area by a
525         corresponding page. */
526      vg_assert(VG_STACK_REDZONE_SZB >= 0);
527      vg_assert(VG_STACK_REDZONE_SZB < VKI_PAGE_SIZE);
528      if (VG_STACK_REDZONE_SZB > 0) {
529         vg_assert(resvn_size > VKI_PAGE_SIZE);
530         resvn_size -= VKI_PAGE_SIZE;
531         anon_start -= VKI_PAGE_SIZE;
532         anon_size += VKI_PAGE_SIZE;
533      }
534
535      vg_assert(VG_IS_PAGE_ALIGNED(anon_size));
536      vg_assert(VG_IS_PAGE_ALIGNED(resvn_size));
537      vg_assert(VG_IS_PAGE_ALIGNED(anon_start));
538      vg_assert(VG_IS_PAGE_ALIGNED(resvn_start));
539      vg_assert(resvn_start == clstack_end + 1 - clstack_max_size);
540
541#     ifdef ENABLE_INNER
542      /* Create 1M non-fault-extending stack. */
543      inner_HACK = 1024 * 1024;
544#     endif
545
546      if (0)
547         VG_(printf)("resvn_start=%#lx, resvn_size=%#lx\n"
548                     "anon_start=%#lx, anon_size=%#lx\n",
549                     resvn_start, resvn_size, anon_start, anon_size);
550
551      /* Create a shrinkable reservation followed by an anonymous segment.
552         Together these constitute a growdown stack. */
553      ok = VG_(am_create_reservation)(resvn_start,
554                                      resvn_size - inner_HACK,
555                                      SmUpper,
556                                      anon_size + inner_HACK);
557      if (ok) {
558         /* Allocate a stack - mmap enough space for the stack. */
559         res = VG_(am_mmap_anon_fixed_client)(anon_start - inner_HACK,
560                                              anon_size + inner_HACK,
561                                              info->stack_prot);
562      }
563      if (!ok || sr_isError(res)) {
564         /* Allocation of the stack failed.  We have to stop. */
565         VG_(printf)("valgrind: "
566                     "I failed to allocate space for the application's stack.\n");
567         VG_(printf)("valgrind: "
568                     "This may be the result of a very large --main-stacksize=\n");
569         VG_(printf)("valgrind: setting.  Cannot continue.  Sorry.\n\n");
570         VG_(exit)(1);
571         /*NOTREACHED*/
572      }
573   }
574
575   /* ==================== create client stack ==================== */
576
577   ptr = (Addr*)client_SP;
578
579   /* Copy-out client argc. */
580   *ptr++ = argc;
581
582   /* Copy-out client argv. */
583   if (info->interp_name) {
584      *ptr++ = (Addr)copy_str(&strtab, info->interp_name);
585      VG_(free)(info->interp_name);
586   }
587   if (info->interp_args) {
588      *ptr++ = (Addr)copy_str(&strtab, info->interp_args);
589      VG_(free)(info->interp_args);
590   }
591
592   *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename));
593   for (i = 0; i < VG_(sizeXA)(VG_(args_for_client)); i++)
594      *ptr++ = (Addr)copy_str(
595                  &strtab, *(HChar**) VG_(indexXA)(VG_(args_for_client), i));
596   *ptr++ = 0;
597
598   /* Copy-out envp. */
599   VG_(client_envp) = (HChar**)ptr;
600   for (cpp = orig_envp; *cpp; ptr++, cpp++)
601      *ptr = (Addr)copy_str(&strtab, *cpp);
602   *ptr++ = 0;
603
604   /* Create aux vector. */
605   auxv = (auxv_t*)ptr;
606   VG_(client_auxv) = (UWord*)ptr;
607
608   /* AT_SUN_PLATFORM */
609   auxv->a_type = VKI_AT_SUN_PLATFORM;
610#  if defined(VGA_x86) || defined(VGA_amd64)
611   auxv->a_un.a_ptr = copy_str(&strtab, "i86pc");
612#  else
613#    error "Unknown architecture"
614#  endif
615   auxv++;
616
617   /* AT_SUN_EXECNAME */
618   auxv->a_type = VKI_AT_SUN_EXECNAME;
619   auxv->a_un.a_ptr = copy_str(&strtab, resolved_exe_name);
620   auxv++;
621
622   /* AT_PHDR */
623   if ((info->real_phdr_present) && (info->phdr != 0)) {
624      auxv->a_type = VKI_AT_PHDR;
625      auxv->a_un.a_val = info->phdr;
626      auxv++;
627   }
628
629   /* AT_BASE */
630   auxv->a_type = VKI_AT_BASE;
631   auxv->a_un.a_val = info->interp_offset;
632   auxv++;
633
634   /* AT_FLAGS */
635   auxv->a_type = VKI_AT_FLAGS;
636#  if defined(VGA_x86) || defined(VGA_amd64)
637   auxv->a_un.a_val = 0; /* 0 on i86pc */
638#  else
639#    error "Unknown architecture"
640#  endif
641   auxv++;
642
643   /* AT_PAGESZ */
644   auxv->a_type = VKI_AT_PAGESZ;
645   auxv->a_un.a_val = VKI_PAGE_SIZE;
646   auxv++;
647
648   /* AT_SUN_AUXFLAFGS */
649   auxv->a_type = VKI_AT_SUN_AUXFLAGS;
650   /* XXX Handle AF_SUN_SETUGID? */
651   auxv->a_un.a_val = VKI_AF_SUN_HWCAPVERIFY;
652   auxv++;
653
654   /* AT_SUN_HWCAP */
655   {
656      VexArch vex_arch;
657      VexArchInfo vex_archinfo;
658      UInt hwcaps;
659
660      VG_(machine_get_VexArchInfo)(&vex_arch, &vex_archinfo);
661
662#     if defined(VGA_x86)
663      vg_assert(vex_arch == VexArchX86);
664
665      /* Set default hwcaps. */
666      hwcaps =
667           VKI_AV_386_FPU       /* x87-style floating point */
668         | VKI_AV_386_TSC       /* rdtsc insn */
669         | VKI_AV_386_CX8       /* cmpxchg8b insn */
670         | VKI_AV_386_SEP       /* sysenter and sysexit */
671         | VKI_AV_386_AMD_SYSC  /* AMD's syscall and sysret */
672         | VKI_AV_386_CMOV      /* conditional move insns */
673         | VKI_AV_386_MMX       /* MMX insn */
674         | VKI_AV_386_AHF;      /* lahf/sahf insns */
675
676      /* Handle additional hwcaps. */
677      if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE1)
678         hwcaps |=
679              VKI_AV_386_FXSR   /* fxsave and fxrstor */
680            | VKI_AV_386_SSE;   /* SSE insns and regs  */
681      if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE2) {
682         vg_assert(vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE1);
683         hwcaps |=
684              VKI_AV_386_SSE2;  /* SSE2 insns and regs */
685      }
686      if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE3) {
687         vg_assert(vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE2);
688         hwcaps |=
689              VKI_AV_386_SSE3   /* SSE3 insns and regs */
690            | VKI_AV_386_SSSE3; /* Intel SSSE3 insns */
691      }
692      if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_LZCNT)
693         hwcaps |=
694              VKI_AV_386_AMD_LZCNT; /* AMD's LZCNT insn */
695
696      /* No support for:
697         AV_386_AMD_MMX         AMD's MMX insns
698         AV_386_AMD_3DNow       AMD's 3Dnow! insns
699         AV_386_AMD_3DNowx      AMD's 3Dnow! extended insns
700         AV_386_CX16            cmpxchg16b insn
701         AV_386_TSCP            rdtscp instruction
702         AV_386_AMD_SSE4A       AMD's SSE4A insns
703         AV_386_POPCNT          POPCNT insn
704         AV_386_SSE4_1          Intel SSE4.1 insns
705         AV_386_SSE4_2          Intel SSE4.2 insns
706         AV_386_MOVBE           Intel MOVBE insns
707         AV_386_AES             Intel AES insns
708         AV_386_PCLMULQDQ       Intel PCLMULQDQ insn
709         AV_386_XSAVE           Intel XSAVE/XRSTOR insns
710         AV_386_AVX             Intel AVX insns
711         illumos only:
712            AV_386_VMX          Intel VMX support
713            AV_386_AMD_SVM      AMD SVM support
714         solaris only:
715            AV_386_AMD_XOP      AMD XOP insns
716            AV_386_AMD_FMA4     AMD FMA4 insns */
717
718#     elif defined(VGA_amd64)
719      vg_assert(vex_arch == VexArchAMD64);
720
721      /* Set default hwcaps. */
722      hwcaps =
723           VKI_AV_386_FPU       /* x87-style floating point */
724         | VKI_AV_386_TSC       /* rdtsc insn */
725         | VKI_AV_386_CX8       /* cmpxchg8b insn */
726         | VKI_AV_386_AMD_SYSC  /* AMD's syscall and sysret */
727         | VKI_AV_386_CMOV      /* conditional move insns */
728         | VKI_AV_386_MMX       /* MMX insn */
729         | VKI_AV_386_AHF       /* lahf/sahf insns */
730         | VKI_AV_386_FXSR      /* fxsave and fxrstor */
731         | VKI_AV_386_SSE       /* SSE insns and regs  */
732         | VKI_AV_386_SSE2;     /* SSE2 insns and regs */
733
734      /* Handle additional hwcaps. */
735      if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3)
736         hwcaps |=
737              VKI_AV_386_SSE3   /* SSE3 insns and regs */
738            | VKI_AV_386_SSSE3; /* Intel SSSE3 insns */
739      if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16)
740         hwcaps |=
741              VKI_AV_386_CX16;  /* cmpxchg16b insn */
742      if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_LZCNT)
743         hwcaps |=
744              VKI_AV_386_AMD_LZCNT; /* AMD's LZCNT insn */
745      if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_RDTSCP)
746         hwcaps |=
747              VKI_AV_386_TSCP;  /* rdtscp instruction */
748      if ((vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3) &&
749          (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16)) {
750         /* The CPUID simulation provided by VEX claims to have POPCNT, AES
751            and SSE4 (SSE4.1/SSE4.2) in the SSE3+CX16 configuration. */
752         hwcaps |=
753              VKI_AV_386_POPCNT /* POPCNT insn */
754            | VKI_AV_386_AES    /* Intel AES insns */
755            | VKI_AV_386_SSE4_1 /* Intel SSE4.1 insns */
756            | VKI_AV_386_SSE4_2; /* Intel SSE4.2 insns */
757      }
758      if ((vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3) &&
759          (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16) &&
760          (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_AVX)) {
761         /* The CPUID simulation provided by VEX claims to have PCLMULQDQ and
762            XSAVE in the SSE3+CX16+AVX configuration. */
763         hwcaps |=
764              VKI_AV_386_PCLMULQDQ /* Intel PCLMULQDQ insn */
765            | VKI_AV_386_XSAVE; /* Intel XSAVE/XRSTOR insns */
766      }
767      /* No support for:
768         AV_386_SEP             sysenter and sysexit
769         AV_386_AMD_MMX         AMD's MMX insns
770         AV_386_AMD_3DNow       AMD's 3Dnow! insns
771         AV_386_AMD_3DNowx      AMD's 3Dnow! extended insns
772         AV_386_AMD_SSE4A       AMD's SSE4A insns
773         AV_386_MOVBE           Intel MOVBE insns
774         AV_386_AVX             Intel AVX insns
775         illumos only:
776            AV_386_VMX          Intel VMX support
777            AV_386_AMD_SVM      AMD SVM support
778         solaris only:
779            AV_386_AMD_XOP      AMD XOP insns
780            AV_386_AMD_FMA4     AMD FMA4 insns
781
782         TODO VEX supports AVX, BMI and AVX2. Investigate if they can be
783         enabled on Solaris/illumos.
784       */
785
786#     else
787#       error "Unknown architecture"
788#     endif
789
790      auxv->a_type = VKI_AT_SUN_HWCAP;
791      auxv->a_un.a_val = hwcaps;
792      auxv++;
793   }
794
795   /* AT_SUN_HWCAP2 */
796   {
797      /* No support for:
798         illumos only:
799            AV_386_2_F16C       F16C half percision extensions
800            AV_386_2_RDRAND     RDRAND insn
801         solaris only:
802            AV2_386_RDRAND      Intel RDRAND insns
803            AV2_386_FMA         Intel FMA insn
804            AV2_386_F16C        IEEE half precn(float) insn
805            AV2_386_AMD_TBM     AMD TBM insn
806            AV2_386_BMI1        Intel BMI1 insn
807            AV2_386_FSGSBASE    Intel RD/WR FS/GSBASE insn
808            AV2_386_AVX2        Intel AVX2 insns
809            AV2_386_BMI2        Intel BMI2 insns
810            AV2_386_HLE         Intel HLE insns
811            AV2_386_RTM         Intel RTM insns
812            AV2_386_EFS         Intel Enhanced Fast String
813            AV2_386_RDSEED      Intel RDSEED insn
814            AV2_386_ADX         Intel ADX insns
815            AV2_386_PRFCHW      Intel PREFETCHW hint
816       */
817   }
818
819#  if defined(SOLARIS_RESERVE_SYSSTAT_ADDR)
820   /* AT_SUN_SYSSTAT_ADDR */
821   copy_auxv_entry(orig_auxv, VKI_AT_SUN_SYSSTAT_ADDR,
822                   "AT_SUN_SYSSTAT_ADDR", auxv);
823   VG_(change_mapping_ownership)(auxv->a_un.a_val, True);
824   auxv++;
825#  endif
826
827#  if defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR)
828   /* AT_SUN_SYSSTAT_ZONE_ADDR */
829   copy_auxv_entry(orig_auxv, VKI_AT_SUN_SYSSTAT_ZONE_ADDR,
830                   "AT_SUN_SYSSTAT_ZONE_ADDR", auxv);
831   VG_(change_mapping_ownership)(auxv->a_un.a_val, True);
832   auxv++;
833#  endif
834
835   /* AT_NULL */
836   auxv->a_type = VKI_AT_NULL;
837   auxv->a_un.a_val = 0;
838
839   vg_assert(strtab - stringbase == stringsize);
840
841   /* The variable client_SP is now pointing at client's argc/argv. */
842
843   if (0)
844      VG_(printf)("startup SP = %#lx\n", client_SP);
845   return client_SP;
846}
847
848/*====================================================================*/
849/*=== TOP-LEVEL: VG_(setup_client_initial_image)                   ===*/
850/*====================================================================*/
851
852/* Create the client's initial memory image. */
853IIFinaliseImageInfo VG_(ii_create_image)(IICreateImageInfo iicii,
854                                         const VexArchInfo *vex_archinfo)
855{
856   ExeInfo info;
857   HChar **env = NULL;
858   HChar resolved_exe_name[VKI_PATH_MAX];
859
860   IIFinaliseImageInfo iifii;
861   VG_(memset)(&iifii, 0, sizeof(iifii));
862
863   //--------------------------------------------------------------
864   // Load client executable, finding in $PATH if necessary
865   //   p: early_process_cmd_line_options()  [for 'exec', 'need_help']
866   //   p: layout_remaining_space            [so there's space]
867   //--------------------------------------------------------------
868   VG_(debugLog)(1, "initimg", "Loading client\n");
869
870   if (!VG_(args_the_exename)) {
871      VG_(err_missing_prog)();
872      /*NOTREACHED*/
873   }
874
875   load_client(&info, resolved_exe_name, sizeof(resolved_exe_name));
876   iifii.initial_client_IP = info.init_ip;
877   /* Note: TOC isn't available on Solaris. */
878   iifii.initial_client_TOC = info.init_toc;
879   iifii.initial_client_TP = info.init_thrptr;
880   /* Note that iifii.client_auxv is never set on Solaris, because it isn't
881      necessary to have this value in VG_(ii_finalise_image). */
882
883   //--------------------------------------------------------------
884   // Set up client's environment
885   //   p: set-libdir                       [for VG_(libdir)]
886   //   p: early_process_cmd_line_options() [for toolname]
887   //--------------------------------------------------------------
888   VG_(debugLog)(1, "initimg", "Setup client env\n");
889   env = setup_client_env(iicii.envp, iicii.toolname);
890
891   //--------------------------------------------------------------
892   // Setup client stack and EIP
893   //   p: load_client()     [for 'info']
894   //   p: fix_environment() [for 'env']
895   //--------------------------------------------------------------
896   {
897      /* When allocating space for the client stack, take notice of the
898         --main-stacksize value.  This makes it possible to run programs with
899         very large (primary) stack requirements simply by specifying
900         --main-stacksize. */
901      /* Logic is as follows:
902         - By default, use the client's current stack rlimit.
903         - If that exceeds 16M, clamp to 16M.
904         - If a larger --main-stacksize value is specified, use that instead.
905         - In all situations, the minimum allowed stack size is 1M.
906      */
907      Addr init_sp = (Addr) (iicii.argv - 1);
908      SizeT m1  = 1024 * 1024;
909      SizeT m16 = 16 * m1;
910      SizeT szB = (SizeT)VG_(client_rlimit_stack).rlim_cur;
911      if (szB < m1)
912         szB = m1;
913      if (szB > m16)
914         szB = m16;
915
916      if (VG_(clo_main_stacksize) > 0)
917         szB = VG_(clo_main_stacksize);
918      if (szB < m1)
919         szB = m1;
920
921      szB = VG_PGROUNDUP(szB);
922      VG_(debugLog)(1, "initimg",
923                       "Setup client stack: size will be %ld\n", szB);
924
925      iifii.clstack_max_size = szB;
926      iifii.initial_client_SP = setup_client_stack(init_sp, env, &info,
927                                                   iicii.clstack_end,
928                                                   iifii.clstack_max_size,
929                                                   resolved_exe_name);
930      VG_(free)(env);
931
932      VG_(debugLog)(2, "initimg", "Client info: "
933                       "initial_IP=%#lx, initial_TOC=%#lx, brk_base=%#lx\n",
934                       iifii.initial_client_IP, iifii.initial_client_TOC,
935                       VG_(brk_base));
936      VG_(debugLog)(2, "initimg", "Client info: "
937                       "initial_SP=%#lx, max_stack_size=%lu\n",
938                       iifii.initial_client_SP,
939                       iifii.clstack_max_size);
940   }
941
942   if (info.ldsoexec) {
943      /* We are executing the runtime linker itself.
944         Initial data (brk) segment is setup on demand, after the target dynamic
945         executable has been loaded or when a first brk() syscall is made.
946         It cannot be established now because it would conflict with a temporary
947         stack which ld.so.1 (when executed directly) uses for loading the
948         target dynamic executable. See PRE(sys_brk) in syswrap-solaris.c. */
949   } else {
950      if (!VG_(setup_client_dataseg)()) {
951         VG_(printf)("valgrind: cannot initialize data segment (brk).\n");
952         VG_(exit)(1);
953      }
954   }
955
956   return iifii;
957}
958
959
960/*====================================================================*/
961/*=== TOP-LEVEL: VG_(finalise_image)                               ===*/
962/*====================================================================*/
963
964/* Just before starting the client, we may need to make final adjustments to
965   its initial image.  Also we need to set up the VEX guest state for thread 1
966   (the root thread) and copy in essential starting values.  This is handed
967   the IIFinaliseImageInfo created by VG_(ii_create_image).
968*/
969void VG_(ii_finalise_image)(IIFinaliseImageInfo iifii)
970{
971   ThreadArchState *arch = &VG_(threads)[1].arch;
972
973#  if defined(VGA_x86)
974   vg_assert(0 == sizeof(VexGuestX86State) % LibVEX_GUEST_STATE_ALIGN);
975
976   /* Zero out the initial state, and set up the simulated FPU in a sane
977      way. */
978   LibVEX_GuestX86_initialise(&arch->vex);
979
980   /* Zero out the shadow areas. */
981   VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State));
982   VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State));
983
984   /* Put essential stuff into the new state. */
985   arch->vex.guest_ESP = iifii.initial_client_SP;
986   arch->vex.guest_EIP = iifii.initial_client_IP;
987   LibVEX_GuestX86_put_eflags(VKI_PSL_USER, &arch->vex);
988
989   /* Set %cs, %ds, %ss and %es to default values. */
990   __asm__ __volatile__ ("movw %%cs, %[cs]" : [cs] "=m" (arch->vex.guest_CS));
991   __asm__ __volatile__ ("movw %%ds, %[ds]" : [ds] "=m" (arch->vex.guest_DS));
992   __asm__ __volatile__ ("movw %%ss, %[ss]" : [ss] "=m" (arch->vex.guest_SS));
993   __asm__ __volatile__ ("movw %%es, %[es]" : [es] "=m" (arch->vex.guest_ES));
994
995   {
996      /* Initial thread pointer value will be saved in GDT when the thread is
997         started in the syswrap module and a thread's GDT is allocated. */
998      ThreadOSstate *os = &VG_(threads)[1].os_state;
999      os->thrptr = iifii.initial_client_TP;
1000   }
1001
1002#  elif defined(VGA_amd64)
1003   vg_assert(0 == sizeof(VexGuestAMD64State) % LibVEX_GUEST_STATE_ALIGN);
1004
1005   /* Zero out the initial state, and set up the simulated FPU in a sane
1006      way. */
1007   LibVEX_GuestAMD64_initialise(&arch->vex);
1008
1009   /* Zero out the shadow areas. */
1010   VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestAMD64State));
1011   VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State));
1012
1013   /* Put essential stuff into the new state. */
1014   arch->vex.guest_RSP = iifii.initial_client_SP;
1015   arch->vex.guest_RIP = iifii.initial_client_IP;
1016   arch->vex.guest_FS_CONST = iifii.initial_client_TP;
1017   LibVEX_GuestAMD64_put_rflags(VKI_PSL_USER, &arch->vex);
1018
1019#  else
1020#    error "Unknown platform"
1021#  endif
1022
1023   /* Tell the tool that we just wrote to the registers. */
1024   VG_TRACK(post_reg_write, Vg_CoreStartup, 1/*tid*/, 0/*offset*/,
1025            sizeof(VexGuestArchState));
1026
1027   if (VG_(brk_base) != -1 ) {
1028      /* Make inaccessible/unaddressable the end of the client data segment.
1029         See PRE(sys_brk) in syswrap-solaris.c for details. */
1030      VG_(track_client_dataseg)(1 /* tid */);
1031   }
1032}
1033
1034#endif // defined(VGO_solaris)
1035
1036/*--------------------------------------------------------------------*/
1037/*---                                                              ---*/
1038/*--------------------------------------------------------------------*/
1039