18eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 28eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--------------------------------------------------------------------*/ 38eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--- Startup: create initial process image on Solaris ---*/ 48eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--- initimg-solaris.c ---*/ 58eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--------------------------------------------------------------------*/ 68eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 78eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* 88eb8bab992e3998c33770b0cdb16059a8b918a06sewardj This file is part of Valgrind, a dynamic binary instrumentation 98eb8bab992e3998c33770b0cdb16059a8b918a06sewardj framework. 108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 11ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2011-2017 Petr Pavlu 128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj setup@dagobah.cz 138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj This program is free software; you can redistribute it and/or 158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj modify it under the terms of the GNU General Public License as 168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj published by the Free Software Foundation; either version 2 of the 178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj License, or (at your option) any later version. 188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj This program is distributed in the hope that it will be useful, but 208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj WITHOUT ANY WARRANTY; without even the implied warranty of 218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj General Public License for more details. 238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj You should have received a copy of the GNU General Public License 258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj along with this program; if not, write to the Free Software 268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 02111-1307, USA. 288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj The GNU General Public License is contained in the file COPYING. 308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj*/ 318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 32ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes/* Copyright 2013-2017, Ivo Raisr <ivosh@ivosh.net>. */ 33e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#if defined(VGO_solaris) 358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Note: This file is based on initimg-linux.c. */ 378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_basics.h" 398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_vki.h" 408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_debuglog.h" 418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_libcbase.h" 428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_libcassert.h" 438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_libcfile.h" 448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_libcproc.h" 458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_libcprint.h" 468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_xarray.h" 478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_clientstate.h" 488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_aspacemgr.h" 498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_mallocfree.h" 508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_machine.h" 518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_ume.h" 528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_options.h" 53bcfaeedb1e1ac2625eea81951a785a777834321ciraisr#include "pub_core_syswrap.h" 548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_tooliface.h" /* VG_TRACK */ 558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_threadstate.h" /* ThreadArchState */ 568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "priv_initimg_pathscan.h" 578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#include "pub_core_initimg.h" /* self */ 588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*====================================================================*/ 618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*=== Loading the client ===*/ 628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*====================================================================*/ 638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Load the client whose name is VG_(argv_the_exename). */ 658eb8bab992e3998c33770b0cdb16059a8b918a06sewardjstatic void load_client(/*OUT*/ExeInfo *info, 668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /*OUT*/HChar *out_exe_name, SizeT out_exe_name_size) 678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj const HChar *exe_name; 698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Int ret; 708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SysRes res; 718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_(args_the_exename)); 738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj exe_name = ML_(find_executable)(VG_(args_the_exename)); 748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!exe_name) { 768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename)); 778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Return POSIX's NOTFOUND. */ 788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(exit)(127); 798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /*NOTREACHED*/ 808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(memset)(info, 0, sizeof(*info)); 838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ret = VG_(do_exec)(exe_name, info); 848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (ret < 0) { 858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(printf)("valgrind: could not execute '%s'\n", exe_name); 868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(exit)(1); 878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /*NOTREACHED*/ 888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The client was successfully loaded! Continue. */ 918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Save resolved exename. */ 938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (VG_(strlen)(exe_name) + 1 > out_exe_name_size) { 948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* This should not really happen. */ 958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(printf)("valgrind: execname %s is too long\n", exe_name); 968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(exit)(1); 978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /*NOTREACHED*/ 988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(strcpy)(out_exe_name, exe_name); 1008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Get hold of a file descriptor which refers to the client executable. 1028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj This is needed for attaching to GDB. */ 1038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR); 1048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!sr_isError(res)) 1058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(cl_exec_fd) = sr_Res(res); 1068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Set initial brk values. */ 108bcfaeedb1e1ac2625eea81951a785a777834321ciraisr if (info->ldsoexec) { 109bcfaeedb1e1ac2625eea81951a785a777834321ciraisr VG_(brk_base) = VG_(brk_limit) = -1; 110bcfaeedb1e1ac2625eea81951a785a777834321ciraisr } else { 111bcfaeedb1e1ac2625eea81951a785a777834321ciraisr VG_(brk_base) = VG_(brk_limit) = info->brkbase; 112bcfaeedb1e1ac2625eea81951a785a777834321ciraisr } 1138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 1148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*====================================================================*/ 1178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*=== Setting up the client's environment ===*/ 1188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*====================================================================*/ 1198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Prepare the client's environment. This is basically a copy of our 1218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj environment, except: 1228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj LD_PRELOAD=$VALGRIND_LIB/vgpreload_core-PLATFORM.so: 1248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ($VALGRIND_LIB/vgpreload_TOOL-PLATFORM.so:)? 1258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj $LD_PRELOAD 1268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj If this is missing, then it is added. 1288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Also, remove any binding for VALGRIND_LAUNCHER=. The client should not be 1308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj able to see this. 1318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj If this needs to handle any more variables it should be hacked into 1338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj something table driven. The copy is VG_(malloc)'d space. 1348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj*/ 1358eb8bab992e3998c33770b0cdb16059a8b918a06sewardjstatic HChar **setup_client_env(HChar **origenv, const HChar *toolname) 1368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 1378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj const HChar *ld_preload = "LD_PRELOAD="; 1388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT ld_preload_len = VG_(strlen)(ld_preload); 1398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Bool ld_preload_done = False; 1408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT vglib_len = VG_(strlen)(VG_(libdir)); 1418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar **cpp; 1438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar **ret; 1448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar *preload_tool_path; 1458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT envc, i; 1468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Alloc space for the 1488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj <path>/vgpreload_core-<platform>.so and 1498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj <path>/vgpreload_<tool>-<platform>.so 1508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj paths. We might not need the space for the tool path, but it doesn't 1518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hurt to over-allocate briefly. */ 1528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT preload_core_path_size = vglib_len + sizeof("/vgpreload_core-") - 1 1538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj + sizeof(VG_PLATFORM) - 1 1548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj + sizeof(".so"); 1558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT preload_tool_path_size = vglib_len + sizeof("/vgpreload_") - 1 1568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj + VG_(strlen)(toolname) + 1 /*-*/ 1578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj + sizeof(VG_PLATFORM) - 1 1588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj + sizeof(".so"); 1598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT preload_string_size = preload_core_path_size 1608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj + preload_tool_path_size; 1618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar *preload_string = VG_(malloc)("initimg-solaris.sce.1", 1628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj preload_string_size); 1638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Check that the parameters are sane. */ 1658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(origenv); 1668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(toolname); 1678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Determine if there's a vgpreload_<tool>-<platform>.so file, and setup 1698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj preload_string. */ 1708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj preload_tool_path = VG_(malloc)("initimg-solaris.sce.2", 1718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj preload_tool_path_size); 1728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(sprintf)(preload_tool_path, "%s/vgpreload_%s-%s.so", VG_(libdir), 1738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj toolname, VG_PLATFORM); 1748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!VG_(access)(preload_tool_path, True/*r*/, False/*w*/, False/*x*/)) { 1758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The tool's .so exists, put it into LD_PRELOAD with the core's so. */ 1768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(sprintf)(preload_string, "%s/vgpreload_core-%s.so:%s", VG_(libdir), 1778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_PLATFORM, preload_tool_path); 1788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 1798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj else { 1808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The tool's .so doesn't exist, put only the core's .so into 1818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj LD_PRELOAD. */ 1828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(sprintf)(preload_string, "%s/vgpreload_core-%s.so", VG_(libdir), 1838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_PLATFORM); 1848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 1858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(free)(preload_tool_path); 1868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(debugLog)(2, "initimg", "preload_string:\n"); 1888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(debugLog)(2, "initimg", " \"%s\"\n", preload_string); 1898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Count the original size of the env. */ 1918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj envc = 0; 1928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (cpp = origenv; *cpp; cpp++) 1938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj envc++; 1948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Allocate a new space, envc + 1 new entry + NULL. */ 1968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ret = VG_(malloc)("initimg-solaris.sce.3", sizeof(HChar*) * (envc + 1 + 1)); 1978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Copy it over. */ 1998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (cpp = ret; *origenv; ) 2008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *cpp++ = *origenv++; 2018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *cpp = NULL; 2028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(envc == cpp - ret); 2048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Walk over the new environment, mashing as we go. */ 2068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (cpp = ret; *cpp; cpp++) { 2078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (VG_(memcmp)(*cpp, ld_preload, ld_preload_len)) 2088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj continue; 2098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* LD_PRELOAD entry found, smash it. */ 2118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT size = VG_(strlen)(*cpp) + 1 /*:*/ 2128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj + preload_string_size; 2138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar *cp = VG_(malloc)("initimg-solaris.sce.4", size); 2148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(sprintf)(cp, "%s%s:%s", ld_preload, preload_string, 2168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (*cpp) + ld_preload_len); 2178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *cpp = cp; 2188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ld_preload_done = True; 2208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 2218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Add the missing bits. */ 2238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!ld_preload_done) { 2248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT size = ld_preload_len + preload_string_size; 2258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar *cp = VG_(malloc)("initimg-solaris.sce.5", size); 2268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(sprintf)(cp, "%s%s", ld_preload, preload_string); 2288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ret[envc++] = cp; 2298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 2308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* We've got ret[0 .. envc-1] live now. */ 2328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Find and remove a binding for VALGRIND_LAUNCHER. */ 2348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj { 2358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj const HChar *v_launcher = VALGRIND_LAUNCHER "="; 2368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT v_launcher_len = VG_(strlen)(v_launcher); 2378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (i = 0; i < envc; i++) 239a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (!VG_(memcmp)(ret[i], v_launcher, v_launcher_len)) { 2408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* VALGRIND_LAUNCHER was found. */ 2418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj break; 2428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 2438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (i < envc) { 2458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* VALGRIND_LAUNCHER was found, remove it. */ 2468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (; i < envc - 1; i++) 2478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ret[i] = ret[i + 1]; 2488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj envc--; 2498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 2508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 2518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(free)(preload_string); 2538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ret[envc] = NULL; 2548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj return ret; 2568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 2578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*====================================================================*/ 2608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*=== Setting up the client's stack ===*/ 2618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*====================================================================*/ 2628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Add a string onto the string table, and return its address. */ 2648eb8bab992e3998c33770b0cdb16059a8b918a06sewardjstatic HChar *copy_str(HChar **tab, const HChar *str) 2658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 2668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar *cp = *tab; 2678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar *orig = cp; 2688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj while (*str) 2708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *cp++ = *str++; 2718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *cp++ = '\0'; 2728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *tab = cp; 2748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj return orig; 2768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 2778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 2786150d3e63c6989aa7b6540ff75d6ae104ad3aa28iraisr#if defined(SOLARIS_RESERVE_SYSSTAT_ADDR) || \ 2796150d3e63c6989aa7b6540ff75d6ae104ad3aa28iraisr defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR) 2806150d3e63c6989aa7b6540ff75d6ae104ad3aa28iraisr#define ORIG_AUXV_PRESENT 1 2816150d3e63c6989aa7b6540ff75d6ae104ad3aa28iraisr#endif 2826150d3e63c6989aa7b6540ff75d6ae104ad3aa28iraisr 2836150d3e63c6989aa7b6540ff75d6ae104ad3aa28iraisr#if defined(ORIG_AUXV_PRESENT) 284e03654002556aa3ece73c344ec8c8cbe15754df1iraisr/* The auxiliary vector might not be present. So we cross-check pointers from 285e03654002556aa3ece73c344ec8c8cbe15754df1iraisr argv and envp pointing to the string table. */ 286e03654002556aa3ece73c344ec8c8cbe15754df1iraisrstatic vki_auxv_t *find_original_auxv(Addr init_sp) 287e03654002556aa3ece73c344ec8c8cbe15754df1iraisr{ 288e03654002556aa3ece73c344ec8c8cbe15754df1iraisr HChar **sp = (HChar **) init_sp; 289e03654002556aa3ece73c344ec8c8cbe15754df1iraisr HChar *lowest_str_ptr = (HChar *) UINTPTR_MAX; // lowest ptr to string table 290e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 291e03654002556aa3ece73c344ec8c8cbe15754df1iraisr sp++; // skip argc 292e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 293e03654002556aa3ece73c344ec8c8cbe15754df1iraisr while (*sp != NULL) { // skip argv 294e03654002556aa3ece73c344ec8c8cbe15754df1iraisr if (*sp < lowest_str_ptr) 295e03654002556aa3ece73c344ec8c8cbe15754df1iraisr lowest_str_ptr = *sp; 296e03654002556aa3ece73c344ec8c8cbe15754df1iraisr sp++; 297e03654002556aa3ece73c344ec8c8cbe15754df1iraisr } 298e03654002556aa3ece73c344ec8c8cbe15754df1iraisr sp++; 299e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 300e03654002556aa3ece73c344ec8c8cbe15754df1iraisr while (*sp != 0) { // skip env 301e03654002556aa3ece73c344ec8c8cbe15754df1iraisr if (*sp < lowest_str_ptr) 302e03654002556aa3ece73c344ec8c8cbe15754df1iraisr lowest_str_ptr = *sp; 303e03654002556aa3ece73c344ec8c8cbe15754df1iraisr sp++; 304e03654002556aa3ece73c344ec8c8cbe15754df1iraisr } 305e03654002556aa3ece73c344ec8c8cbe15754df1iraisr sp++; 306e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 307e03654002556aa3ece73c344ec8c8cbe15754df1iraisr if ((Addr) sp < (Addr) lowest_str_ptr) { 308e03654002556aa3ece73c344ec8c8cbe15754df1iraisr return (vki_auxv_t *) sp; 309e03654002556aa3ece73c344ec8c8cbe15754df1iraisr } else { 310e03654002556aa3ece73c344ec8c8cbe15754df1iraisr return NULL; 311e03654002556aa3ece73c344ec8c8cbe15754df1iraisr } 312e03654002556aa3ece73c344ec8c8cbe15754df1iraisr} 313e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 314e03654002556aa3ece73c344ec8c8cbe15754df1iraisrstatic void copy_auxv_entry(const vki_auxv_t *orig_auxv, Int type, 315e03654002556aa3ece73c344ec8c8cbe15754df1iraisr const HChar *type_name, vki_auxv_t *auxv) 316e03654002556aa3ece73c344ec8c8cbe15754df1iraisr{ 317e03654002556aa3ece73c344ec8c8cbe15754df1iraisr vg_assert(auxv != NULL); 318e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 319e03654002556aa3ece73c344ec8c8cbe15754df1iraisr if (orig_auxv == NULL) { 320e03654002556aa3ece73c344ec8c8cbe15754df1iraisr VG_(printf)("valgrind: Cannot locate auxiliary vector.\n"); 321e03654002556aa3ece73c344ec8c8cbe15754df1iraisr VG_(printf)("valgrind: Cannot continue. Sorry.\n\n"); 322e03654002556aa3ece73c344ec8c8cbe15754df1iraisr VG_(exit)(1); 323e03654002556aa3ece73c344ec8c8cbe15754df1iraisr } 324e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 325e03654002556aa3ece73c344ec8c8cbe15754df1iraisr for ( ; orig_auxv->a_type != VKI_AT_NULL; orig_auxv++) { 326e03654002556aa3ece73c344ec8c8cbe15754df1iraisr if (orig_auxv->a_type == type) { 327e03654002556aa3ece73c344ec8c8cbe15754df1iraisr auxv->a_type = type; 328e03654002556aa3ece73c344ec8c8cbe15754df1iraisr auxv->a_un.a_val = orig_auxv->a_un.a_val; 329e03654002556aa3ece73c344ec8c8cbe15754df1iraisr return; 330e03654002556aa3ece73c344ec8c8cbe15754df1iraisr } 331e03654002556aa3ece73c344ec8c8cbe15754df1iraisr } 332e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 333e03654002556aa3ece73c344ec8c8cbe15754df1iraisr VG_(printf)("valgrind: Cannot locate %s in the aux\n", type_name); 334e03654002556aa3ece73c344ec8c8cbe15754df1iraisr VG_(printf)("valgrind: vector. Cannot continue. Sorry.\n\n"); 335e03654002556aa3ece73c344ec8c8cbe15754df1iraisr VG_(exit)(1); 336e03654002556aa3ece73c344ec8c8cbe15754df1iraisr} 3376150d3e63c6989aa7b6540ff75d6ae104ad3aa28iraisr#endif /* ORIG_AUXV_PRESENT */ 3388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 3398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* This sets up the client's initial stack, containing the args, 3408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj environment and aux vector. 3418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 3428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj The format of the stack is: 3438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 3448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj higher address +-----------------+ <- clstack_end 3458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | | 3468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj : string table : 3478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | | 3488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj +-----------------+ 3498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | AT_NULL | 3508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj - - 3518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | auxv | 3528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj +-----------------+ 3538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | NULL | 3548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj - - 3558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | envp | 3568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj +-----------------+ 3578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | NULL | 3588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj - - 3598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | argv | 3608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj +-----------------+ 3618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | argc | 3628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj lower address +-----------------+ <- sp 3638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | undefined | 3648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj : : 3658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 3668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Allocate and create the initial client stack. It is allocated down from 3678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj clstack_end, which was previously determined by the address space manager. 3688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj The returned value is the SP value for the client. 3698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 370e03654002556aa3ece73c344ec8c8cbe15754df1iraisr Note that auxiliary vector is *not* created by kernel on illumos and 371e03654002556aa3ece73c344ec8c8cbe15754df1iraisr Solaris 11 if the program is statically linked (which is our case). 372e03654002556aa3ece73c344ec8c8cbe15754df1iraisr Although we now taught Solaris 12 to create the auxiliary vector, we still 373e03654002556aa3ece73c344ec8c8cbe15754df1iraisr have to build auxv from scratch, to make the code consistent. */ 3748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 375e03654002556aa3ece73c344ec8c8cbe15754df1iraisrstatic Addr setup_client_stack(Addr init_sp, 3768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar **orig_envp, 3778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj const ExeInfo *info, 3788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr clstack_end, 3798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT clstack_max_size, 3808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj const HChar *resolved_exe_name) 3818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 3828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SysRes res; 3838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar **cpp; 3848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar *strtab; /* string table */ 3858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar *stringbase; 3868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr *ptr; 3878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vki_auxv_t *auxv; 3888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT stringsize; /* total size of strings in bytes */ 3898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT auxsize; /* total size of auxv in bytes */ 3908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Int argc; /* total argc */ 3918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Int envc; /* total number of env vars */ 3928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT stacksize; /* total client stack size */ 3938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr client_SP; /* client stack base (initial SP) */ 3948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr clstack_start; 3958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Int i; 3968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 3978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_IS_PAGE_ALIGNED(clstack_end + 1)); 3988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_(args_the_exename)); 3998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_(args_for_client)); 4008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4016150d3e63c6989aa7b6540ff75d6ae104ad3aa28iraisr# if defined(ORIG_AUXV_PRESENT) 402e03654002556aa3ece73c344ec8c8cbe15754df1iraisr /* Get the original auxv (if any). */ 403e03654002556aa3ece73c344ec8c8cbe15754df1iraisr vki_auxv_t *orig_auxv = find_original_auxv(init_sp); 4046150d3e63c6989aa7b6540ff75d6ae104ad3aa28iraisr# endif /* ORIG_AUXV_PRESENT */ 405e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 4068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* ==================== compute sizes ==================== */ 4078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* First of all, work out how big the client stack will be. */ 4098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stringsize = 0; 4108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Paste on the extra args if the loader needs them (i.e. the #! 4128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj interpreter and its argument). */ 4138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj argc = 0; 4148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (info->interp_name) { 4158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj argc++; 4168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stringsize += VG_(strlen)(info->interp_name) + 1; 4178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 4188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (info->interp_args) { 4198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj argc++; 4208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stringsize += VG_(strlen)(info->interp_args) + 1; 4218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 4228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Now scan the args we're given... */ 4248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj argc++; 4258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stringsize += VG_(strlen)(VG_(args_the_exename)) + 1; 4268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (i = 0; i < VG_(sizeXA)(VG_(args_for_client)); i++) { 4278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj argc++; 4288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stringsize += VG_(strlen)(*(HChar**) 4298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(indexXA)(VG_(args_for_client), i)) + 1; 4308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 4318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* ...and the environment. */ 4338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj envc = 0; 4348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (cpp = orig_envp; *cpp; cpp++) { 4358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj envc++; 4368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stringsize += VG_(strlen)(*cpp) + 1; 4378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 4388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Now, how big is the auxv? 4408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AT_SUN_PLATFORM 4428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AT_SUN_EXECNAME 443358f27ccb54ef77fbd0d6e199b4b5431dfb1b465iraisr AT_PHDR (not for elfs with no PT_PHDR, such as ld.so.1) 4448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AT_BASE 445a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes AT_ENTRY 4468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AT_FLAGS 4478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AT_PAGESZ 4488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AT_SUN_AUXFLAFGS 4498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AT_SUN_HWCAP 450e03654002556aa3ece73c344ec8c8cbe15754df1iraisr AT_SUN_SYSSTAT_ADDR (if supported) 451e03654002556aa3ece73c344ec8c8cbe15754df1iraisr AT_SUN_SYSSTAT_ZONE_ADDR (if supported) 4528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AT_NULL 4538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 454a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes It would be possible to also add AT_PHENT, AT_PHNUM, AT_SUN_LDDATA, 455a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes but they don't seem to be so important. */ 456a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes auxsize = 10 * sizeof(*auxv); 457e03654002556aa3ece73c344ec8c8cbe15754df1iraisr# if defined(SOLARIS_RESERVE_SYSSTAT_ADDR) 458e03654002556aa3ece73c344ec8c8cbe15754df1iraisr auxsize += sizeof(*auxv); 459e03654002556aa3ece73c344ec8c8cbe15754df1iraisr# endif 460e03654002556aa3ece73c344ec8c8cbe15754df1iraisr# if defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR) 461e03654002556aa3ece73c344ec8c8cbe15754df1iraisr auxsize += sizeof(*auxv); 462e03654002556aa3ece73c344ec8c8cbe15754df1iraisr# endif 463e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 4648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# if defined(VGA_x86) || defined(VGA_amd64) 4658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_SUN_PLATFORM string. */ 4668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stringsize += VG_(strlen)("i86pc") + 1; 4678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# else 4688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# error "Unknown architecture" 4698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# endif 4708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_SUN_EXECNAME string. */ 4718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stringsize += VG_(strlen)(resolved_exe_name) + 1; 4728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Calculate how big the client stack is. */ 4748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stacksize = 4758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(Word) + /* argc */ 4768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(HChar**) + /* argc[0] == exename */ 4778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(HChar**) * argc + /* argv */ 4788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(HChar**) + /* terminal NULL */ 4798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(HChar**) * envc + /* envp */ 4808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(HChar**) + /* terminal NULL */ 4818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxsize + /* auxv */ 4828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_ROUNDUP(stringsize, sizeof(Word)); /* strings (aligned) */ 4838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The variable client_SP is the client's stack pointer. */ 4858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj client_SP = clstack_end - stacksize; 4868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj client_SP = VG_ROUNDDN(client_SP, 16); /* Make stack 16 byte aligned. */ 4878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Calculate base of the string table (aligned). */ 4898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stringbase = (HChar*)clstack_end - VG_ROUNDUP(stringsize, sizeof(Int)); 4908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj strtab = stringbase; 4918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj clstack_start = VG_PGROUNDDN(client_SP); 4938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Calculate the max stack size. */ 4958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj clstack_max_size = VG_PGROUNDUP(clstack_max_size); 4968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 4978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Record stack extent -- needed for stack-change code. */ 4988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(clstk_start_base) = clstack_start; 4998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(clstk_end) = clstack_end; 5008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(clstk_max_size) = clstack_max_size; 5018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (0) 5038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(printf)("stringsize=%lu, auxsize=%lu, stacksize=%lu, maxsize=%#lx\n" 5048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "clstack_start %#lx\n" 5058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "clstack_end %#lx\n", 5068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj stringsize, auxsize, stacksize, clstack_max_size, 5078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj clstack_start, clstack_end); 5088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* ==================== allocate space ==================== */ 5108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj { 5128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT anon_size = clstack_end - clstack_start + 1; 5138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT resvn_size = clstack_max_size - anon_size; 5148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr anon_start = clstack_start; 5158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Addr resvn_start = anon_start - resvn_size; 5168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT inner_HACK = 0; 5178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Bool ok; 5188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* So far we've only accounted for space requirements down to the stack 5208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj pointer. If this target's ABI requires a redzone below the stack 5218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj pointer, we need to allocate an extra page, to handle the worst case 5228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj in which the stack pointer is almost at the bottom of a page, and so 5238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj there is insufficient room left over to put the redzone in. In this 5248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj case the simple thing to do is allocate an extra page, by shrinking 5258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj the reservation by one page and growing the anonymous area by a 5268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj corresponding page. */ 5278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_STACK_REDZONE_SZB >= 0); 5288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_STACK_REDZONE_SZB < VKI_PAGE_SIZE); 5298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (VG_STACK_REDZONE_SZB > 0) { 5308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(resvn_size > VKI_PAGE_SIZE); 5318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj resvn_size -= VKI_PAGE_SIZE; 5328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj anon_start -= VKI_PAGE_SIZE; 5338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj anon_size += VKI_PAGE_SIZE; 5348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 5358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_IS_PAGE_ALIGNED(anon_size)); 5378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_IS_PAGE_ALIGNED(resvn_size)); 5388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_IS_PAGE_ALIGNED(anon_start)); 5398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(VG_IS_PAGE_ALIGNED(resvn_start)); 5408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(resvn_start == clstack_end + 1 - clstack_max_size); 5418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# ifdef ENABLE_INNER 5438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Create 1M non-fault-extending stack. */ 5448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj inner_HACK = 1024 * 1024; 5458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# endif 5468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (0) 5488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(printf)("resvn_start=%#lx, resvn_size=%#lx\n" 5498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "anon_start=%#lx, anon_size=%#lx\n", 5508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj resvn_start, resvn_size, anon_start, anon_size); 5518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Create a shrinkable reservation followed by an anonymous segment. 5538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj Together these constitute a growdown stack. */ 5548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ok = VG_(am_create_reservation)(resvn_start, 5558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj resvn_size - inner_HACK, 5568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SmUpper, 5578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj anon_size + inner_HACK); 5588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (ok) { 5598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Allocate a stack - mmap enough space for the stack. */ 5608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj res = VG_(am_mmap_anon_fixed_client)(anon_start - inner_HACK, 5618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj anon_size + inner_HACK, 5628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj info->stack_prot); 5638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 5648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!ok || sr_isError(res)) { 5658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Allocation of the stack failed. We have to stop. */ 5668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(printf)("valgrind: " 5678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "I failed to allocate space for the application's stack.\n"); 5688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(printf)("valgrind: " 5698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "This may be the result of a very large --main-stacksize=\n"); 5708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(printf)("valgrind: setting. Cannot continue. Sorry.\n\n"); 5718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(exit)(1); 5728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /*NOTREACHED*/ 5738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 5748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 5758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* ==================== create client stack ==================== */ 5778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ptr = (Addr*)client_SP; 5798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Copy-out client argc. */ 5818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *ptr++ = argc; 5828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Copy-out client argv. */ 584a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (info->interp_name) 5858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *ptr++ = (Addr)copy_str(&strtab, info->interp_name); 586a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (info->interp_args) 5878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *ptr++ = (Addr)copy_str(&strtab, info->interp_args); 5888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename)); 5908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (i = 0; i < VG_(sizeXA)(VG_(args_for_client)); i++) 5918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *ptr++ = (Addr)copy_str( 5928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj &strtab, *(HChar**) VG_(indexXA)(VG_(args_for_client), i)); 5938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *ptr++ = 0; 5948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 5958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Copy-out envp. */ 5968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(client_envp) = (HChar**)ptr; 5978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj for (cpp = orig_envp; *cpp; ptr++, cpp++) 5988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *ptr = (Addr)copy_str(&strtab, *cpp); 5998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj *ptr++ = 0; 6008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Create aux vector. */ 6028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv = (auxv_t*)ptr; 6038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(client_auxv) = (UWord*)ptr; 6048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_SUN_PLATFORM */ 6068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_type = VKI_AT_SUN_PLATFORM; 6078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# if defined(VGA_x86) || defined(VGA_amd64) 6088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_un.a_ptr = copy_str(&strtab, "i86pc"); 6098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# else 6108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# error "Unknown architecture" 6118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# endif 6128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv++; 6138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_SUN_EXECNAME */ 6158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_type = VKI_AT_SUN_EXECNAME; 6168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_un.a_ptr = copy_str(&strtab, resolved_exe_name); 6178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv++; 6188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_PHDR */ 620358f27ccb54ef77fbd0d6e199b4b5431dfb1b465iraisr if ((info->real_phdr_present) && (info->phdr != 0)) { 6218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_type = VKI_AT_PHDR; 6228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_un.a_val = info->phdr; 6238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv++; 6248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 6258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_BASE */ 6278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_type = VKI_AT_BASE; 6288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_un.a_val = info->interp_offset; 6298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv++; 6308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 631a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes /* AT_ENTRY */ 632a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes auxv->a_type = VKI_AT_ENTRY; 633a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes auxv->a_un.a_val = info->entry; 634a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes auxv++; 635a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 6368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_FLAGS */ 6378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_type = VKI_AT_FLAGS; 6388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# if defined(VGA_x86) || defined(VGA_amd64) 6398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_un.a_val = 0; /* 0 on i86pc */ 6408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# else 6418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# error "Unknown architecture" 6428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# endif 6438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv++; 6448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_PAGESZ */ 6468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_type = VKI_AT_PAGESZ; 6478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_un.a_val = VKI_PAGE_SIZE; 6488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv++; 6498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_SUN_AUXFLAFGS */ 6518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_type = VKI_AT_SUN_AUXFLAGS; 6528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* XXX Handle AF_SUN_SETUGID? */ 6538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_un.a_val = VKI_AF_SUN_HWCAPVERIFY; 6548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv++; 6558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_SUN_HWCAP */ 6578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj { 6588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VexArch vex_arch; 6598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VexArchInfo vex_archinfo; 6608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj UInt hwcaps; 6618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(machine_get_VexArchInfo)(&vex_arch, &vex_archinfo); 6638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# if defined(VGA_x86) 6658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(vex_arch == VexArchX86); 6668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Set default hwcaps. */ 6688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps = 6698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_FPU /* x87-style floating point */ 6708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_TSC /* rdtsc insn */ 6718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_CX8 /* cmpxchg8b insn */ 6728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_SEP /* sysenter and sysexit */ 6738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_AMD_SYSC /* AMD's syscall and sysret */ 6748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_CMOV /* conditional move insns */ 6758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_MMX /* MMX insn */ 6768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_AHF; /* lahf/sahf insns */ 6778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Handle additional hwcaps. */ 6798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE1) 6808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps |= 6818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_FXSR /* fxsave and fxrstor */ 6828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_SSE; /* SSE insns and regs */ 6838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE2) { 6848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE1); 6858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps |= 6868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_SSE2; /* SSE2 insns and regs */ 6878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 6888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE3) { 6898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(vex_archinfo.hwcaps & VEX_HWCAPS_X86_SSE2); 6908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps |= 6918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_SSE3 /* SSE3 insns and regs */ 6928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_SSSE3; /* Intel SSSE3 insns */ 6938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 6948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (vex_archinfo.hwcaps & VEX_HWCAPS_X86_LZCNT) 6958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps |= 6968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_AMD_LZCNT; /* AMD's LZCNT insn */ 6978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 6988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* No support for: 6998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_MMX AMD's MMX insns 7008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_3DNow AMD's 3Dnow! insns 7018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_3DNowx AMD's 3Dnow! extended insns 7028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_CX16 cmpxchg16b insn 7038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_TSCP rdtscp instruction 7048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_SSE4A AMD's SSE4A insns 7058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_POPCNT POPCNT insn 7068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_SSE4_1 Intel SSE4.1 insns 7078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_SSE4_2 Intel SSE4.2 insns 7088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_MOVBE Intel MOVBE insns 7098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AES Intel AES insns 7108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_PCLMULQDQ Intel PCLMULQDQ insn 7118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_XSAVE Intel XSAVE/XRSTOR insns 7128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AVX Intel AVX insns 7138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj illumos only: 7148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_VMX Intel VMX support 7158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_SVM AMD SVM support 7168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj solaris only: 7178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_XOP AMD XOP insns 7188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_FMA4 AMD FMA4 insns */ 7198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# elif defined(VGA_amd64) 7218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(vex_arch == VexArchAMD64); 7228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Set default hwcaps. */ 7248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps = 7258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_FPU /* x87-style floating point */ 7268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_TSC /* rdtsc insn */ 7278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_CX8 /* cmpxchg8b insn */ 7288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_AMD_SYSC /* AMD's syscall and sysret */ 7298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_CMOV /* conditional move insns */ 7308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_MMX /* MMX insn */ 7318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_AHF /* lahf/sahf insns */ 7328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_FXSR /* fxsave and fxrstor */ 7338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_SSE /* SSE insns and regs */ 7348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_SSE2; /* SSE2 insns and regs */ 7358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Handle additional hwcaps. */ 7378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3) 7388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps |= 7398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_SSE3 /* SSE3 insns and regs */ 7408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_SSSE3; /* Intel SSSE3 insns */ 7418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16) 7428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps |= 7438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_CX16; /* cmpxchg16b insn */ 7448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_LZCNT) 7458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps |= 7468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_AMD_LZCNT; /* AMD's LZCNT insn */ 7478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_RDTSCP) 7488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps |= 7498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_TSCP; /* rdtscp instruction */ 7508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if ((vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3) && 7518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16)) { 7528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The CPUID simulation provided by VEX claims to have POPCNT, AES 7538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj and SSE4 (SSE4.1/SSE4.2) in the SSE3+CX16 configuration. */ 7548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps |= 7558eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_POPCNT /* POPCNT insn */ 7568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_AES /* Intel AES insns */ 7578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_SSE4_1 /* Intel SSE4.1 insns */ 7588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_SSE4_2; /* Intel SSE4.2 insns */ 7598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 7608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if ((vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_SSE3) && 7618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_CX16) && 7628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (vex_archinfo.hwcaps & VEX_HWCAPS_AMD64_AVX)) { 7638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The CPUID simulation provided by VEX claims to have PCLMULQDQ and 7648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj XSAVE in the SSE3+CX16+AVX configuration. */ 7658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj hwcaps |= 7668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VKI_AV_386_PCLMULQDQ /* Intel PCLMULQDQ insn */ 7678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj | VKI_AV_386_XSAVE; /* Intel XSAVE/XRSTOR insns */ 7688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 7698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* No support for: 7708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_SEP sysenter and sysexit 7718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_MMX AMD's MMX insns 7728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_3DNow AMD's 3Dnow! insns 7738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_3DNowx AMD's 3Dnow! extended insns 7748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_SSE4A AMD's SSE4A insns 7758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_MOVBE Intel MOVBE insns 7768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AVX Intel AVX insns 7778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj illumos only: 7788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_VMX Intel VMX support 7798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_SVM AMD SVM support 7808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj solaris only: 7818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_XOP AMD XOP insns 7828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_AMD_FMA4 AMD FMA4 insns 7838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj TODO VEX supports AVX, BMI and AVX2. Investigate if they can be 7858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj enabled on Solaris/illumos. 7868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj */ 7878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# else 7898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# error "Unknown architecture" 7908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# endif 7918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_type = VKI_AT_SUN_HWCAP; 7938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_un.a_val = hwcaps; 7948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv++; 7958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 7968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 7978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_SUN_HWCAP2 */ 7988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj { 7998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* No support for: 8008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj illumos only: 8018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_2_F16C F16C half percision extensions 8028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV_386_2_RDRAND RDRAND insn 8038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj solaris only: 8048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_RDRAND Intel RDRAND insns 8058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_FMA Intel FMA insn 8068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_F16C IEEE half precn(float) insn 8078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_AMD_TBM AMD TBM insn 8088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_BMI1 Intel BMI1 insn 8098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_FSGSBASE Intel RD/WR FS/GSBASE insn 8108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_AVX2 Intel AVX2 insns 8118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_BMI2 Intel BMI2 insns 8128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_HLE Intel HLE insns 8138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_RTM Intel RTM insns 8148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_EFS Intel Enhanced Fast String 8158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_RDSEED Intel RDSEED insn 8168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_ADX Intel ADX insns 8178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj AV2_386_PRFCHW Intel PREFETCHW hint 8188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj */ 8198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 821e03654002556aa3ece73c344ec8c8cbe15754df1iraisr# if defined(SOLARIS_RESERVE_SYSSTAT_ADDR) 822e03654002556aa3ece73c344ec8c8cbe15754df1iraisr /* AT_SUN_SYSSTAT_ADDR */ 823e03654002556aa3ece73c344ec8c8cbe15754df1iraisr copy_auxv_entry(orig_auxv, VKI_AT_SUN_SYSSTAT_ADDR, 824e03654002556aa3ece73c344ec8c8cbe15754df1iraisr "AT_SUN_SYSSTAT_ADDR", auxv); 825e03654002556aa3ece73c344ec8c8cbe15754df1iraisr VG_(change_mapping_ownership)(auxv->a_un.a_val, True); 826e03654002556aa3ece73c344ec8c8cbe15754df1iraisr auxv++; 827e03654002556aa3ece73c344ec8c8cbe15754df1iraisr# endif 828e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 829e03654002556aa3ece73c344ec8c8cbe15754df1iraisr# if defined(SOLARIS_RESERVE_SYSSTAT_ZONE_ADDR) 830e03654002556aa3ece73c344ec8c8cbe15754df1iraisr /* AT_SUN_SYSSTAT_ZONE_ADDR */ 831e03654002556aa3ece73c344ec8c8cbe15754df1iraisr copy_auxv_entry(orig_auxv, VKI_AT_SUN_SYSSTAT_ZONE_ADDR, 832e03654002556aa3ece73c344ec8c8cbe15754df1iraisr "AT_SUN_SYSSTAT_ZONE_ADDR", auxv); 833e03654002556aa3ece73c344ec8c8cbe15754df1iraisr VG_(change_mapping_ownership)(auxv->a_un.a_val, True); 834e03654002556aa3ece73c344ec8c8cbe15754df1iraisr auxv++; 835e03654002556aa3ece73c344ec8c8cbe15754df1iraisr# endif 836e03654002556aa3ece73c344ec8c8cbe15754df1iraisr 8378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* AT_NULL */ 8388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_type = VKI_AT_NULL; 8398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj auxv->a_un.a_val = 0; 8408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(strtab - stringbase == stringsize); 8428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* The variable client_SP is now pointing at client's argc/argv. */ 8448eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8458eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (0) 8468eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(printf)("startup SP = %#lx\n", client_SP); 8478eb8bab992e3998c33770b0cdb16059a8b918a06sewardj return client_SP; 8488eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 8498eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8508eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*====================================================================*/ 8518eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*=== TOP-LEVEL: VG_(setup_client_initial_image) ===*/ 8528eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*====================================================================*/ 8538eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8548eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Create the client's initial memory image. */ 8558eb8bab992e3998c33770b0cdb16059a8b918a06sewardjIIFinaliseImageInfo VG_(ii_create_image)(IICreateImageInfo iicii, 8568eb8bab992e3998c33770b0cdb16059a8b918a06sewardj const VexArchInfo *vex_archinfo) 8578eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 8588eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ExeInfo info; 8598eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar **env = NULL; 8608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj HChar resolved_exe_name[VKI_PATH_MAX]; 8618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj IIFinaliseImageInfo iifii; 8638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(memset)(&iifii, 0, sizeof(iifii)); 8648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj //-------------------------------------------------------------- 8668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj // Load client executable, finding in $PATH if necessary 8678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj // p: early_process_cmd_line_options() [for 'exec', 'need_help'] 8688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj // p: layout_remaining_space [so there's space] 8698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj //-------------------------------------------------------------- 8708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(debugLog)(1, "initimg", "Loading client\n"); 8718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (!VG_(args_the_exename)) { 8738eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(err_missing_prog)(); 8748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /*NOTREACHED*/ 8758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 8768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj load_client(&info, resolved_exe_name, sizeof(resolved_exe_name)); 8788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj iifii.initial_client_IP = info.init_ip; 8798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Note: TOC isn't available on Solaris. */ 8808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj iifii.initial_client_TOC = info.init_toc; 8818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj iifii.initial_client_TP = info.init_thrptr; 8828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Note that iifii.client_auxv is never set on Solaris, because it isn't 8838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj necessary to have this value in VG_(ii_finalise_image). */ 8848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj //-------------------------------------------------------------- 8868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj // Set up client's environment 8878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj // p: set-libdir [for VG_(libdir)] 8888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj // p: early_process_cmd_line_options() [for toolname] 8898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj //-------------------------------------------------------------- 8908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(debugLog)(1, "initimg", "Setup client env\n"); 8918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj env = setup_client_env(iicii.envp, iicii.toolname); 8928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 8938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj //-------------------------------------------------------------- 8948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj // Setup client stack and EIP 8958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj // p: load_client() [for 'info'] 8968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj // p: fix_environment() [for 'env'] 8978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj //-------------------------------------------------------------- 8988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj { 8998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* When allocating space for the client stack, take notice of the 9008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj --main-stacksize value. This makes it possible to run programs with 9018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj very large (primary) stack requirements simply by specifying 9028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj --main-stacksize. */ 9038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Logic is as follows: 9048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj - By default, use the client's current stack rlimit. 9058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj - If that exceeds 16M, clamp to 16M. 9068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj - If a larger --main-stacksize value is specified, use that instead. 9078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj - In all situations, the minimum allowed stack size is 1M. 9088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj */ 909e03654002556aa3ece73c344ec8c8cbe15754df1iraisr Addr init_sp = (Addr) (iicii.argv - 1); 9108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT m1 = 1024 * 1024; 9118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT m16 = 16 * m1; 9128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj SizeT szB = (SizeT)VG_(client_rlimit_stack).rlim_cur; 9138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (szB < m1) 9148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj szB = m1; 9158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (szB > m16) 9168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj szB = m16; 9178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (VG_(clo_main_stacksize) > 0) 9198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj szB = VG_(clo_main_stacksize); 9208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj if (szB < m1) 9218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj szB = m1; 9228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj szB = VG_PGROUNDUP(szB); 9248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(debugLog)(1, "initimg", 9258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "Setup client stack: size will be %ld\n", szB); 9268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj iifii.clstack_max_size = szB; 9288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj iifii.initial_client_SP = setup_client_stack(init_sp, env, &info, 9298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj iicii.clstack_end, 9308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj iifii.clstack_max_size, 9318eb8bab992e3998c33770b0cdb16059a8b918a06sewardj resolved_exe_name); 9328eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(free)(env); 9338eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9348eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(debugLog)(2, "initimg", "Client info: " 9358eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "initial_IP=%#lx, initial_TOC=%#lx, brk_base=%#lx\n", 9368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj iifii.initial_client_IP, iifii.initial_client_TOC, 9378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(brk_base)); 9388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(debugLog)(2, "initimg", "Client info: " 9398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj "initial_SP=%#lx, max_stack_size=%lu\n", 9408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj iifii.initial_client_SP, 9418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj iifii.clstack_max_size); 9428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 9438eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 944bcfaeedb1e1ac2625eea81951a785a777834321ciraisr if (info.ldsoexec) { 945bcfaeedb1e1ac2625eea81951a785a777834321ciraisr /* We are executing the runtime linker itself. 946bcfaeedb1e1ac2625eea81951a785a777834321ciraisr Initial data (brk) segment is setup on demand, after the target dynamic 947bcfaeedb1e1ac2625eea81951a785a777834321ciraisr executable has been loaded or when a first brk() syscall is made. 948bcfaeedb1e1ac2625eea81951a785a777834321ciraisr It cannot be established now because it would conflict with a temporary 949bcfaeedb1e1ac2625eea81951a785a777834321ciraisr stack which ld.so.1 (when executed directly) uses for loading the 950bcfaeedb1e1ac2625eea81951a785a777834321ciraisr target dynamic executable. See PRE(sys_brk) in syswrap-solaris.c. */ 951bcfaeedb1e1ac2625eea81951a785a777834321ciraisr } else { 952bcfaeedb1e1ac2625eea81951a785a777834321ciraisr if (!VG_(setup_client_dataseg)()) { 953bcfaeedb1e1ac2625eea81951a785a777834321ciraisr VG_(printf)("valgrind: cannot initialize data segment (brk).\n"); 954bcfaeedb1e1ac2625eea81951a785a777834321ciraisr VG_(exit)(1); 955bcfaeedb1e1ac2625eea81951a785a777834321ciraisr } 956bcfaeedb1e1ac2625eea81951a785a777834321ciraisr } 957bcfaeedb1e1ac2625eea81951a785a777834321ciraisr 958a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(free)(info.interp_name); 959a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(free)(info.interp_args); 9608eb8bab992e3998c33770b0cdb16059a8b918a06sewardj return iifii; 9618eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 9628eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9638eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9648eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*====================================================================*/ 9658eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*=== TOP-LEVEL: VG_(finalise_image) ===*/ 9668eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*====================================================================*/ 9678eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9688eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/* Just before starting the client, we may need to make final adjustments to 9698eb8bab992e3998c33770b0cdb16059a8b918a06sewardj its initial image. Also we need to set up the VEX guest state for thread 1 9708eb8bab992e3998c33770b0cdb16059a8b918a06sewardj (the root thread) and copy in essential starting values. This is handed 9718eb8bab992e3998c33770b0cdb16059a8b918a06sewardj the IIFinaliseImageInfo created by VG_(ii_create_image). 9728eb8bab992e3998c33770b0cdb16059a8b918a06sewardj*/ 9738eb8bab992e3998c33770b0cdb16059a8b918a06sewardjvoid VG_(ii_finalise_image)(IIFinaliseImageInfo iifii) 9748eb8bab992e3998c33770b0cdb16059a8b918a06sewardj{ 9758eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ThreadArchState *arch = &VG_(threads)[1].arch; 9768eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9778eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# if defined(VGA_x86) 9788eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(0 == sizeof(VexGuestX86State) % LibVEX_GUEST_STATE_ALIGN); 9798eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9808eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Zero out the initial state, and set up the simulated FPU in a sane 9818eb8bab992e3998c33770b0cdb16059a8b918a06sewardj way. */ 9828eb8bab992e3998c33770b0cdb16059a8b918a06sewardj LibVEX_GuestX86_initialise(&arch->vex); 9838eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9848eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Zero out the shadow areas. */ 9858eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State)); 9868eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State)); 9878eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9888eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Put essential stuff into the new state. */ 9898eb8bab992e3998c33770b0cdb16059a8b918a06sewardj arch->vex.guest_ESP = iifii.initial_client_SP; 9908eb8bab992e3998c33770b0cdb16059a8b918a06sewardj arch->vex.guest_EIP = iifii.initial_client_IP; 9918eb8bab992e3998c33770b0cdb16059a8b918a06sewardj LibVEX_GuestX86_put_eflags(VKI_PSL_USER, &arch->vex); 9928eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9938eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Set %cs, %ds, %ss and %es to default values. */ 9948eb8bab992e3998c33770b0cdb16059a8b918a06sewardj __asm__ __volatile__ ("movw %%cs, %[cs]" : [cs] "=m" (arch->vex.guest_CS)); 9958eb8bab992e3998c33770b0cdb16059a8b918a06sewardj __asm__ __volatile__ ("movw %%ds, %[ds]" : [ds] "=m" (arch->vex.guest_DS)); 9968eb8bab992e3998c33770b0cdb16059a8b918a06sewardj __asm__ __volatile__ ("movw %%ss, %[ss]" : [ss] "=m" (arch->vex.guest_SS)); 9978eb8bab992e3998c33770b0cdb16059a8b918a06sewardj __asm__ __volatile__ ("movw %%es, %[es]" : [es] "=m" (arch->vex.guest_ES)); 9988eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 9998eb8bab992e3998c33770b0cdb16059a8b918a06sewardj { 10008eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Initial thread pointer value will be saved in GDT when the thread is 10018eb8bab992e3998c33770b0cdb16059a8b918a06sewardj started in the syswrap module and a thread's GDT is allocated. */ 10028eb8bab992e3998c33770b0cdb16059a8b918a06sewardj ThreadOSstate *os = &VG_(threads)[1].os_state; 10038eb8bab992e3998c33770b0cdb16059a8b918a06sewardj os->thrptr = iifii.initial_client_TP; 10048eb8bab992e3998c33770b0cdb16059a8b918a06sewardj } 10058eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 10068eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# elif defined(VGA_amd64) 10078eb8bab992e3998c33770b0cdb16059a8b918a06sewardj vg_assert(0 == sizeof(VexGuestAMD64State) % LibVEX_GUEST_STATE_ALIGN); 10088eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 10098eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Zero out the initial state, and set up the simulated FPU in a sane 10108eb8bab992e3998c33770b0cdb16059a8b918a06sewardj way. */ 10118eb8bab992e3998c33770b0cdb16059a8b918a06sewardj LibVEX_GuestAMD64_initialise(&arch->vex); 10128eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 10138eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Zero out the shadow areas. */ 10148eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestAMD64State)); 10158eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State)); 10168eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 10178eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Put essential stuff into the new state. */ 10188eb8bab992e3998c33770b0cdb16059a8b918a06sewardj arch->vex.guest_RSP = iifii.initial_client_SP; 10198eb8bab992e3998c33770b0cdb16059a8b918a06sewardj arch->vex.guest_RIP = iifii.initial_client_IP; 10208eb8bab992e3998c33770b0cdb16059a8b918a06sewardj arch->vex.guest_FS_CONST = iifii.initial_client_TP; 10218eb8bab992e3998c33770b0cdb16059a8b918a06sewardj LibVEX_GuestAMD64_put_rflags(VKI_PSL_USER, &arch->vex); 10228eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 10238eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# else 10248eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# error "Unknown platform" 10258eb8bab992e3998c33770b0cdb16059a8b918a06sewardj# endif 10268eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 10278eb8bab992e3998c33770b0cdb16059a8b918a06sewardj /* Tell the tool that we just wrote to the registers. */ 10288eb8bab992e3998c33770b0cdb16059a8b918a06sewardj VG_TRACK(post_reg_write, Vg_CoreStartup, 1/*tid*/, 0/*offset*/, 10298eb8bab992e3998c33770b0cdb16059a8b918a06sewardj sizeof(VexGuestArchState)); 10308eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 1031bcfaeedb1e1ac2625eea81951a785a777834321ciraisr if (VG_(brk_base) != -1 ) { 1032bcfaeedb1e1ac2625eea81951a785a777834321ciraisr /* Make inaccessible/unaddressable the end of the client data segment. 1033bcfaeedb1e1ac2625eea81951a785a777834321ciraisr See PRE(sys_brk) in syswrap-solaris.c for details. */ 1034bcfaeedb1e1ac2625eea81951a785a777834321ciraisr VG_(track_client_dataseg)(1 /* tid */); 10351c628f3016f3437eda3294da1df7fcedef96d1d9iraisr } 10368eb8bab992e3998c33770b0cdb16059a8b918a06sewardj} 10378eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 10388eb8bab992e3998c33770b0cdb16059a8b918a06sewardj#endif // defined(VGO_solaris) 10398eb8bab992e3998c33770b0cdb16059a8b918a06sewardj 10408eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--------------------------------------------------------------------*/ 10418eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--- ---*/ 10428eb8bab992e3998c33770b0cdb16059a8b918a06sewardj/*--------------------------------------------------------------------*/ 1043