Home | History | Annotate | Download | only in m_initimg
      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 (at) 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 (at) 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). */
     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 */
    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. */
    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. */
    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 
    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 
    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_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. */
    853 IIFinaliseImageInfo 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 */
    969 void 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