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