
/*--------------------------------------------------------------------*/
/*--- Startup: create initial process image on Solaris             ---*/
/*---                                            initimg-solaris.c ---*/
/*--------------------------------------------------------------------*/

/*
   This file is part of Valgrind, a dynamic binary instrumentation
   framework.

   Copyright (C) 2011-2015 Petr Pavlu
      setup@dagobah.cz

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307, USA.

   The GNU General Public License is contained in the file COPYING.
*/

/* Copyright 2013-2015, Ivo Raisr <ivosh@ivosh.net>. */

#if defined(VGO_solaris)

/* Note: This file is based on initimg-linux.c. */

#include "pub_core_basics.h"
#include "pub_core_vki.h"
#include "pub_core_debuglog.h"
#include "pub_core_libcbase.h"
#include "pub_core_libcassert.h"
#include "pub_core_libcfile.h"
#include "pub_core_libcproc.h"
#include "pub_core_libcprint.h"
#include "pub_core_xarray.h"
#include "pub_core_clientstate.h"
#include "pub_core_aspacemgr.h"
#include "pub_core_mallocfree.h"
#include "pub_core_machine.h"
#include "pub_core_ume.h"
#include "pub_core_options.h"
#include "pub_core_syswrap.h"
#include "pub_core_tooliface.h"       /* VG_TRACK */
#include "pub_core_threadstate.h"     /* ThreadArchState */
#include "priv_initimg_pathscan.h"
#include "pub_core_initimg.h"         /* self */


/*====================================================================*/
/*=== Loading the client                                           ===*/
/*====================================================================*/

/* Load the client whose name is VG_(argv_the_exename). */
static void load_client(/*OUT*/ExeInfo *info,
                        /*OUT*/HChar *out_exe_name, SizeT out_exe_name_size)
{
   const HChar *exe_name;
   Int ret;
   SysRes res;

   vg_assert(VG_(args_the_exename));
   exe_name = ML_(find_executable)(VG_(args_the_exename));

   if (!exe_name) {
      VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename));
      /* Return POSIX's NOTFOUND. */
      VG_(exit)(127);
      /*NOTREACHED*/
   }

   VG_(memset)(info, 0, sizeof(*info));
   ret = VG_(do_exec)(exe_name, info);
   if (ret < 0) {
      VG_(printf)("valgrind: could not execute '%s'\n", exe_name);
      VG_(exit)(1);
      /*NOTREACHED*/
   }

   /* The client was successfully loaded!  Continue. */

   /* Save resolved exename. */
   if (VG_(strlen)(exe_name) + 1 > out_exe_name_size) {
      /* This should not really happen. */
      VG_(printf)("valgrind: execname %s is too long\n", exe_name);
      VG_(exit)(1);
      /*NOTREACHED*/
   }
   VG_(strcpy)(out_exe_name, exe_name);

   /* Get hold of a file descriptor which refers to the client executable.
      This is needed for attaching to GDB. */
   res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR);
   if (!sr_isError(res))
      VG_(cl_exec_fd) = sr_Res(res);

   /* Set initial brk values. */
   if (info->ldsoexec) {
      VG_(brk_base) = VG_(brk_limit) = -1;
   } else {
      VG_(brk_base) = VG_(brk_limit) = info->brkbase;
   }
}


/*====================================================================*/
/*=== Setting up the client's environment                          ===*/
/*====================================================================*/

/* Prepare the client's environment.  This is basically a copy of our
   environment, except:

     LD_PRELOAD=$VALGRIND_LIB/vgpreload_core-PLATFORM.so:
                ($VALGRIND_LIB/vgpreload_TOOL-PLATFORM.so:)?
                $LD_PRELOAD

   If this is missing, then it is added.

   Also, remove any binding for VALGRIND_LAUNCHER=.  The client should not be
   able to see this.

   If this needs to handle any more variables it should be hacked into
   something table driven.  The copy is VG_(malloc)'d space.
*/
static HChar **setup_client_env(HChar **origenv, const HChar *toolname)
{
   const HChar *ld_preload = "LD_PRELOAD=";
   SizeT ld_preload_len = VG_(strlen)(ld_preload);
   Bool ld_preload_done = False;
   SizeT vglib_len = VG_(strlen)(VG_(libdir));

   HChar **cpp;
   HChar **ret;
   HChar *preload_tool_path;
   SizeT envc, i;

   /* Alloc space for the
        <path>/vgpreload_core-<platform>.so and
        <path>/vgpreload_<tool>-<platform>.so
      paths.  We might not need the space for the tool path, but it doesn't
      hurt to over-allocate briefly.  */
   SizeT preload_core_path_size = vglib_len + sizeof("/vgpreload_core-") - 1
                                            + sizeof(VG_PLATFORM) - 1
                                            + sizeof(".so");
   SizeT preload_tool_path_size = vglib_len + sizeof("/vgpreload_") - 1
                                            + VG_(strlen)(toolname) + 1 /*-*/
                                            + sizeof(VG_PLATFORM) - 1
                                            + sizeof(".so");
   SizeT preload_string_size = preload_core_path_size
                               + preload_tool_path_size;
   HChar *preload_string = VG_(malloc)("initimg-solaris.sce.1",
                                       preload_string_size);

   /* Check that the parameters are sane. */
   vg_assert(origenv);
   vg_assert(toolname);

   /* Determine if there's a vgpreload_<tool>-<platform>.so file, and setup
      preload_string. */
   preload_tool_path = VG_(malloc)("initimg-solaris.sce.2",
                                   preload_tool_path_size);
   VG_(sprintf)(preload_tool_path, "%s/vgpreload_%s-%s.so", VG_(libdir),
                toolname, VG_PLATFORM);
   if (!VG_(access)(preload_tool_path, True/*r*/, False/*w*/, False/*x*/)) {
      /* The tool's .so exists, put it into LD_PRELOAD with the core's so. */
      VG_(sprintf)(preload_string, "%s/vgpreload_core-%s.so:%s", VG_(libdir),
                   VG_PLATFORM, preload_tool_path);
   }
   else {
      /* The tool's .so doesn't exist, put only the core's .so into
         LD_PRELOAD. */
      VG_(sprintf)(preload_string, "%s/vgpreload_core-%s.so", VG_(libdir),
                   VG_PLATFORM);
   }
   VG_(free)(preload_tool_path);

   VG_(debugLog)(2, "initimg", "preload_string:\n");
   VG_(debugLog)(2, "initimg", "  \"%s\"\n", preload_string);

   /* Count the original size of the env. */
   envc = 0;
   for (cpp = origenv; *cpp; cpp++)
      envc++;

   /* Allocate a new space, envc + 1 new entry + NULL. */
   ret = VG_(malloc)("initimg-solaris.sce.3", sizeof(HChar*) * (envc + 1 + 1));

   /* Copy it over. */
   for (cpp = ret; *origenv; )
      *cpp++ = *origenv++;
   *cpp = NULL;

   vg_assert(envc == cpp - ret);

   /* Walk over the new environment, mashing as we go. */
   for (cpp = ret; *cpp; cpp++) {
      if (VG_(memcmp)(*cpp, ld_preload, ld_preload_len))
         continue;

      /* LD_PRELOAD entry found, smash it. */
      SizeT size = VG_(strlen)(*cpp) + 1 /*:*/
                                     + preload_string_size;
      HChar *cp = VG_(malloc)("initimg-solaris.sce.4", size);

      VG_(sprintf)(cp, "%s%s:%s", ld_preload, preload_string,
                   (*cpp) + ld_preload_len);
      *cpp = cp;

      ld_preload_done = True;
   }

   /* Add the missing bits. */
   if (!ld_preload_done) {
      SizeT size = ld_preload_len + preload_string_size;
      HChar *cp = VG_(malloc)("initimg-solaris.sce.5", size);

      VG_(sprintf)(cp, "%s%s", ld_preload, preload_string);
      ret[envc++] = cp;
   }

   /* We've got ret[0 .. envc-1] live now. */

   /* Find and remove a binding for VALGRIND_LAUNCHER. */
   {
      const HChar *v_launcher = VALGRIND_LAUNCHER "=";
      SizeT v_launcher_len = VG_(strlen)(v_launcher);

      for (i = 0; i < envc; i++)
         if (!VG_(memcmp(ret[i], v_launcher, v_launcher_len))) {
            /* VALGRIND_LAUNCHER was found. */
            break;
         }

      if (i < envc) {
         /* VALGRIND_LAUNCHER was found, remove it. */
         for (; i < envc - 1; i++)
            ret[i] = ret[i + 1];
         envc--;
      }
   }

   VG_(free)(preload_string);
   ret[envc] = NULL;

   return ret;
}


/*====================================================================*/
/*=== Setting up the client's stack                                ===*/
/*====================================================================*/

/* Add a string onto the string table, and return its address. */
static HChar *copy_str(HChar **tab, const HChar *str)
{
   HChar *cp = *tab;
   HChar *orig = cp;

   while (*str)
      *cp++ = *str++;
   *cp++ = '\0';

   *tab = cp;

   return orig;
}

#if defined(SOLARIS_RESERVE_SYSSTAT_ADDR) || \
    defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR)
#define ORIG_AUXV_PRESENT 1
#endif

#if defined(ORIG_AUXV_PRESENT)
/* The auxiliary vector might not be present. So we cross-check pointers from
   argv and envp pointing to the string table. */ 
static vki_auxv_t *find_original_auxv(Addr init_sp)
{
   HChar **sp = (HChar **) init_sp;
   HChar *lowest_str_ptr = (HChar *) UINTPTR_MAX; // lowest ptr to string table

   sp++; // skip argc

   while (*sp != NULL) { // skip argv
      if (*sp < lowest_str_ptr)
         lowest_str_ptr = *sp;
      sp++;
   }
   sp++;

   while (*sp != 0) { // skip env
      if (*sp < lowest_str_ptr)
         lowest_str_ptr = *sp;
      sp++;
   }
   sp++;

   if ((Addr) sp < (Addr) lowest_str_ptr) {
      return (vki_auxv_t *) sp;
   } else {
      return NULL;
   }
}

static void copy_auxv_entry(const vki_auxv_t *orig_auxv, Int type,
                            const HChar *type_name, vki_auxv_t *auxv)
{
   vg_assert(auxv != NULL);

   if (orig_auxv == NULL) {
      VG_(printf)("valgrind: Cannot locate auxiliary vector.\n");
      VG_(printf)("valgrind: Cannot continue. Sorry.\n\n");
      VG_(exit)(1);
   }

   for ( ; orig_auxv->a_type != VKI_AT_NULL; orig_auxv++) {
      if (orig_auxv->a_type == type) {
         auxv->a_type = type;
         auxv->a_un.a_val = orig_auxv->a_un.a_val;
         return;
      }
   }

   VG_(printf)("valgrind: Cannot locate %s in the aux\n", type_name);
   VG_(printf)("valgrind: vector. Cannot continue. Sorry.\n\n");
   VG_(exit)(1);
}
#endif /* ORIG_AUXV_PRESENT */

/* This sets up the client's initial stack, containing the args,
   environment and aux vector.

   The format of the stack is:

   higher address +-----------------+ <- clstack_end
                  |                 |
                  : string table    :
                  |                 |
                  +-----------------+
                  | AT_NULL         |
                  -                 -
                  | auxv            |
                  +-----------------+
                  | NULL            |
                  -                 -
                  | envp            |
                  +-----------------+
                  | NULL            |
                  -                 -
                  | argv            |
                  +-----------------+
                  | argc            |
   lower address  +-----------------+ <- sp
                  | undefined       |
                  :                 :

   Allocate and create the initial client stack.  It is allocated down from
   clstack_end, which was previously determined by the address space manager.
   The returned value is the SP value for the client.

   Note that auxiliary vector is *not* created by kernel on illumos and
   Solaris 11 if the program is statically linked (which is our case).
   Although we now taught Solaris 12 to create the auxiliary vector, we still
   have to build auxv from scratch, to make the code consistent. */

static Addr setup_client_stack(Addr init_sp,
                               HChar **orig_envp,
                               const ExeInfo *info,
                               Addr clstack_end,
                               SizeT clstack_max_size,
                               const HChar *resolved_exe_name)
{
   SysRes res;
   HChar **cpp;
   HChar *strtab;       /* string table */
   HChar *stringbase;
   Addr *ptr;
   vki_auxv_t *auxv;
   SizeT stringsize;    /* total size of strings in bytes */
   SizeT auxsize;       /* total size of auxv in bytes */
   Int argc;            /* total argc */
   Int envc;            /* total number of env vars */
   SizeT stacksize;     /* total client stack size */
   Addr client_SP;      /* client stack base (initial SP) */
   Addr clstack_start;
   Int i;

   vg_assert(VG_IS_PAGE_ALIGNED(clstack_end + 1));
   vg_assert(VG_(args_the_exename));
   vg_assert(VG_(args_for_client));

#  if defined(ORIG_AUXV_PRESENT)
   /* Get the original auxv (if any). */
   vki_auxv_t *orig_auxv = find_original_auxv(init_sp);
#  endif /* ORIG_AUXV_PRESENT */

   /* ==================== compute sizes ==================== */

   /* First of all, work out how big the client stack will be. */
   stringsize = 0;

   /* Paste on the extra args if the loader needs them (i.e. the #!
      interpreter and its argument). */
   argc = 0;
   if (info->interp_name) {
      argc++;
      stringsize += VG_(strlen)(info->interp_name) + 1;
   }
   if (info->interp_args) {
      argc++;
      stringsize += VG_(strlen)(info->interp_args) + 1;
   }

   /* Now scan the args we're given... */
   argc++;
   stringsize += VG_(strlen)(VG_(args_the_exename)) + 1;
   for (i = 0; i < VG_(sizeXA)(VG_(args_for_client)); i++) {
      argc++;
      stringsize += VG_(strlen)(*(HChar**)
                                  VG_(indexXA)(VG_(args_for_client), i)) + 1;
   }

   /* ...and the environment. */
   envc = 0;
   for (cpp = orig_envp; *cpp; cpp++) {
      envc++;
      stringsize += VG_(strlen)(*cpp) + 1;
   }

   /* Now, how big is the auxv?

      AT_SUN_PLATFORM
      AT_SUN_EXECNAME
      AT_PHDR            (not for elfs with no PT_PHDR, such as ld.so.1)
      AT_BASE
      AT_FLAGS
      AT_PAGESZ
      AT_SUN_AUXFLAFGS
      AT_SUN_HWCAP
      AT_SUN_SYSSTAT_ADDR      (if supported)
      AT_SUN_SYSSTAT_ZONE_ADDR (if supported)
      AT_NULL

      It would be possible to also add AT_PHENT, AT_PHNUM, AT_ENTRY,
      AT_SUN_LDDATA, but they don't seem to be so important. */
   auxsize = 9 * sizeof(*auxv);
#  if defined(SOLARIS_RESERVE_SYSSTAT_ADDR)
   auxsize += sizeof(*auxv);
#  endif
#  if defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR)
   auxsize += sizeof(*auxv);
#  endif

#  if defined(VGA_x86) || defined(VGA_amd64)
   /* AT_SUN_PLATFORM string. */
   stringsize += VG_(strlen)("i86pc") + 1;
#  else
#    error "Unknown architecture"
#  endif
   /* AT_SUN_EXECNAME string. */
   stringsize += VG_(strlen)(resolved_exe_name) + 1;

   /* Calculate how big the client stack is. */
   stacksize =
      sizeof(Word) +                            /* argc */
      sizeof(HChar**) +                         /* argc[0] == exename */
      sizeof(HChar**) * argc +                  /* argv */
      sizeof(HChar**) +                         /* terminal NULL */
      sizeof(HChar**) * envc +                  /* envp */
      sizeof(HChar**) +                         /* terminal NULL */
      auxsize +                                 /* auxv */
      VG_ROUNDUP(stringsize, sizeof(Word));     /* strings (aligned) */

   /* The variable client_SP is the client's stack pointer. */
   client_SP = clstack_end - stacksize;
   client_SP = VG_ROUNDDN(client_SP, 16); /* Make stack 16 byte aligned. */

   /* Calculate base of the string table (aligned). */
   stringbase = (HChar*)clstack_end - VG_ROUNDUP(stringsize, sizeof(Int));
   strtab = stringbase;

   clstack_start = VG_PGROUNDDN(client_SP);

   /* Calculate the max stack size. */
   clstack_max_size = VG_PGROUNDUP(clstack_max_size);

   /* Record stack extent -- needed for stack-change code. */
   VG_(clstk_start_base) = clstack_start;
   VG_(clstk_end) = clstack_end;
   VG_(clstk_max_size) = clstack_max_size;

   if (0)
      VG_(printf)("stringsize=%lu, auxsize=%lu, stacksize=%lu, maxsize=%#lx\n"
                  "clstack_start %#lx\n"
                  "clstack_end   %#lx\n",
                  stringsize, auxsize, stacksize, clstack_max_size,
                  clstack_start, clstack_end);

   /* ==================== allocate space ==================== */

   {
      SizeT anon_size = clstack_end - clstack_start + 1;
      SizeT resvn_size = clstack_max_size - anon_size;
      Addr anon_start = clstack_start;
      Addr resvn_start = anon_start - resvn_size;
      SizeT inner_HACK = 0;
      Bool ok;

      /* So far we've only accounted for space requirements down to the stack
         pointer.  If this target's ABI requires a redzone below the stack
         pointer, we need to allocate an extra page, to handle the worst case
         in which the stack pointer is almost at the bottom of a page, and so
         there is insufficient room left over to put the redzone in.  In this
         case the simple thing to do is allocate an extra page, by shrinking
         the reservation by one page and growing the anonymous area by a
         corresponding page. */
      vg_assert(VG_STACK_REDZONE_SZB >= 0);
      vg_assert(VG_STACK_REDZONE_SZB < VKI_PAGE_SIZE);
      if (VG_STACK_REDZONE_SZB > 0) {
         vg_assert(resvn_size > VKI_PAGE_SIZE);
         resvn_size -= VKI_PAGE_SIZE;
         anon_start -= VKI_PAGE_SIZE;
         anon_size += VKI_PAGE_SIZE;
      }

      vg_assert(VG_IS_PAGE_ALIGNED(anon_size));
      vg_assert(VG_IS_PAGE_ALIGNED(resvn_size));
      vg_assert(VG_IS_PAGE_ALIGNED(anon_start));
      vg_assert(VG_IS_PAGE_ALIGNED(resvn_start));
      vg_assert(resvn_start == clstack_end + 1 - clstack_max_size);

#     ifdef ENABLE_INNER
      /* Create 1M non-fault-extending stack. */
      inner_HACK = 1024 * 1024;
#     endif

      if (0)
         VG_(printf)("resvn_start=%#lx, resvn_size=%#lx\n"
                     "anon_start=%#lx, anon_size=%#lx\n",
                     resvn_start, resvn_size, anon_start, anon_size);

      /* Create a shrinkable reservation followed by an anonymous segment.
         Together these constitute a growdown stack. */
      ok = VG_(am_create_reservation)(resvn_start,
                                      resvn_size - inner_HACK,
                                      SmUpper,
                                      anon_size + inner_HACK);
      if (ok) {
         /* Allocate a stack - mmap enough space for the stack. */
         res = VG_(am_mmap_anon_fixed_client)(anon_start - inner_HACK,
                                              anon_size + inner_HACK,
                                              info->stack_prot);
      }
      if (!ok || sr_isError(res)) {
         /* Allocation of the stack failed.  We have to stop. */
         VG_(printf)("valgrind: "
                     "I failed to allocate space for the application's stack.\n");
         VG_(printf)("valgrind: "
                     "This may be the result of a very large --main-stacksize=\n");
         VG_(printf)("valgrind: setting.  Cannot continue.  Sorry.\n\n");
         VG_(exit)(1);
         /*NOTREACHED*/
      }
   }

   /* ==================== create client stack ==================== */

   ptr = (Addr*)client_SP;

   /* Copy-out client argc. */
   *ptr++ = argc;

   /* Copy-out client argv. */
   if (info->interp_name) {
      *ptr++ = (Addr)copy_str(&strtab, info->interp_name);
      VG_(free)(info->interp_name);
   }
   if (info->interp_args) {
      *ptr++ = (Addr)copy_str(&strtab, info->interp_args);
      VG_(free)(info->interp_args);
   }

   *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename));
   for (i = 0; i < VG_(sizeXA)(VG_(args_for_client)); i++)
      *ptr++ = (Addr)copy_str(
                  &strtab, *(HChar**) VG_(indexXA)(VG_(args_for_client), i));
   *ptr++ = 0;

   /* Copy-out envp. */
   VG_(client_envp) = (HChar**)ptr;
   for (cpp = orig_envp; *cpp; ptr++, cpp++)
      *ptr = (Addr)copy_str(&strtab, *cpp);
   *ptr++ = 0;

   /* Create aux vector. */
   auxv = (auxv_t*)ptr;
   VG_(client_auxv) = (UWord*)ptr;

   /* AT_SUN_PLATFORM */
   auxv->a_type = VKI_AT_SUN_PLATFORM;
#  if defined(VGA_x86) || defined(VGA_amd64)
   auxv->a_un.a_ptr = copy_str(&strtab, "i86pc");
#  else
#    error "Unknown architecture"
#  endif
   auxv++;

   /* AT_SUN_EXECNAME */
   auxv->a_type = VKI_AT_SUN_EXECNAME;
   auxv->a_un.a_ptr = copy_str(&strtab, resolved_exe_name);
   auxv++;

   /* AT_PHDR */
   if ((info->real_phdr_present) && (info->phdr != 0)) {
      auxv->a_type = VKI_AT_PHDR;
      auxv->a_un.a_val = info->phdr;
      auxv++;
   }

   /* AT_BASE */
   auxv->a_type = VKI_AT_BASE;
   auxv->a_un.a_val = info->interp_offset;
   auxv++;

   /* AT_FLAGS */
   auxv->a_type = VKI_AT_FLAGS;
#  if defined(VGA_x86) || defined(VGA_amd64)
   auxv->a_un.a_val = 0; /* 0 on i86pc */
#  else
#    error "Unknown architecture"
#  endif
   auxv++;

   /* AT_PAGESZ */
   auxv->a_type = VKI_AT_PAGESZ;
   auxv->a_un.a_val = VKI_PAGE_SIZE;
   auxv++;

   /* AT_SUN_AUXFLAFGS */
   auxv->a_type = VKI_AT_SUN_AUXFLAGS;
   /* XXX Handle AF_SUN_SETUGID? */
   auxv->a_un.a_val = VKI_AF_SUN_HWCAPVERIFY;
   auxv++;

   /* AT_SUN_HWCAP */
   {
      VexArch vex_arch;
      VexArchInfo vex_archinfo;
      UInt hwcaps;

      VG_(machine_get_VexArchInfo)(&vex_arch, &vex_archinfo);

#     if defined(VGA_x86)
      vg_assert(vex_arch == VexArchX86);

      /* Set default hwcaps. */
      hwcaps =
           VKI_AV_386_FPU       /* x87-style floating point */
         | VKI_AV_386_TSC       /* rdtsc insn */
         | VKI_AV_386_CX8       /* cmpxchg8b insn */
         | VKI_AV_386_SEP       /* sysenter and sysexit */
         | VKI_AV_386_AMD_SYSC  /* AMD's syscall and sysret */
         | VKI_AV_386_CMOV      /* conditional move insns */
         | VKI_AV_386_MMX       /* MMX insn */
         | VKI_AV_386_AHF;      /* lahf/sahf insns */

      /* Handle additional hwcaps. */
      if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE1)
         hwcaps |=
              VKI_AV_386_FXSR   /* fxsave and fxrstor */
            | VKI_AV_386_SSE;   /* SSE insns and regs  */
      if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE2) {
         vg_assert(vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE1);
         hwcaps |=
              VKI_AV_386_SSE2;  /* SSE2 insns and regs */
      }
      if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE3) {
         vg_assert(vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE2);
         hwcaps |=
              VKI_AV_386_SSE3   /* SSE3 insns and regs */
            | VKI_AV_386_SSSE3; /* Intel SSSE3 insns */
      }
      if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_LZCNT)
         hwcaps |=
              VKI_AV_386_AMD_LZCNT; /* AMD's LZCNT insn */

      /* No support for:
         AV_386_AMD_MMX         AMD's MMX insns
         AV_386_AMD_3DNow       AMD's 3Dnow! insns
         AV_386_AMD_3DNowx      AMD's 3Dnow! extended insns
         AV_386_CX16            cmpxchg16b insn
         AV_386_TSCP            rdtscp instruction
         AV_386_AMD_SSE4A       AMD's SSE4A insns
         AV_386_POPCNT          POPCNT insn
         AV_386_SSE4_1          Intel SSE4.1 insns
         AV_386_SSE4_2          Intel SSE4.2 insns
         AV_386_MOVBE           Intel MOVBE insns
         AV_386_AES             Intel AES insns
         AV_386_PCLMULQDQ       Intel PCLMULQDQ insn
         AV_386_XSAVE           Intel XSAVE/XRSTOR insns
         AV_386_AVX             Intel AVX insns
         illumos only:
            AV_386_VMX          Intel VMX support
            AV_386_AMD_SVM      AMD SVM support
         solaris only:
            AV_386_AMD_XOP      AMD XOP insns
            AV_386_AMD_FMA4     AMD FMA4 insns */

#     elif defined(VGA_amd64)
      vg_assert(vex_arch == VexArchAMD64);

      /* Set default hwcaps. */
      hwcaps =
           VKI_AV_386_FPU       /* x87-style floating point */
         | VKI_AV_386_TSC       /* rdtsc insn */
         | VKI_AV_386_CX8       /* cmpxchg8b insn */
         | VKI_AV_386_AMD_SYSC  /* AMD's syscall and sysret */
         | VKI_AV_386_CMOV      /* conditional move insns */
         | VKI_AV_386_MMX       /* MMX insn */
         | VKI_AV_386_AHF       /* lahf/sahf insns */
         | VKI_AV_386_FXSR      /* fxsave and fxrstor */
         | VKI_AV_386_SSE       /* SSE insns and regs  */
         | VKI_AV_386_SSE2;     /* SSE2 insns and regs */

      /* Handle additional hwcaps. */
      if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3)
         hwcaps |=
              VKI_AV_386_SSE3   /* SSE3 insns and regs */
            | VKI_AV_386_SSSE3; /* Intel SSSE3 insns */
      if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16)
         hwcaps |=
              VKI_AV_386_CX16;  /* cmpxchg16b insn */
      if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_LZCNT)
         hwcaps |=
              VKI_AV_386_AMD_LZCNT; /* AMD's LZCNT insn */
      if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_RDTSCP)
         hwcaps |=
              VKI_AV_386_TSCP;  /* rdtscp instruction */
      if ((vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3) &&
          (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16)) {
         /* The CPUID simulation provided by VEX claims to have POPCNT, AES
            and SSE4 (SSE4.1/SSE4.2) in the SSE3+CX16 configuration. */
         hwcaps |=
              VKI_AV_386_POPCNT /* POPCNT insn */
            | VKI_AV_386_AES    /* Intel AES insns */
            | VKI_AV_386_SSE4_1 /* Intel SSE4.1 insns */
            | VKI_AV_386_SSE4_2; /* Intel SSE4.2 insns */
      }
      if ((vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3) &&
          (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16) &&
          (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_AVX)) {
         /* The CPUID simulation provided by VEX claims to have PCLMULQDQ and
            XSAVE in the SSE3+CX16+AVX configuration. */
         hwcaps |=
              VKI_AV_386_PCLMULQDQ /* Intel PCLMULQDQ insn */
            | VKI_AV_386_XSAVE; /* Intel XSAVE/XRSTOR insns */
      }
      /* No support for:
         AV_386_SEP             sysenter and sysexit
         AV_386_AMD_MMX         AMD's MMX insns
         AV_386_AMD_3DNow       AMD's 3Dnow! insns
         AV_386_AMD_3DNowx      AMD's 3Dnow! extended insns
         AV_386_AMD_SSE4A       AMD's SSE4A insns
         AV_386_MOVBE           Intel MOVBE insns
         AV_386_AVX             Intel AVX insns
         illumos only:
            AV_386_VMX          Intel VMX support
            AV_386_AMD_SVM      AMD SVM support
         solaris only:
            AV_386_AMD_XOP      AMD XOP insns
            AV_386_AMD_FMA4     AMD FMA4 insns

         TODO VEX supports AVX, BMI and AVX2. Investigate if they can be
         enabled on Solaris/illumos.
       */

#     else
#       error "Unknown architecture"
#     endif

      auxv->a_type = VKI_AT_SUN_HWCAP;
      auxv->a_un.a_val = hwcaps;
      auxv++;
   }

   /* AT_SUN_HWCAP2 */
   {
      /* No support for:
         illumos only:
            AV_386_2_F16C       F16C half percision extensions
            AV_386_2_RDRAND     RDRAND insn
         solaris only:
            AV2_386_RDRAND      Intel RDRAND insns
            AV2_386_FMA         Intel FMA insn
            AV2_386_F16C        IEEE half precn(float) insn
            AV2_386_AMD_TBM     AMD TBM insn
            AV2_386_BMI1        Intel BMI1 insn
            AV2_386_FSGSBASE    Intel RD/WR FS/GSBASE insn
            AV2_386_AVX2        Intel AVX2 insns
            AV2_386_BMI2        Intel BMI2 insns
            AV2_386_HLE         Intel HLE insns
            AV2_386_RTM         Intel RTM insns
            AV2_386_EFS         Intel Enhanced Fast String
            AV2_386_RDSEED      Intel RDSEED insn
            AV2_386_ADX         Intel ADX insns
            AV2_386_PRFCHW      Intel PREFETCHW hint
       */
   }

#  if defined(SOLARIS_RESERVE_SYSSTAT_ADDR)
   /* AT_SUN_SYSSTAT_ADDR */
   copy_auxv_entry(orig_auxv, VKI_AT_SUN_SYSSTAT_ADDR,
                   "AT_SUN_SYSSTAT_ADDR", auxv);
   VG_(change_mapping_ownership)(auxv->a_un.a_val, True);
   auxv++;
#  endif

#  if defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR)
   /* AT_SUN_SYSSTAT_ZONE_ADDR */
   copy_auxv_entry(orig_auxv, VKI_AT_SUN_SYSSTAT_ZONE_ADDR,
                   "AT_SUN_SYSSTAT_ZONE_ADDR", auxv);
   VG_(change_mapping_ownership)(auxv->a_un.a_val, True);
   auxv++;
#  endif

   /* AT_NULL */
   auxv->a_type = VKI_AT_NULL;
   auxv->a_un.a_val = 0;

   vg_assert(strtab - stringbase == stringsize);

   /* The variable client_SP is now pointing at client's argc/argv. */

   if (0)
      VG_(printf)("startup SP = %#lx\n", client_SP);
   return client_SP;
}

/*====================================================================*/
/*=== TOP-LEVEL: VG_(setup_client_initial_image)                   ===*/
/*====================================================================*/

/* Create the client's initial memory image. */
IIFinaliseImageInfo VG_(ii_create_image)(IICreateImageInfo iicii,
                                         const VexArchInfo *vex_archinfo)
{
   ExeInfo info;
   HChar **env = NULL;
   HChar resolved_exe_name[VKI_PATH_MAX];

   IIFinaliseImageInfo iifii;
   VG_(memset)(&iifii, 0, sizeof(iifii));

   //--------------------------------------------------------------
   // Load client executable, finding in $PATH if necessary
   //   p: early_process_cmd_line_options()  [for 'exec', 'need_help']
   //   p: layout_remaining_space            [so there's space]
   //--------------------------------------------------------------
   VG_(debugLog)(1, "initimg", "Loading client\n");

   if (!VG_(args_the_exename)) {
      VG_(err_missing_prog)();
      /*NOTREACHED*/
   }

   load_client(&info, resolved_exe_name, sizeof(resolved_exe_name));
   iifii.initial_client_IP = info.init_ip;
   /* Note: TOC isn't available on Solaris. */
   iifii.initial_client_TOC = info.init_toc;
   iifii.initial_client_TP = info.init_thrptr;
   /* Note that iifii.client_auxv is never set on Solaris, because it isn't
      necessary to have this value in VG_(ii_finalise_image). */

   //--------------------------------------------------------------
   // Set up client's environment
   //   p: set-libdir                       [for VG_(libdir)]
   //   p: early_process_cmd_line_options() [for toolname]
   //--------------------------------------------------------------
   VG_(debugLog)(1, "initimg", "Setup client env\n");
   env = setup_client_env(iicii.envp, iicii.toolname);

   //--------------------------------------------------------------
   // Setup client stack and EIP
   //   p: load_client()     [for 'info']
   //   p: fix_environment() [for 'env']
   //--------------------------------------------------------------
   {
      /* When allocating space for the client stack, take notice of the
         --main-stacksize value.  This makes it possible to run programs with
         very large (primary) stack requirements simply by specifying
         --main-stacksize. */
      /* Logic is as follows:
         - By default, use the client's current stack rlimit.
         - If that exceeds 16M, clamp to 16M.
         - If a larger --main-stacksize value is specified, use that instead.
         - In all situations, the minimum allowed stack size is 1M.
      */
      Addr init_sp = (Addr) (iicii.argv - 1);
      SizeT m1  = 1024 * 1024;
      SizeT m16 = 16 * m1;
      SizeT szB = (SizeT)VG_(client_rlimit_stack).rlim_cur;
      if (szB < m1)
         szB = m1;
      if (szB > m16)
         szB = m16;

      if (VG_(clo_main_stacksize) > 0)
         szB = VG_(clo_main_stacksize);
      if (szB < m1)
         szB = m1;

      szB = VG_PGROUNDUP(szB);
      VG_(debugLog)(1, "initimg",
                       "Setup client stack: size will be %ld\n", szB);

      iifii.clstack_max_size = szB;
      iifii.initial_client_SP = setup_client_stack(init_sp, env, &info,
                                                   iicii.clstack_end,
                                                   iifii.clstack_max_size,
                                                   resolved_exe_name);
      VG_(free)(env);

      VG_(debugLog)(2, "initimg", "Client info: "
                       "initial_IP=%#lx, initial_TOC=%#lx, brk_base=%#lx\n",
                       iifii.initial_client_IP, iifii.initial_client_TOC,
                       VG_(brk_base));
      VG_(debugLog)(2, "initimg", "Client info: "
                       "initial_SP=%#lx, max_stack_size=%lu\n",
                       iifii.initial_client_SP,
                       iifii.clstack_max_size);
   }

   if (info.ldsoexec) {
      /* We are executing the runtime linker itself.
         Initial data (brk) segment is setup on demand, after the target dynamic
         executable has been loaded or when a first brk() syscall is made.
         It cannot be established now because it would conflict with a temporary
         stack which ld.so.1 (when executed directly) uses for loading the
         target dynamic executable. See PRE(sys_brk) in syswrap-solaris.c. */
   } else {
      if (!VG_(setup_client_dataseg)()) {
         VG_(printf)("valgrind: cannot initialize data segment (brk).\n");
         VG_(exit)(1);
      }
   }

   return iifii;
}


/*====================================================================*/
/*=== TOP-LEVEL: VG_(finalise_image)                               ===*/
/*====================================================================*/

/* Just before starting the client, we may need to make final adjustments to
   its initial image.  Also we need to set up the VEX guest state for thread 1
   (the root thread) and copy in essential starting values.  This is handed
   the IIFinaliseImageInfo created by VG_(ii_create_image).
*/
void VG_(ii_finalise_image)(IIFinaliseImageInfo iifii)
{
   ThreadArchState *arch = &VG_(threads)[1].arch;

#  if defined(VGA_x86)
   vg_assert(0 == sizeof(VexGuestX86State) % LibVEX_GUEST_STATE_ALIGN);

   /* Zero out the initial state, and set up the simulated FPU in a sane
      way. */
   LibVEX_GuestX86_initialise(&arch->vex);

   /* Zero out the shadow areas. */
   VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State));
   VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State));

   /* Put essential stuff into the new state. */
   arch->vex.guest_ESP = iifii.initial_client_SP;
   arch->vex.guest_EIP = iifii.initial_client_IP;
   LibVEX_GuestX86_put_eflags(VKI_PSL_USER, &arch->vex);

   /* Set %cs, %ds, %ss and %es to default values. */
   __asm__ __volatile__ ("movw %%cs, %[cs]" : [cs] "=m" (arch->vex.guest_CS));
   __asm__ __volatile__ ("movw %%ds, %[ds]" : [ds] "=m" (arch->vex.guest_DS));
   __asm__ __volatile__ ("movw %%ss, %[ss]" : [ss] "=m" (arch->vex.guest_SS));
   __asm__ __volatile__ ("movw %%es, %[es]" : [es] "=m" (arch->vex.guest_ES));

   {
      /* Initial thread pointer value will be saved in GDT when the thread is
         started in the syswrap module and a thread's GDT is allocated. */
      ThreadOSstate *os = &VG_(threads)[1].os_state;
      os->thrptr = iifii.initial_client_TP;
   }

#  elif defined(VGA_amd64)
   vg_assert(0 == sizeof(VexGuestAMD64State) % LibVEX_GUEST_STATE_ALIGN);

   /* Zero out the initial state, and set up the simulated FPU in a sane
      way. */
   LibVEX_GuestAMD64_initialise(&arch->vex);

   /* Zero out the shadow areas. */
   VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestAMD64State));
   VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State));

   /* Put essential stuff into the new state. */
   arch->vex.guest_RSP = iifii.initial_client_SP;
   arch->vex.guest_RIP = iifii.initial_client_IP;
   arch->vex.guest_FS_CONST = iifii.initial_client_TP;
   LibVEX_GuestAMD64_put_rflags(VKI_PSL_USER, &arch->vex);

#  else
#    error "Unknown platform"
#  endif

   /* Tell the tool that we just wrote to the registers. */
   VG_TRACK(post_reg_write, Vg_CoreStartup, 1/*tid*/, 0/*offset*/,
            sizeof(VexGuestArchState));

   if (VG_(brk_base) != -1 ) {
      /* Make inaccessible/unaddressable the end of the client data segment.
         See PRE(sys_brk) in syswrap-solaris.c for details. */
      VG_(track_client_dataseg)(1 /* tid */);
   }
}

#endif // defined(VGO_solaris)

/*--------------------------------------------------------------------*/
/*---                                                              ---*/
/*--------------------------------------------------------------------*/
