117c110443e39c0c63bb298689cad31e0b4671dfesewardj 217c110443e39c0c63bb298689cad31e0b4671dfesewardj/*--------------------------------------------------------------------*/ 317c110443e39c0c63bb298689cad31e0b4671dfesewardj/*--- Startup: create initial process image on Linux ---*/ 417c110443e39c0c63bb298689cad31e0b4671dfesewardj/*--- initimg-linux.c ---*/ 517c110443e39c0c63bb298689cad31e0b4671dfesewardj/*--------------------------------------------------------------------*/ 617c110443e39c0c63bb298689cad31e0b4671dfesewardj 717c110443e39c0c63bb298689cad31e0b4671dfesewardj/* 817c110443e39c0c63bb298689cad31e0b4671dfesewardj This file is part of Valgrind, a dynamic binary instrumentation 917c110443e39c0c63bb298689cad31e0b4671dfesewardj framework. 1017c110443e39c0c63bb298689cad31e0b4671dfesewardj 11ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes Copyright (C) 2000-2017 Julian Seward 1217c110443e39c0c63bb298689cad31e0b4671dfesewardj jseward@acm.org 1317c110443e39c0c63bb298689cad31e0b4671dfesewardj 1417c110443e39c0c63bb298689cad31e0b4671dfesewardj This program is free software; you can redistribute it and/or 1517c110443e39c0c63bb298689cad31e0b4671dfesewardj modify it under the terms of the GNU General Public License as 1617c110443e39c0c63bb298689cad31e0b4671dfesewardj published by the Free Software Foundation; either version 2 of the 1717c110443e39c0c63bb298689cad31e0b4671dfesewardj License, or (at your option) any later version. 1817c110443e39c0c63bb298689cad31e0b4671dfesewardj 1917c110443e39c0c63bb298689cad31e0b4671dfesewardj This program is distributed in the hope that it will be useful, but 2017c110443e39c0c63bb298689cad31e0b4671dfesewardj WITHOUT ANY WARRANTY; without even the implied warranty of 2117c110443e39c0c63bb298689cad31e0b4671dfesewardj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 2217c110443e39c0c63bb298689cad31e0b4671dfesewardj General Public License for more details. 2317c110443e39c0c63bb298689cad31e0b4671dfesewardj 2417c110443e39c0c63bb298689cad31e0b4671dfesewardj You should have received a copy of the GNU General Public License 2517c110443e39c0c63bb298689cad31e0b4671dfesewardj along with this program; if not, write to the Free Software 2617c110443e39c0c63bb298689cad31e0b4671dfesewardj Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 2717c110443e39c0c63bb298689cad31e0b4671dfesewardj 02111-1307, USA. 2817c110443e39c0c63bb298689cad31e0b4671dfesewardj 2917c110443e39c0c63bb298689cad31e0b4671dfesewardj The GNU General Public License is contained in the file COPYING. 3017c110443e39c0c63bb298689cad31e0b4671dfesewardj*/ 3117c110443e39c0c63bb298689cad31e0b4671dfesewardj 328b68b64759254d514d98328c496cbd88cde4c9a5njn#if defined(VGO_linux) 338b68b64759254d514d98328c496cbd88cde4c9a5njn 3417c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_basics.h" 3517c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_vki.h" 3617c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_debuglog.h" 3717c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_libcbase.h" 3817c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_libcassert.h" 3917c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_libcfile.h" 4017c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_libcproc.h" 4117c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_libcprint.h" 4214c7cc5a5fbe9526329f058116f921988efe679esewardj#include "pub_core_xarray.h" 4317c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_clientstate.h" 4417c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_aspacemgr.h" 4517c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_mallocfree.h" 4617c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_machine.h" 4717c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_ume.h" 4817c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_options.h" 49d5c3f2839495d785ccf8e70c060eb2671507c192sewardj#include "pub_core_syscall.h" 5017c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_tooliface.h" /* VG_TRACK */ 5117c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_threadstate.h" /* ThreadArchState */ 5263ae69a7464f3cb383ea0b079f6ae5a8622a2c8fnjn#include "priv_initimg_pathscan.h" 5317c110443e39c0c63bb298689cad31e0b4671dfesewardj#include "pub_core_initimg.h" /* self */ 5417c110443e39c0c63bb298689cad31e0b4671dfesewardj 5517c110443e39c0c63bb298689cad31e0b4671dfesewardj/* --- !!! --- EXTERNAL HEADERS start --- !!! --- */ 5617c110443e39c0c63bb298689cad31e0b4671dfesewardj#define _GNU_SOURCE 5717c110443e39c0c63bb298689cad31e0b4671dfesewardj#define _FILE_OFFSET_BITS 64 5817c110443e39c0c63bb298689cad31e0b4671dfesewardj/* This is for ELF types etc, and also the AT_ constants. */ 5917c110443e39c0c63bb298689cad31e0b4671dfesewardj#include <elf.h> 6017c110443e39c0c63bb298689cad31e0b4671dfesewardj/* --- !!! --- EXTERNAL HEADERS end --- !!! --- */ 6117c110443e39c0c63bb298689cad31e0b4671dfesewardj 6217c110443e39c0c63bb298689cad31e0b4671dfesewardj 6317c110443e39c0c63bb298689cad31e0b4671dfesewardj/*====================================================================*/ 6417c110443e39c0c63bb298689cad31e0b4671dfesewardj/*=== Loading the client ===*/ 6517c110443e39c0c63bb298689cad31e0b4671dfesewardj/*====================================================================*/ 6617c110443e39c0c63bb298689cad31e0b4671dfesewardj 6717c110443e39c0c63bb298689cad31e0b4671dfesewardj/* Load the client whose name is VG_(argv_the_exename). */ 6817c110443e39c0c63bb298689cad31e0b4671dfesewardj 69a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughesstatic void load_client ( /*MOD*/ExeInfo* info, 7017c110443e39c0c63bb298689cad31e0b4671dfesewardj /*OUT*/Addr* client_ip, 7117c110443e39c0c63bb298689cad31e0b4671dfesewardj /*OUT*/Addr* client_toc) 7217c110443e39c0c63bb298689cad31e0b4671dfesewardj{ 73c8b821428c9a8e63a6d055211963eae6eccc41c0florian const HChar* exe_name; 7417c110443e39c0c63bb298689cad31e0b4671dfesewardj Int ret; 7517c110443e39c0c63bb298689cad31e0b4671dfesewardj SysRes res; 7617c110443e39c0c63bb298689cad31e0b4671dfesewardj 7717c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert( VG_(args_the_exename) != NULL); 7863ae69a7464f3cb383ea0b079f6ae5a8622a2c8fnjn exe_name = ML_(find_executable)( VG_(args_the_exename) ); 7917c110443e39c0c63bb298689cad31e0b4671dfesewardj 8017c110443e39c0c63bb298689cad31e0b4671dfesewardj if (!exe_name) { 8117c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(printf)("valgrind: %s: command not found\n", VG_(args_the_exename)); 8217c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(exit)(127); // 127 is Posix NOTFOUND 8317c110443e39c0c63bb298689cad31e0b4671dfesewardj } 8417c110443e39c0c63bb298689cad31e0b4671dfesewardj 8517c110443e39c0c63bb298689cad31e0b4671dfesewardj ret = VG_(do_exec)(exe_name, info); 864c245e595b9f6300d3120408ca873f7115d9cc7dnjn if (ret < 0) { 874c245e595b9f6300d3120408ca873f7115d9cc7dnjn VG_(printf)("valgrind: could not execute '%s'\n", exe_name); 884c245e595b9f6300d3120408ca873f7115d9cc7dnjn VG_(exit)(1); 894c245e595b9f6300d3120408ca873f7115d9cc7dnjn } 9017c110443e39c0c63bb298689cad31e0b4671dfesewardj 9117c110443e39c0c63bb298689cad31e0b4671dfesewardj // The client was successfully loaded! Continue. 9217c110443e39c0c63bb298689cad31e0b4671dfesewardj 9317c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Get hold of a file descriptor which refers to the client 9417c110443e39c0c63bb298689cad31e0b4671dfesewardj executable. This is needed for attaching to GDB. */ 9517c110443e39c0c63bb298689cad31e0b4671dfesewardj res = VG_(open)(exe_name, VKI_O_RDONLY, VKI_S_IRUSR); 96cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if (!sr_isError(res)) 97cda2f0fbda4c4b2644babc830244be8aed95de1dnjn VG_(cl_exec_fd) = sr_Res(res); 9817c110443e39c0c63bb298689cad31e0b4671dfesewardj 9917c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Copy necessary bits of 'info' that were filled in */ 10017c110443e39c0c63bb298689cad31e0b4671dfesewardj *client_ip = info->init_ip; 10117c110443e39c0c63bb298689cad31e0b4671dfesewardj *client_toc = info->init_toc; 10217c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(brk_base) = VG_(brk_limit) = VG_PGROUNDUP(info->brkbase); 10317c110443e39c0c63bb298689cad31e0b4671dfesewardj} 10417c110443e39c0c63bb298689cad31e0b4671dfesewardj 10517c110443e39c0c63bb298689cad31e0b4671dfesewardj 10617c110443e39c0c63bb298689cad31e0b4671dfesewardj/*====================================================================*/ 10717c110443e39c0c63bb298689cad31e0b4671dfesewardj/*=== Setting up the client's environment ===*/ 10817c110443e39c0c63bb298689cad31e0b4671dfesewardj/*====================================================================*/ 10917c110443e39c0c63bb298689cad31e0b4671dfesewardj 11017c110443e39c0c63bb298689cad31e0b4671dfesewardj/* Prepare the client's environment. This is basically a copy of our 11117c110443e39c0c63bb298689cad31e0b4671dfesewardj environment, except: 11217c110443e39c0c63bb298689cad31e0b4671dfesewardj 1136bf365c2d4e55cb109d20e0a8f90dc121bdc003fnjn LD_PRELOAD=$VALGRIND_LIB/vgpreload_core-PLATFORM.so: 1146bf365c2d4e55cb109d20e0a8f90dc121bdc003fnjn ($VALGRIND_LIB/vgpreload_TOOL-PLATFORM.so:)? 11517c110443e39c0c63bb298689cad31e0b4671dfesewardj $LD_PRELOAD 11617c110443e39c0c63bb298689cad31e0b4671dfesewardj 11717c110443e39c0c63bb298689cad31e0b4671dfesewardj If this is missing, then it is added. 11817c110443e39c0c63bb298689cad31e0b4671dfesewardj 11917c110443e39c0c63bb298689cad31e0b4671dfesewardj Also, remove any binding for VALGRIND_LAUNCHER=. The client should 12017c110443e39c0c63bb298689cad31e0b4671dfesewardj not be able to see this. 12117c110443e39c0c63bb298689cad31e0b4671dfesewardj 12217c110443e39c0c63bb298689cad31e0b4671dfesewardj If this needs to handle any more variables it should be hacked 12317c110443e39c0c63bb298689cad31e0b4671dfesewardj into something table driven. The copy is VG_(malloc)'d space. 12417c110443e39c0c63bb298689cad31e0b4671dfesewardj*/ 12517c110443e39c0c63bb298689cad31e0b4671dfesewardjstatic HChar** setup_client_env ( HChar** origenv, const HChar* toolname) 12617c110443e39c0c63bb298689cad31e0b4671dfesewardj{ 12768790a73bcb290746a5b34c44538c3b2728eaaecflorian vg_assert(origenv); 12868790a73bcb290746a5b34c44538c3b2728eaaecflorian vg_assert(toolname); 12968790a73bcb290746a5b34c44538c3b2728eaaecflorian 130c8b821428c9a8e63a6d055211963eae6eccc41c0florian const HChar* preload_core = "vgpreload_core"; 131c8b821428c9a8e63a6d055211963eae6eccc41c0florian const HChar* ld_preload = "LD_PRELOAD="; 132c8b821428c9a8e63a6d055211963eae6eccc41c0florian const HChar* v_launcher = VALGRIND_LAUNCHER "="; 13317c110443e39c0c63bb298689cad31e0b4671dfesewardj Int ld_preload_len = VG_(strlen)( ld_preload ); 13417c110443e39c0c63bb298689cad31e0b4671dfesewardj Int v_launcher_len = VG_(strlen)( v_launcher ); 13517c110443e39c0c63bb298689cad31e0b4671dfesewardj Bool ld_preload_done = False; 13617c110443e39c0c63bb298689cad31e0b4671dfesewardj Int vglib_len = VG_(strlen)(VG_(libdir)); 137e9dd322e97711b2b399b0523163cf7e819425209sewardj Bool debug = False; 13817c110443e39c0c63bb298689cad31e0b4671dfesewardj 13917c110443e39c0c63bb298689cad31e0b4671dfesewardj HChar** cpp; 14017c110443e39c0c63bb298689cad31e0b4671dfesewardj HChar** ret; 14117c110443e39c0c63bb298689cad31e0b4671dfesewardj HChar* preload_tool_path; 14217c110443e39c0c63bb298689cad31e0b4671dfesewardj Int envc, i; 14317c110443e39c0c63bb298689cad31e0b4671dfesewardj 14417c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Alloc space for the vgpreload_core.so path and vgpreload_<tool>.so 14517c110443e39c0c63bb298689cad31e0b4671dfesewardj paths. We might not need the space for vgpreload_<tool>.so, but it 14617c110443e39c0c63bb298689cad31e0b4671dfesewardj doesn't hurt to over-allocate briefly. The 16s are just cautious 14717c110443e39c0c63bb298689cad31e0b4671dfesewardj slop. */ 14817c110443e39c0c63bb298689cad31e0b4671dfesewardj Int preload_core_path_len = vglib_len + sizeof(preload_core) 14917c110443e39c0c63bb298689cad31e0b4671dfesewardj + sizeof(VG_PLATFORM) + 16; 15017c110443e39c0c63bb298689cad31e0b4671dfesewardj Int preload_tool_path_len = vglib_len + VG_(strlen)(toolname) 15117c110443e39c0c63bb298689cad31e0b4671dfesewardj + sizeof(VG_PLATFORM) + 16; 15217c110443e39c0c63bb298689cad31e0b4671dfesewardj Int preload_string_len = preload_core_path_len + preload_tool_path_len; 1539c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj HChar* preload_string = VG_(malloc)("initimg-linux.sce.1", 1549c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj preload_string_len); 1556bf365c2d4e55cb109d20e0a8f90dc121bdc003fnjn /* Determine if there's a vgpreload_<tool>_<platform>.so file, and setup 15617c110443e39c0c63bb298689cad31e0b4671dfesewardj preload_string. */ 1579c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj preload_tool_path = VG_(malloc)("initimg-linux.sce.2", preload_tool_path_len); 15817c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(snprintf)(preload_tool_path, preload_tool_path_len, 1596bf365c2d4e55cb109d20e0a8f90dc121bdc003fnjn "%s/vgpreload_%s-%s.so", VG_(libdir), toolname, VG_PLATFORM); 16017c110443e39c0c63bb298689cad31e0b4671dfesewardj if (VG_(access)(preload_tool_path, True/*r*/, False/*w*/, False/*x*/) == 0) { 1616bf365c2d4e55cb109d20e0a8f90dc121bdc003fnjn VG_(snprintf)(preload_string, preload_string_len, "%s/%s-%s.so:%s", 1626bf365c2d4e55cb109d20e0a8f90dc121bdc003fnjn VG_(libdir), preload_core, VG_PLATFORM, preload_tool_path); 16317c110443e39c0c63bb298689cad31e0b4671dfesewardj } else { 1646bf365c2d4e55cb109d20e0a8f90dc121bdc003fnjn VG_(snprintf)(preload_string, preload_string_len, "%s/%s-%s.so", 1656bf365c2d4e55cb109d20e0a8f90dc121bdc003fnjn VG_(libdir), preload_core, VG_PLATFORM); 16617c110443e39c0c63bb298689cad31e0b4671dfesewardj } 16717c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(free)(preload_tool_path); 16817c110443e39c0c63bb298689cad31e0b4671dfesewardj 16917c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(debugLog)(2, "initimg", "preload_string:\n"); 17017c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(debugLog)(2, "initimg", " \"%s\"\n", preload_string); 17117c110443e39c0c63bb298689cad31e0b4671dfesewardj 17217c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Count the original size of the env */ 173e9dd322e97711b2b399b0523163cf7e819425209sewardj if (debug) VG_(printf)("\n\n"); 17417c110443e39c0c63bb298689cad31e0b4671dfesewardj envc = 0; 175e9dd322e97711b2b399b0523163cf7e819425209sewardj for (cpp = origenv; cpp && *cpp; cpp++) { 17617c110443e39c0c63bb298689cad31e0b4671dfesewardj envc++; 177e9dd322e97711b2b399b0523163cf7e819425209sewardj if (debug) VG_(printf)("XXXXXXXXX: BEFORE %s\n", *cpp); 178e9dd322e97711b2b399b0523163cf7e819425209sewardj } 17917c110443e39c0c63bb298689cad31e0b4671dfesewardj 18017c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Allocate a new space */ 1819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj ret = VG_(malloc) ("initimg-linux.sce.3", 1829c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj sizeof(HChar *) * (envc+1+1)); /* 1 new entry + NULL */ 18317c110443e39c0c63bb298689cad31e0b4671dfesewardj 18417c110443e39c0c63bb298689cad31e0b4671dfesewardj /* copy it over */ 185e9dd322e97711b2b399b0523163cf7e819425209sewardj for (cpp = ret; *origenv; ) { 186e9dd322e97711b2b399b0523163cf7e819425209sewardj if (debug) VG_(printf)("XXXXXXXXX: COPY %s\n", *origenv); 18717c110443e39c0c63bb298689cad31e0b4671dfesewardj *cpp++ = *origenv++; 188e9dd322e97711b2b399b0523163cf7e819425209sewardj } 18917c110443e39c0c63bb298689cad31e0b4671dfesewardj *cpp = NULL; 19017c110443e39c0c63bb298689cad31e0b4671dfesewardj 19117c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(envc == (cpp - ret)); 19217c110443e39c0c63bb298689cad31e0b4671dfesewardj 19317c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Walk over the new environment, mashing as we go */ 19417c110443e39c0c63bb298689cad31e0b4671dfesewardj for (cpp = ret; cpp && *cpp; cpp++) { 19517c110443e39c0c63bb298689cad31e0b4671dfesewardj if (VG_(memcmp)(*cpp, ld_preload, ld_preload_len) == 0) { 19617c110443e39c0c63bb298689cad31e0b4671dfesewardj Int len = VG_(strlen)(*cpp) + preload_string_len; 1979c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj HChar *cp = VG_(malloc)("initimg-linux.sce.4", len); 19817c110443e39c0c63bb298689cad31e0b4671dfesewardj 19917c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(snprintf)(cp, len, "%s%s:%s", 20017c110443e39c0c63bb298689cad31e0b4671dfesewardj ld_preload, preload_string, (*cpp)+ld_preload_len); 20117c110443e39c0c63bb298689cad31e0b4671dfesewardj 20217c110443e39c0c63bb298689cad31e0b4671dfesewardj *cpp = cp; 20317c110443e39c0c63bb298689cad31e0b4671dfesewardj 20417c110443e39c0c63bb298689cad31e0b4671dfesewardj ld_preload_done = True; 20517c110443e39c0c63bb298689cad31e0b4671dfesewardj } 206e9dd322e97711b2b399b0523163cf7e819425209sewardj if (debug) VG_(printf)("XXXXXXXXX: MASH %s\n", *cpp); 20717c110443e39c0c63bb298689cad31e0b4671dfesewardj } 20817c110443e39c0c63bb298689cad31e0b4671dfesewardj 20917c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Add the missing bits */ 21017c110443e39c0c63bb298689cad31e0b4671dfesewardj if (!ld_preload_done) { 21117c110443e39c0c63bb298689cad31e0b4671dfesewardj Int len = ld_preload_len + preload_string_len; 2129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj HChar *cp = VG_(malloc) ("initimg-linux.sce.5", len); 21317c110443e39c0c63bb298689cad31e0b4671dfesewardj 21417c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(snprintf)(cp, len, "%s%s", ld_preload, preload_string); 21517c110443e39c0c63bb298689cad31e0b4671dfesewardj 21617c110443e39c0c63bb298689cad31e0b4671dfesewardj ret[envc++] = cp; 217e9dd322e97711b2b399b0523163cf7e819425209sewardj if (debug) VG_(printf)("XXXXXXXXX: ADD %s\n", cp); 21817c110443e39c0c63bb298689cad31e0b4671dfesewardj } 21917c110443e39c0c63bb298689cad31e0b4671dfesewardj 22017c110443e39c0c63bb298689cad31e0b4671dfesewardj /* ret[0 .. envc-1] is live now. */ 22117c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Find and remove a binding for VALGRIND_LAUNCHER. */ 22217c110443e39c0c63bb298689cad31e0b4671dfesewardj for (i = 0; i < envc; i++) 223a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (0 == VG_(memcmp)(ret[i], v_launcher, v_launcher_len)) 22417c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 22517c110443e39c0c63bb298689cad31e0b4671dfesewardj 22617c110443e39c0c63bb298689cad31e0b4671dfesewardj if (i < envc) { 22717c110443e39c0c63bb298689cad31e0b4671dfesewardj for (; i < envc-1; i++) 22817c110443e39c0c63bb298689cad31e0b4671dfesewardj ret[i] = ret[i+1]; 22917c110443e39c0c63bb298689cad31e0b4671dfesewardj envc--; 23017c110443e39c0c63bb298689cad31e0b4671dfesewardj } 23117c110443e39c0c63bb298689cad31e0b4671dfesewardj 23217c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(free)(preload_string); 23317c110443e39c0c63bb298689cad31e0b4671dfesewardj ret[envc] = NULL; 23417c110443e39c0c63bb298689cad31e0b4671dfesewardj 235e9dd322e97711b2b399b0523163cf7e819425209sewardj for (i = 0; i < envc; i++) { 236e9dd322e97711b2b399b0523163cf7e819425209sewardj if (debug) VG_(printf)("XXXXXXXXX: FINAL %s\n", ret[i]); 237e9dd322e97711b2b399b0523163cf7e819425209sewardj } 238e9dd322e97711b2b399b0523163cf7e819425209sewardj 23917c110443e39c0c63bb298689cad31e0b4671dfesewardj return ret; 24017c110443e39c0c63bb298689cad31e0b4671dfesewardj} 24117c110443e39c0c63bb298689cad31e0b4671dfesewardj 24217c110443e39c0c63bb298689cad31e0b4671dfesewardj 24317c110443e39c0c63bb298689cad31e0b4671dfesewardj/*====================================================================*/ 24417c110443e39c0c63bb298689cad31e0b4671dfesewardj/*=== Setting up the client's stack ===*/ 24517c110443e39c0c63bb298689cad31e0b4671dfesewardj/*====================================================================*/ 24617c110443e39c0c63bb298689cad31e0b4671dfesewardj 24752b284b2fb907204dfae5a067e83eed98ea72dd2carll#ifndef AT_DCACHEBSIZE 24852b284b2fb907204dfae5a067e83eed98ea72dd2carll#define AT_DCACHEBSIZE 19 24952b284b2fb907204dfae5a067e83eed98ea72dd2carll#endif /* AT_DCACHEBSIZE */ 25052b284b2fb907204dfae5a067e83eed98ea72dd2carll 25117c110443e39c0c63bb298689cad31e0b4671dfesewardj#ifndef AT_ICACHEBSIZE 25217c110443e39c0c63bb298689cad31e0b4671dfesewardj#define AT_ICACHEBSIZE 20 25317c110443e39c0c63bb298689cad31e0b4671dfesewardj#endif /* AT_ICACHEBSIZE */ 25417c110443e39c0c63bb298689cad31e0b4671dfesewardj 25517c110443e39c0c63bb298689cad31e0b4671dfesewardj#ifndef AT_UCACHEBSIZE 25617c110443e39c0c63bb298689cad31e0b4671dfesewardj#define AT_UCACHEBSIZE 21 25717c110443e39c0c63bb298689cad31e0b4671dfesewardj#endif /* AT_UCACHEBSIZE */ 25817c110443e39c0c63bb298689cad31e0b4671dfesewardj 259c880930fdabebbe59dd2c1f72f707cf95c796f1etom#ifndef AT_BASE_PLATFORM 260c880930fdabebbe59dd2c1f72f707cf95c796f1etom#define AT_BASE_PLATFORM 24 261c880930fdabebbe59dd2c1f72f707cf95c796f1etom#endif /* AT_BASE_PLATFORM */ 262c880930fdabebbe59dd2c1f72f707cf95c796f1etom 2639c6533d2c47883f9e491a2a388c5503b3bf4c002tom#ifndef AT_RANDOM 2649c6533d2c47883f9e491a2a388c5503b3bf4c002tom#define AT_RANDOM 25 2659c6533d2c47883f9e491a2a388c5503b3bf4c002tom#endif /* AT_RANDOM */ 2669c6533d2c47883f9e491a2a388c5503b3bf4c002tom 26752b284b2fb907204dfae5a067e83eed98ea72dd2carll#ifndef AT_HWCAP2 26852b284b2fb907204dfae5a067e83eed98ea72dd2carll#define AT_HWCAP2 26 26952b284b2fb907204dfae5a067e83eed98ea72dd2carll#endif /* AT_HWCAP2 */ 27052b284b2fb907204dfae5a067e83eed98ea72dd2carll 27120a8a6125459a919a9561f8480b38f78f7c91fe9tom#ifndef AT_EXECFN 27220a8a6125459a919a9561f8480b38f78f7c91fe9tom#define AT_EXECFN 31 27320a8a6125459a919a9561f8480b38f78f7c91fe9tom#endif /* AT_EXECFN */ 27420a8a6125459a919a9561f8480b38f78f7c91fe9tom 27517c110443e39c0c63bb298689cad31e0b4671dfesewardj#ifndef AT_SYSINFO 27617c110443e39c0c63bb298689cad31e0b4671dfesewardj#define AT_SYSINFO 32 27717c110443e39c0c63bb298689cad31e0b4671dfesewardj#endif /* AT_SYSINFO */ 27817c110443e39c0c63bb298689cad31e0b4671dfesewardj 27917c110443e39c0c63bb298689cad31e0b4671dfesewardj#ifndef AT_SYSINFO_EHDR 28017c110443e39c0c63bb298689cad31e0b4671dfesewardj#define AT_SYSINFO_EHDR 33 28117c110443e39c0c63bb298689cad31e0b4671dfesewardj#endif /* AT_SYSINFO_EHDR */ 28217c110443e39c0c63bb298689cad31e0b4671dfesewardj 28317c110443e39c0c63bb298689cad31e0b4671dfesewardj#ifndef AT_SECURE 28417c110443e39c0c63bb298689cad31e0b4671dfesewardj#define AT_SECURE 23 /* secure mode boolean */ 28517c110443e39c0c63bb298689cad31e0b4671dfesewardj#endif /* AT_SECURE */ 28617c110443e39c0c63bb298689cad31e0b4671dfesewardj 28717c110443e39c0c63bb298689cad31e0b4671dfesewardj/* Add a string onto the string table, and return its address */ 288c8b821428c9a8e63a6d055211963eae6eccc41c0florianstatic HChar *copy_str(HChar **tab, const HChar *str) 28917c110443e39c0c63bb298689cad31e0b4671dfesewardj{ 290c8b821428c9a8e63a6d055211963eae6eccc41c0florian HChar *cp = *tab; 291c8b821428c9a8e63a6d055211963eae6eccc41c0florian HChar *orig = cp; 29217c110443e39c0c63bb298689cad31e0b4671dfesewardj 29317c110443e39c0c63bb298689cad31e0b4671dfesewardj while(*str) 29417c110443e39c0c63bb298689cad31e0b4671dfesewardj *cp++ = *str++; 29517c110443e39c0c63bb298689cad31e0b4671dfesewardj *cp++ = '\0'; 29617c110443e39c0c63bb298689cad31e0b4671dfesewardj 29717c110443e39c0c63bb298689cad31e0b4671dfesewardj if (0) 29817c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(printf)("copied %p \"%s\" len %lld\n", orig, orig, (Long)(cp-orig)); 29917c110443e39c0c63bb298689cad31e0b4671dfesewardj 30017c110443e39c0c63bb298689cad31e0b4671dfesewardj *tab = cp; 30117c110443e39c0c63bb298689cad31e0b4671dfesewardj 30217c110443e39c0c63bb298689cad31e0b4671dfesewardj return orig; 30317c110443e39c0c63bb298689cad31e0b4671dfesewardj} 30417c110443e39c0c63bb298689cad31e0b4671dfesewardj 30517c110443e39c0c63bb298689cad31e0b4671dfesewardj 30617c110443e39c0c63bb298689cad31e0b4671dfesewardj/* ---------------------------------------------------------------- 30717c110443e39c0c63bb298689cad31e0b4671dfesewardj 30817c110443e39c0c63bb298689cad31e0b4671dfesewardj This sets up the client's initial stack, containing the args, 30917c110443e39c0c63bb298689cad31e0b4671dfesewardj environment and aux vector. 31017c110443e39c0c63bb298689cad31e0b4671dfesewardj 31117c110443e39c0c63bb298689cad31e0b4671dfesewardj The format of the stack is: 31217c110443e39c0c63bb298689cad31e0b4671dfesewardj 31317c110443e39c0c63bb298689cad31e0b4671dfesewardj higher address +-----------------+ <- clstack_end 31417c110443e39c0c63bb298689cad31e0b4671dfesewardj | | 31517c110443e39c0c63bb298689cad31e0b4671dfesewardj : string table : 31617c110443e39c0c63bb298689cad31e0b4671dfesewardj | | 31717c110443e39c0c63bb298689cad31e0b4671dfesewardj +-----------------+ 31817c110443e39c0c63bb298689cad31e0b4671dfesewardj | AT_NULL | 31917c110443e39c0c63bb298689cad31e0b4671dfesewardj - - 32017c110443e39c0c63bb298689cad31e0b4671dfesewardj | auxv | 32117c110443e39c0c63bb298689cad31e0b4671dfesewardj +-----------------+ 32217c110443e39c0c63bb298689cad31e0b4671dfesewardj | NULL | 32317c110443e39c0c63bb298689cad31e0b4671dfesewardj - - 32417c110443e39c0c63bb298689cad31e0b4671dfesewardj | envp | 32517c110443e39c0c63bb298689cad31e0b4671dfesewardj +-----------------+ 32617c110443e39c0c63bb298689cad31e0b4671dfesewardj | NULL | 32717c110443e39c0c63bb298689cad31e0b4671dfesewardj - - 32817c110443e39c0c63bb298689cad31e0b4671dfesewardj | argv | 32917c110443e39c0c63bb298689cad31e0b4671dfesewardj +-----------------+ 33017c110443e39c0c63bb298689cad31e0b4671dfesewardj | argc | 33117c110443e39c0c63bb298689cad31e0b4671dfesewardj lower address +-----------------+ <- sp 33217c110443e39c0c63bb298689cad31e0b4671dfesewardj | undefined | 33317c110443e39c0c63bb298689cad31e0b4671dfesewardj : : 33417c110443e39c0c63bb298689cad31e0b4671dfesewardj 33517c110443e39c0c63bb298689cad31e0b4671dfesewardj Allocate and create the initial client stack. It is allocated down 33617c110443e39c0c63bb298689cad31e0b4671dfesewardj from clstack_end, which was previously determined by the address 33717c110443e39c0c63bb298689cad31e0b4671dfesewardj space manager. The returned value is the SP value for the client. 33817c110443e39c0c63bb298689cad31e0b4671dfesewardj 33917c110443e39c0c63bb298689cad31e0b4671dfesewardj The client's auxv is created by copying and modifying our own one. 34017c110443e39c0c63bb298689cad31e0b4671dfesewardj As a side effect of scanning our own auxv, some important bits of 34117c110443e39c0c63bb298689cad31e0b4671dfesewardj info are collected: 34217c110443e39c0c63bb298689cad31e0b4671dfesewardj 34317c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(cache_line_size_ppc32) // ppc32 only -- cache line size 34417c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(have_altivec_ppc32) // ppc32 only -- is Altivec supported? 34517c110443e39c0c63bb298689cad31e0b4671dfesewardj 34617c110443e39c0c63bb298689cad31e0b4671dfesewardj ---------------------------------------------------------------- */ 34717c110443e39c0c63bb298689cad31e0b4671dfesewardj 34891772d140e9f918c25b9b20233d3673367b799dfnjnstruct auxv 34991772d140e9f918c25b9b20233d3673367b799dfnjn{ 35091772d140e9f918c25b9b20233d3673367b799dfnjn Word a_type; 35191772d140e9f918c25b9b20233d3673367b799dfnjn union { 35291772d140e9f918c25b9b20233d3673367b799dfnjn void *a_ptr; 35391772d140e9f918c25b9b20233d3673367b799dfnjn Word a_val; 35491772d140e9f918c25b9b20233d3673367b799dfnjn } u; 35591772d140e9f918c25b9b20233d3673367b799dfnjn}; 35691772d140e9f918c25b9b20233d3673367b799dfnjn 35791772d140e9f918c25b9b20233d3673367b799dfnjnstatic 35891772d140e9f918c25b9b20233d3673367b799dfnjnstruct auxv *find_auxv(UWord* sp) 35991772d140e9f918c25b9b20233d3673367b799dfnjn{ 36091772d140e9f918c25b9b20233d3673367b799dfnjn sp++; // skip argc (Nb: is word-sized, not int-sized!) 36191772d140e9f918c25b9b20233d3673367b799dfnjn 36291772d140e9f918c25b9b20233d3673367b799dfnjn while (*sp != 0) // skip argv 36391772d140e9f918c25b9b20233d3673367b799dfnjn sp++; 36491772d140e9f918c25b9b20233d3673367b799dfnjn sp++; 36591772d140e9f918c25b9b20233d3673367b799dfnjn 36691772d140e9f918c25b9b20233d3673367b799dfnjn while (*sp != 0) // skip env 36791772d140e9f918c25b9b20233d3673367b799dfnjn sp++; 36891772d140e9f918c25b9b20233d3673367b799dfnjn sp++; 36991772d140e9f918c25b9b20233d3673367b799dfnjn 370cae0cc22b83ffb260ee8379e92099c5a701944cbcarll#if defined(VGA_ppc32) || defined(VGA_ppc64be) || defined(VGA_ppc64le) 37191772d140e9f918c25b9b20233d3673367b799dfnjn# if defined AT_IGNOREPPC 37291772d140e9f918c25b9b20233d3673367b799dfnjn while (*sp == AT_IGNOREPPC) // skip AT_IGNOREPPC entries 37391772d140e9f918c25b9b20233d3673367b799dfnjn sp += 2; 37491772d140e9f918c25b9b20233d3673367b799dfnjn# endif 37591772d140e9f918c25b9b20233d3673367b799dfnjn#endif 37691772d140e9f918c25b9b20233d3673367b799dfnjn 37791772d140e9f918c25b9b20233d3673367b799dfnjn return (struct auxv *)sp; 37891772d140e9f918c25b9b20233d3673367b799dfnjn} 37991772d140e9f918c25b9b20233d3673367b799dfnjn 38017c110443e39c0c63bb298689cad31e0b4671dfesewardjstatic 38117c110443e39c0c63bb298689cad31e0b4671dfesewardjAddr setup_client_stack( void* init_sp, 382c8b821428c9a8e63a6d055211963eae6eccc41c0florian HChar** orig_envp, 38317c110443e39c0c63bb298689cad31e0b4671dfesewardj const ExeInfo* info, 38417c110443e39c0c63bb298689cad31e0b4671dfesewardj UInt** client_auxv, 38517c110443e39c0c63bb298689cad31e0b4671dfesewardj Addr clstack_end, 38652b284b2fb907204dfae5a067e83eed98ea72dd2carll SizeT clstack_max_size, 38752b284b2fb907204dfae5a067e83eed98ea72dd2carll const VexArchInfo* vex_archinfo ) 38817c110443e39c0c63bb298689cad31e0b4671dfesewardj{ 38952b284b2fb907204dfae5a067e83eed98ea72dd2carll /* The HW configuration setting (hwcaps) of the target can be 39052b284b2fb907204dfae5a067e83eed98ea72dd2carll * checked against the Vex settings of the host platform as given 39152b284b2fb907204dfae5a067e83eed98ea72dd2carll * by the values in vex_archinfo. 39252b284b2fb907204dfae5a067e83eed98ea72dd2carll */ 39352b284b2fb907204dfae5a067e83eed98ea72dd2carll 39417c110443e39c0c63bb298689cad31e0b4671dfesewardj SysRes res; 395c8b821428c9a8e63a6d055211963eae6eccc41c0florian HChar **cpp; 396c8b821428c9a8e63a6d055211963eae6eccc41c0florian HChar *strtab; /* string table */ 397c8b821428c9a8e63a6d055211963eae6eccc41c0florian HChar *stringbase; 39817c110443e39c0c63bb298689cad31e0b4671dfesewardj Addr *ptr; 39991772d140e9f918c25b9b20233d3673367b799dfnjn struct auxv *auxv; 40091772d140e9f918c25b9b20233d3673367b799dfnjn const struct auxv *orig_auxv; 40191772d140e9f918c25b9b20233d3673367b799dfnjn const struct auxv *cauxv; 40217c110443e39c0c63bb298689cad31e0b4671dfesewardj unsigned stringsize; /* total size of strings in bytes */ 40317c110443e39c0c63bb298689cad31e0b4671dfesewardj unsigned auxsize; /* total size of auxv in bytes */ 40417c110443e39c0c63bb298689cad31e0b4671dfesewardj Int argc; /* total argc */ 40517c110443e39c0c63bb298689cad31e0b4671dfesewardj Int envc; /* total number of env vars */ 40617c110443e39c0c63bb298689cad31e0b4671dfesewardj unsigned stacksize; /* total client stack size */ 40717c110443e39c0c63bb298689cad31e0b4671dfesewardj Addr client_SP; /* client stack base (initial SP) */ 40817c110443e39c0c63bb298689cad31e0b4671dfesewardj Addr clstack_start; 40917c110443e39c0c63bb298689cad31e0b4671dfesewardj Int i; 41017c110443e39c0c63bb298689cad31e0b4671dfesewardj 41117c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_IS_PAGE_ALIGNED(clstack_end+1)); 41214c7cc5a5fbe9526329f058116f921988efe679esewardj vg_assert( VG_(args_for_client) ); 41317c110443e39c0c63bb298689cad31e0b4671dfesewardj 41417c110443e39c0c63bb298689cad31e0b4671dfesewardj /* use our own auxv as a prototype */ 41591772d140e9f918c25b9b20233d3673367b799dfnjn orig_auxv = find_auxv(init_sp); 41617c110443e39c0c63bb298689cad31e0b4671dfesewardj 41717c110443e39c0c63bb298689cad31e0b4671dfesewardj /* ==================== compute sizes ==================== */ 41817c110443e39c0c63bb298689cad31e0b4671dfesewardj 41917c110443e39c0c63bb298689cad31e0b4671dfesewardj /* first of all, work out how big the client stack will be */ 42017c110443e39c0c63bb298689cad31e0b4671dfesewardj stringsize = 0; 42117c110443e39c0c63bb298689cad31e0b4671dfesewardj 42217c110443e39c0c63bb298689cad31e0b4671dfesewardj /* paste on the extra args if the loader needs them (ie, the #! 42317c110443e39c0c63bb298689cad31e0b4671dfesewardj interpreter and its argument) */ 42417c110443e39c0c63bb298689cad31e0b4671dfesewardj argc = 0; 42517c110443e39c0c63bb298689cad31e0b4671dfesewardj if (info->interp_name != NULL) { 42617c110443e39c0c63bb298689cad31e0b4671dfesewardj argc++; 42717c110443e39c0c63bb298689cad31e0b4671dfesewardj stringsize += VG_(strlen)(info->interp_name) + 1; 42817c110443e39c0c63bb298689cad31e0b4671dfesewardj } 42917c110443e39c0c63bb298689cad31e0b4671dfesewardj if (info->interp_args != NULL) { 43017c110443e39c0c63bb298689cad31e0b4671dfesewardj argc++; 43117c110443e39c0c63bb298689cad31e0b4671dfesewardj stringsize += VG_(strlen)(info->interp_args) + 1; 43217c110443e39c0c63bb298689cad31e0b4671dfesewardj } 43317c110443e39c0c63bb298689cad31e0b4671dfesewardj 43417c110443e39c0c63bb298689cad31e0b4671dfesewardj /* now scan the args we're given... */ 435b16609bf952bf381154cb6cba87efc99c2c86a23florian stringsize += VG_(strlen)( VG_(args_the_exename) ) + 1; 43617c110443e39c0c63bb298689cad31e0b4671dfesewardj 43714c7cc5a5fbe9526329f058116f921988efe679esewardj for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { 43817c110443e39c0c63bb298689cad31e0b4671dfesewardj argc++; 43914c7cc5a5fbe9526329f058116f921988efe679esewardj stringsize += VG_(strlen)( * (HChar**) 44014c7cc5a5fbe9526329f058116f921988efe679esewardj VG_(indexXA)( VG_(args_for_client), i )) 44114c7cc5a5fbe9526329f058116f921988efe679esewardj + 1; 44217c110443e39c0c63bb298689cad31e0b4671dfesewardj } 44317c110443e39c0c63bb298689cad31e0b4671dfesewardj 44417c110443e39c0c63bb298689cad31e0b4671dfesewardj /* ...and the environment */ 44517c110443e39c0c63bb298689cad31e0b4671dfesewardj envc = 0; 44617c110443e39c0c63bb298689cad31e0b4671dfesewardj for (cpp = orig_envp; cpp && *cpp; cpp++) { 44717c110443e39c0c63bb298689cad31e0b4671dfesewardj envc++; 44817c110443e39c0c63bb298689cad31e0b4671dfesewardj stringsize += VG_(strlen)(*cpp) + 1; 44917c110443e39c0c63bb298689cad31e0b4671dfesewardj } 45017c110443e39c0c63bb298689cad31e0b4671dfesewardj 45117c110443e39c0c63bb298689cad31e0b4671dfesewardj /* now, how big is the auxv? */ 45217c110443e39c0c63bb298689cad31e0b4671dfesewardj auxsize = sizeof(*auxv); /* there's always at least one entry: AT_NULL */ 45317c110443e39c0c63bb298689cad31e0b4671dfesewardj for (cauxv = orig_auxv; cauxv->a_type != AT_NULL; cauxv++) { 454c880930fdabebbe59dd2c1f72f707cf95c796f1etom if (cauxv->a_type == AT_PLATFORM || 455c880930fdabebbe59dd2c1f72f707cf95c796f1etom cauxv->a_type == AT_BASE_PLATFORM) 45617c110443e39c0c63bb298689cad31e0b4671dfesewardj stringsize += VG_(strlen)(cauxv->u.a_ptr) + 1; 4579c6533d2c47883f9e491a2a388c5503b3bf4c002tom else if (cauxv->a_type == AT_RANDOM) 4589c6533d2c47883f9e491a2a388c5503b3bf4c002tom stringsize += 16; 459b16609bf952bf381154cb6cba87efc99c2c86a23florian else if (cauxv->a_type == AT_EXECFN) 46020a8a6125459a919a9561f8480b38f78f7c91fe9tom stringsize += VG_(strlen)(VG_(args_the_exename)) + 1; 46117c110443e39c0c63bb298689cad31e0b4671dfesewardj auxsize += sizeof(*cauxv); 46217c110443e39c0c63bb298689cad31e0b4671dfesewardj } 46317c110443e39c0c63bb298689cad31e0b4671dfesewardj 464cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \ 465cae0cc22b83ffb260ee8379e92099c5a701944cbcarll || defined(VGP_ppc64le_linux) 46617c110443e39c0c63bb298689cad31e0b4671dfesewardj auxsize += 2 * sizeof(*cauxv); 46717c110443e39c0c63bb298689cad31e0b4671dfesewardj# endif 46817c110443e39c0c63bb298689cad31e0b4671dfesewardj 46917c110443e39c0c63bb298689cad31e0b4671dfesewardj /* OK, now we know how big the client stack is */ 47017c110443e39c0c63bb298689cad31e0b4671dfesewardj stacksize = 47117c110443e39c0c63bb298689cad31e0b4671dfesewardj sizeof(Word) + /* argc */ 472b16609bf952bf381154cb6cba87efc99c2c86a23florian sizeof(HChar **) + /* argc[0] == exename */ 473c8b821428c9a8e63a6d055211963eae6eccc41c0florian sizeof(HChar **)*argc + /* argv */ 474c8b821428c9a8e63a6d055211963eae6eccc41c0florian sizeof(HChar **) + /* terminal NULL */ 475c8b821428c9a8e63a6d055211963eae6eccc41c0florian sizeof(HChar **)*envc + /* envp */ 476c8b821428c9a8e63a6d055211963eae6eccc41c0florian sizeof(HChar **) + /* terminal NULL */ 47717c110443e39c0c63bb298689cad31e0b4671dfesewardj auxsize + /* auxv */ 47817c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_ROUNDUP(stringsize, sizeof(Word)); /* strings (aligned) */ 47917c110443e39c0c63bb298689cad31e0b4671dfesewardj 480a5e06c36bf9d93461bc8c4351e960888020ea1c4florian if (0) VG_(printf)("stacksize = %u\n", stacksize); 48117c110443e39c0c63bb298689cad31e0b4671dfesewardj 48217c110443e39c0c63bb298689cad31e0b4671dfesewardj /* client_SP is the client's stack pointer */ 48317c110443e39c0c63bb298689cad31e0b4671dfesewardj client_SP = clstack_end - stacksize; 48417c110443e39c0c63bb298689cad31e0b4671dfesewardj client_SP = VG_ROUNDDN(client_SP, 16); /* make stack 16 byte aligned */ 48517c110443e39c0c63bb298689cad31e0b4671dfesewardj 48617c110443e39c0c63bb298689cad31e0b4671dfesewardj /* base of the string table (aligned) */ 487c8b821428c9a8e63a6d055211963eae6eccc41c0florian stringbase = strtab = (HChar *)clstack_end 48817c110443e39c0c63bb298689cad31e0b4671dfesewardj - VG_ROUNDUP(stringsize, sizeof(int)); 48917c110443e39c0c63bb298689cad31e0b4671dfesewardj 49017c110443e39c0c63bb298689cad31e0b4671dfesewardj clstack_start = VG_PGROUNDDN(client_SP); 49117c110443e39c0c63bb298689cad31e0b4671dfesewardj 49217c110443e39c0c63bb298689cad31e0b4671dfesewardj /* The max stack size */ 49317c110443e39c0c63bb298689cad31e0b4671dfesewardj clstack_max_size = VG_PGROUNDUP(clstack_max_size); 49417c110443e39c0c63bb298689cad31e0b4671dfesewardj 49517c110443e39c0c63bb298689cad31e0b4671dfesewardj if (0) 496a5e06c36bf9d93461bc8c4351e960888020ea1c4florian VG_(printf)("stringsize=%u auxsize=%u stacksize=%u maxsize=0x%lx\n" 49717c110443e39c0c63bb298689cad31e0b4671dfesewardj "clstack_start %p\n" 49817c110443e39c0c63bb298689cad31e0b4671dfesewardj "clstack_end %p\n", 499a5e06c36bf9d93461bc8c4351e960888020ea1c4florian stringsize, auxsize, stacksize, clstack_max_size, 50017c110443e39c0c63bb298689cad31e0b4671dfesewardj (void*)clstack_start, (void*)clstack_end); 50117c110443e39c0c63bb298689cad31e0b4671dfesewardj 50217c110443e39c0c63bb298689cad31e0b4671dfesewardj /* ==================== allocate space ==================== */ 50317c110443e39c0c63bb298689cad31e0b4671dfesewardj 50417c110443e39c0c63bb298689cad31e0b4671dfesewardj { SizeT anon_size = clstack_end - clstack_start + 1; 50517c110443e39c0c63bb298689cad31e0b4671dfesewardj SizeT resvn_size = clstack_max_size - anon_size; 50617c110443e39c0c63bb298689cad31e0b4671dfesewardj Addr anon_start = clstack_start; 50717c110443e39c0c63bb298689cad31e0b4671dfesewardj Addr resvn_start = anon_start - resvn_size; 50817c110443e39c0c63bb298689cad31e0b4671dfesewardj SizeT inner_HACK = 0; 50917c110443e39c0c63bb298689cad31e0b4671dfesewardj Bool ok; 51017c110443e39c0c63bb298689cad31e0b4671dfesewardj 51117c110443e39c0c63bb298689cad31e0b4671dfesewardj /* So far we've only accounted for space requirements down to the 51217c110443e39c0c63bb298689cad31e0b4671dfesewardj stack pointer. If this target's ABI requires a redzone below 51317c110443e39c0c63bb298689cad31e0b4671dfesewardj the stack pointer, we need to allocate an extra page, to 51417c110443e39c0c63bb298689cad31e0b4671dfesewardj handle the worst case in which the stack pointer is almost at 51517c110443e39c0c63bb298689cad31e0b4671dfesewardj the bottom of a page, and so there is insufficient room left 51617c110443e39c0c63bb298689cad31e0b4671dfesewardj over to put the redzone in. In this case the simple thing to 51717c110443e39c0c63bb298689cad31e0b4671dfesewardj do is allocate an extra page, by shrinking the reservation by 51817c110443e39c0c63bb298689cad31e0b4671dfesewardj one page and growing the anonymous area by a corresponding 51917c110443e39c0c63bb298689cad31e0b4671dfesewardj page. */ 52017c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_STACK_REDZONE_SZB >= 0); 52117c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_STACK_REDZONE_SZB < VKI_PAGE_SIZE); 52217c110443e39c0c63bb298689cad31e0b4671dfesewardj if (VG_STACK_REDZONE_SZB > 0) { 52317c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(resvn_size > VKI_PAGE_SIZE); 52417c110443e39c0c63bb298689cad31e0b4671dfesewardj resvn_size -= VKI_PAGE_SIZE; 52517c110443e39c0c63bb298689cad31e0b4671dfesewardj anon_start -= VKI_PAGE_SIZE; 52617c110443e39c0c63bb298689cad31e0b4671dfesewardj anon_size += VKI_PAGE_SIZE; 52717c110443e39c0c63bb298689cad31e0b4671dfesewardj } 52817c110443e39c0c63bb298689cad31e0b4671dfesewardj 52917c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_IS_PAGE_ALIGNED(anon_size)); 53017c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_IS_PAGE_ALIGNED(resvn_size)); 53117c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_IS_PAGE_ALIGNED(anon_start)); 53217c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_IS_PAGE_ALIGNED(resvn_start)); 53317c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(resvn_start == clstack_end + 1 - clstack_max_size); 53417c110443e39c0c63bb298689cad31e0b4671dfesewardj 53517c110443e39c0c63bb298689cad31e0b4671dfesewardj# ifdef ENABLE_INNER 53617c110443e39c0c63bb298689cad31e0b4671dfesewardj inner_HACK = 1024*1024; // create 1M non-fault-extending stack 53717c110443e39c0c63bb298689cad31e0b4671dfesewardj# endif 53817c110443e39c0c63bb298689cad31e0b4671dfesewardj 53917c110443e39c0c63bb298689cad31e0b4671dfesewardj if (0) 540a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart VG_(printf)("%#lx 0x%lx %#lx 0x%lx\n", 54117c110443e39c0c63bb298689cad31e0b4671dfesewardj resvn_start, resvn_size, anon_start, anon_size); 54217c110443e39c0c63bb298689cad31e0b4671dfesewardj 54317c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Create a shrinkable reservation followed by an anonymous 54417c110443e39c0c63bb298689cad31e0b4671dfesewardj segment. Together these constitute a growdown stack. */ 545d5c3f2839495d785ccf8e70c060eb2671507c192sewardj res = VG_(mk_SysRes_Error)(0); 54617c110443e39c0c63bb298689cad31e0b4671dfesewardj ok = VG_(am_create_reservation)( 54717c110443e39c0c63bb298689cad31e0b4671dfesewardj resvn_start, 54817c110443e39c0c63bb298689cad31e0b4671dfesewardj resvn_size -inner_HACK, 54917c110443e39c0c63bb298689cad31e0b4671dfesewardj SmUpper, 55017c110443e39c0c63bb298689cad31e0b4671dfesewardj anon_size +inner_HACK 55117c110443e39c0c63bb298689cad31e0b4671dfesewardj ); 552d5c3f2839495d785ccf8e70c060eb2671507c192sewardj if (ok) { 553d5c3f2839495d785ccf8e70c060eb2671507c192sewardj /* allocate a stack - mmap enough space for the stack */ 554d5c3f2839495d785ccf8e70c060eb2671507c192sewardj res = VG_(am_mmap_anon_fixed_client)( 555d5c3f2839495d785ccf8e70c060eb2671507c192sewardj anon_start -inner_HACK, 556d5c3f2839495d785ccf8e70c060eb2671507c192sewardj anon_size +inner_HACK, 55750d6d212fc8dfe63e2e83169fd8e12cf72ccfd1atom info->stack_prot 558d5c3f2839495d785ccf8e70c060eb2671507c192sewardj ); 559d5c3f2839495d785ccf8e70c060eb2671507c192sewardj } 560cda2f0fbda4c4b2644babc830244be8aed95de1dnjn if ((!ok) || sr_isError(res)) { 561d5c3f2839495d785ccf8e70c060eb2671507c192sewardj /* Allocation of the stack failed. We have to stop. */ 562d5c3f2839495d785ccf8e70c060eb2671507c192sewardj VG_(printf)("valgrind: " 563d5c3f2839495d785ccf8e70c060eb2671507c192sewardj "I failed to allocate space for the application's stack.\n"); 564d5c3f2839495d785ccf8e70c060eb2671507c192sewardj VG_(printf)("valgrind: " 56595d86c091a218e904e912354efa4f952a9712e82sewardj "This may be the result of a very large --main-stacksize=\n"); 566d5c3f2839495d785ccf8e70c060eb2671507c192sewardj VG_(printf)("valgrind: setting. Cannot continue. Sorry.\n\n"); 5679dc31561106f3f1b8057fdcdef94fa735a5f9c0aflorian VG_(exit)(1); 568d5c3f2839495d785ccf8e70c060eb2671507c192sewardj } 569d5c3f2839495d785ccf8e70c060eb2671507c192sewardj 57017c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(ok); 571cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(!sr_isError(res)); 5724fa3d371f8a70bb89e7f6bdf95011c05b3dbc7d4philippe 5734fa3d371f8a70bb89e7f6bdf95011c05b3dbc7d4philippe /* Record stack extent -- needed for stack-change code. */ 57438a74d2cc4670e3eb559adff51a376cd6ec98005philippe VG_(clstk_start_base) = anon_start -inner_HACK; 57538a74d2cc4670e3eb559adff51a376cd6ec98005philippe VG_(clstk_end) = VG_(clstk_start_base) + anon_size +inner_HACK -1; 5764fa3d371f8a70bb89e7f6bdf95011c05b3dbc7d4philippe 57717c110443e39c0c63bb298689cad31e0b4671dfesewardj } 57817c110443e39c0c63bb298689cad31e0b4671dfesewardj 57917c110443e39c0c63bb298689cad31e0b4671dfesewardj /* ==================== create client stack ==================== */ 58017c110443e39c0c63bb298689cad31e0b4671dfesewardj 58117c110443e39c0c63bb298689cad31e0b4671dfesewardj ptr = (Addr*)client_SP; 58217c110443e39c0c63bb298689cad31e0b4671dfesewardj 58317c110443e39c0c63bb298689cad31e0b4671dfesewardj /* --- client argc --- */ 584b16609bf952bf381154cb6cba87efc99c2c86a23florian *ptr++ = argc + 1; 58517c110443e39c0c63bb298689cad31e0b4671dfesewardj 58617c110443e39c0c63bb298689cad31e0b4671dfesewardj /* --- client argv --- */ 587a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (info->interp_name) 58817c110443e39c0c63bb298689cad31e0b4671dfesewardj *ptr++ = (Addr)copy_str(&strtab, info->interp_name); 589a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (info->interp_args) 59017c110443e39c0c63bb298689cad31e0b4671dfesewardj *ptr++ = (Addr)copy_str(&strtab, info->interp_args); 59117c110443e39c0c63bb298689cad31e0b4671dfesewardj 592b16609bf952bf381154cb6cba87efc99c2c86a23florian *ptr++ = (Addr)copy_str(&strtab, VG_(args_the_exename)); 59317c110443e39c0c63bb298689cad31e0b4671dfesewardj 59414c7cc5a5fbe9526329f058116f921988efe679esewardj for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) { 59514c7cc5a5fbe9526329f058116f921988efe679esewardj *ptr++ = (Addr)copy_str( 59614c7cc5a5fbe9526329f058116f921988efe679esewardj &strtab, 59714c7cc5a5fbe9526329f058116f921988efe679esewardj * (HChar**) VG_(indexXA)( VG_(args_for_client), i ) 59814c7cc5a5fbe9526329f058116f921988efe679esewardj ); 59917c110443e39c0c63bb298689cad31e0b4671dfesewardj } 60017c110443e39c0c63bb298689cad31e0b4671dfesewardj *ptr++ = 0; 60117c110443e39c0c63bb298689cad31e0b4671dfesewardj 60217c110443e39c0c63bb298689cad31e0b4671dfesewardj /* --- envp --- */ 60319f91bbaedb4caef8a60ce94b0f507193cc0bc10florian VG_(client_envp) = (HChar **)ptr; 60417c110443e39c0c63bb298689cad31e0b4671dfesewardj for (cpp = orig_envp; cpp && *cpp; ptr++, cpp++) 60517c110443e39c0c63bb298689cad31e0b4671dfesewardj *ptr = (Addr)copy_str(&strtab, *cpp); 60617c110443e39c0c63bb298689cad31e0b4671dfesewardj *ptr++ = 0; 60717c110443e39c0c63bb298689cad31e0b4671dfesewardj 60817c110443e39c0c63bb298689cad31e0b4671dfesewardj /* --- auxv --- */ 60991772d140e9f918c25b9b20233d3673367b799dfnjn auxv = (struct auxv *)ptr; 61017c110443e39c0c63bb298689cad31e0b4671dfesewardj *client_auxv = (UInt *)auxv; 6112a31239309f89ea2d70c1bd29d2c1a7874e14812sewardj VG_(client_auxv) = (UWord *)*client_auxv; 6122a31239309f89ea2d70c1bd29d2c1a7874e14812sewardj // ??? According to 'man proc', auxv is a array of unsigned long 6132a31239309f89ea2d70c1bd29d2c1a7874e14812sewardj // terminated by two zeros. Why is valgrind working with UInt ? 6142a31239309f89ea2d70c1bd29d2c1a7874e14812sewardj // We do not take ULong* (as ULong 8 bytes on a 32 bits), 6152a31239309f89ea2d70c1bd29d2c1a7874e14812sewardj // => we take UWord* 61617c110443e39c0c63bb298689cad31e0b4671dfesewardj 617cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \ 618cae0cc22b83ffb260ee8379e92099c5a701944cbcarll || defined(VGP_ppc64le_linux) 61917c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv[0].a_type = AT_IGNOREPPC; 62017c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv[0].u.a_val = AT_IGNOREPPC; 62117c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv[1].a_type = AT_IGNOREPPC; 62217c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv[1].u.a_val = AT_IGNOREPPC; 62317c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv += 2; 62417c110443e39c0c63bb298689cad31e0b4671dfesewardj# endif 62517c110443e39c0c63bb298689cad31e0b4671dfesewardj 62617c110443e39c0c63bb298689cad31e0b4671dfesewardj for (; orig_auxv->a_type != AT_NULL; auxv++, orig_auxv++) { 62717c110443e39c0c63bb298689cad31e0b4671dfesewardj 62817c110443e39c0c63bb298689cad31e0b4671dfesewardj /* copy the entry... */ 62917c110443e39c0c63bb298689cad31e0b4671dfesewardj *auxv = *orig_auxv; 63017c110443e39c0c63bb298689cad31e0b4671dfesewardj 63117c110443e39c0c63bb298689cad31e0b4671dfesewardj /* ...and fix up / examine the copy */ 63217c110443e39c0c63bb298689cad31e0b4671dfesewardj switch(auxv->a_type) { 63317c110443e39c0c63bb298689cad31e0b4671dfesewardj 63417c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_IGNORE: 63517c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_PHENT: 63617c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_PAGESZ: 63717c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_FLAGS: 63817c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_NOTELF: 63917c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_UID: 64017c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_EUID: 64117c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_GID: 64217c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_EGID: 64317c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_CLKTCK: 644a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes# if !defined(VGPV_arm_linux_android) \ 645a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes && !defined(VGPV_x86_linux_android) \ 646a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes && !defined(VGPV_mips32_linux_android) \ 647a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes && !defined(VGPV_arm64_linux_android) 6486a1ec6bdd8ac1d79e721415e7f9e6247ece2ec8esewardj case AT_FPUCW: /* missing on android */ 649c19a5b043a10eb0477f34e66c614ca3a382edab7sewardj# endif 65017c110443e39c0c63bb298689cad31e0b4671dfesewardj /* All these are pointerless, so we don't need to do 65117c110443e39c0c63bb298689cad31e0b4671dfesewardj anything about them. */ 65217c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 65317c110443e39c0c63bb298689cad31e0b4671dfesewardj 65417c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_PHDR: 65517c110443e39c0c63bb298689cad31e0b4671dfesewardj if (info->phdr == 0) 65617c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv->a_type = AT_IGNORE; 65717c110443e39c0c63bb298689cad31e0b4671dfesewardj else 65817c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv->u.a_val = info->phdr; 65917c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 66017c110443e39c0c63bb298689cad31e0b4671dfesewardj 66117c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_PHNUM: 66217c110443e39c0c63bb298689cad31e0b4671dfesewardj if (info->phdr == 0) 66317c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv->a_type = AT_IGNORE; 66417c110443e39c0c63bb298689cad31e0b4671dfesewardj else 66517c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv->u.a_val = info->phnum; 66617c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 66717c110443e39c0c63bb298689cad31e0b4671dfesewardj 66817c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_BASE: 6693d24135101d712a59f9ec722e95d2a5670ea735etom auxv->u.a_val = info->interp_offset; 67017c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 67117c110443e39c0c63bb298689cad31e0b4671dfesewardj 67217c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_PLATFORM: 673c880930fdabebbe59dd2c1f72f707cf95c796f1etom case AT_BASE_PLATFORM: 67417c110443e39c0c63bb298689cad31e0b4671dfesewardj /* points to a platform description string */ 67517c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv->u.a_ptr = copy_str(&strtab, orig_auxv->u.a_ptr); 67617c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 67717c110443e39c0c63bb298689cad31e0b4671dfesewardj 67817c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_ENTRY: 67917c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv->u.a_val = info->entry; 68017c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 68117c110443e39c0c63bb298689cad31e0b4671dfesewardj 68217c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_HWCAP: 683a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj# if defined(VGP_arm_linux) 684a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj { Bool has_neon = (auxv->u.a_val & VKI_HWCAP_NEON) > 0; 685a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj VG_(debugLog)(2, "initimg", 686a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj "ARM has-neon from-auxv: %s\n", 687a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj has_neon ? "YES" : "NO"); 688a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj VG_(machine_arm_set_has_NEON)( has_neon ); 689a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes# define VKI_HWCAP_TLS 32768 690eeb0733e5659b10354d5f5daf69c3474d476705fphilippe Bool has_tls = (auxv->u.a_val & VKI_HWCAP_TLS) > 0; 691a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes# undef VKI_HWCAP_TLS 692eeb0733e5659b10354d5f5daf69c3474d476705fphilippe VG_(debugLog)(2, "initimg", 693eeb0733e5659b10354d5f5daf69c3474d476705fphilippe "ARM has-tls from-auxv: %s\n", 694eeb0733e5659b10354d5f5daf69c3474d476705fphilippe has_tls ? "YES" : "NO"); 695eeb0733e5659b10354d5f5daf69c3474d476705fphilippe /* If real hw sets properly HWCAP_TLS, we might 696eeb0733e5659b10354d5f5daf69c3474d476705fphilippe use this info to decide to really execute set_tls syscall 697eeb0733e5659b10354d5f5daf69c3474d476705fphilippe in syswrap-arm-linux.c rather than to base this on 698eeb0733e5659b10354d5f5daf69c3474d476705fphilippe conditional compilation. */ 699a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj } 700416e4bb7c50cea52f911359da427db3912f87b21florian# elif defined(VGP_s390x_linux) 701416e4bb7c50cea52f911359da427db3912f87b21florian { 702416e4bb7c50cea52f911359da427db3912f87b21florian /* Advertise hardware features "below" TE only. TE and VXRS 703416e4bb7c50cea52f911359da427db3912f87b21florian (and anything above) are not supported by Valgrind. */ 704416e4bb7c50cea52f911359da427db3912f87b21florian auxv->u.a_val &= VKI_HWCAP_S390_TE - 1; 705416e4bb7c50cea52f911359da427db3912f87b21florian } 706a3551be497f6c4afc5dfbbbcd7c7a955a68fb22bsewardj# endif 70717c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 70852b284b2fb907204dfae5a067e83eed98ea72dd2carll# if defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 7093b91f1779802a17344e1901f3b7c0271a22d3194carll case AT_HWCAP2: { 7103b91f1779802a17344e1901f3b7c0271a22d3194carll Bool auxv_2_07, hw_caps_2_07; 7113b91f1779802a17344e1901f3b7c0271a22d3194carll /* The HWCAP2 field may contain an arch_2_07 entry that indicates 7123b91f1779802a17344e1901f3b7c0271a22d3194carll * if the processor is compliant with the 2.07 ISA. (i.e. Power 8 7133b91f1779802a17344e1901f3b7c0271a22d3194carll * or beyond). The Valgrind vai.hwcaps value 7143b91f1779802a17344e1901f3b7c0271a22d3194carll * (coregrind/m_machine.c) has the VEX_HWCAPS_PPC64_ISA2_07 71552b284b2fb907204dfae5a067e83eed98ea72dd2carll * flag set so Valgrind knows about Power8. Need to pass the 71652b284b2fb907204dfae5a067e83eed98ea72dd2carll * HWCAP2 value along so the user level programs can detect that 71752b284b2fb907204dfae5a067e83eed98ea72dd2carll * the processor supports ISA 2.07 and beyond. 71852b284b2fb907204dfae5a067e83eed98ea72dd2carll */ 71952b284b2fb907204dfae5a067e83eed98ea72dd2carll /* Power Architecture 64-Bit ELF V2 ABI Specification 72052b284b2fb907204dfae5a067e83eed98ea72dd2carll July 21, 2014, version 1.0, Page 124 72152b284b2fb907204dfae5a067e83eed98ea72dd2carll www-03.ibm.com/technologyconnect/tgcm/TGCMServlet.wss?alias=OpenPOWER&linkid=1n0000 72252b284b2fb907204dfae5a067e83eed98ea72dd2carll 72352b284b2fb907204dfae5a067e83eed98ea72dd2carll AT_HWCAP2 72452b284b2fb907204dfae5a067e83eed98ea72dd2carll The a_val member of this entry is a bit map of hardware 72552b284b2fb907204dfae5a067e83eed98ea72dd2carll capabilities. Some bit mask values include: 72652b284b2fb907204dfae5a067e83eed98ea72dd2carll 72752b284b2fb907204dfae5a067e83eed98ea72dd2carll PPC_FEATURE2_ARCH_2_07 0x80000000 72852b284b2fb907204dfae5a067e83eed98ea72dd2carll PPC_FEATURE2_HAS_HTM 0x40000000 72952b284b2fb907204dfae5a067e83eed98ea72dd2carll PPC_FEATURE2_HAS_DSCR 0x20000000 73052b284b2fb907204dfae5a067e83eed98ea72dd2carll PPC_FEATURE2_HAS_EBB 0x10000000 73152b284b2fb907204dfae5a067e83eed98ea72dd2carll PPC_FEATURE2_HAS_ISEL 0x08000000 73252b284b2fb907204dfae5a067e83eed98ea72dd2carll PPC_FEATURE2_HAS_TAR 0x04000000 73352b284b2fb907204dfae5a067e83eed98ea72dd2carll PPC_FEATURE2_HAS_VCRYPTO 0x02000000 73452b284b2fb907204dfae5a067e83eed98ea72dd2carll */ 7353b91f1779802a17344e1901f3b7c0271a22d3194carll auxv_2_07 = (auxv->u.a_val & 0x80000000ULL) == 0x80000000ULL; 7363b91f1779802a17344e1901f3b7c0271a22d3194carll hw_caps_2_07 = (vex_archinfo->hwcaps & VEX_HWCAPS_PPC64_ISA2_07) 7373b91f1779802a17344e1901f3b7c0271a22d3194carll == VEX_HWCAPS_PPC64_ISA2_07; 7383b91f1779802a17344e1901f3b7c0271a22d3194carll 7393b91f1779802a17344e1901f3b7c0271a22d3194carll /* Verify the PPC_FEATURE2_ARCH_2_07 setting in HWCAP2 7403b91f1779802a17344e1901f3b7c0271a22d3194carll * matches the setting in VEX HWCAPS. 7413b91f1779802a17344e1901f3b7c0271a22d3194carll */ 7423b91f1779802a17344e1901f3b7c0271a22d3194carll vg_assert(auxv_2_07 == hw_caps_2_07); 7433b91f1779802a17344e1901f3b7c0271a22d3194carll } 74452b284b2fb907204dfae5a067e83eed98ea72dd2carll 74552b284b2fb907204dfae5a067e83eed98ea72dd2carll break; 74652b284b2fb907204dfae5a067e83eed98ea72dd2carll# endif 74717c110443e39c0c63bb298689cad31e0b4671dfesewardj 74817c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_ICACHEBSIZE: 74952b284b2fb907204dfae5a067e83eed98ea72dd2carll case AT_DCACHEBSIZE: 75017c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_UCACHEBSIZE: 75117c110443e39c0c63bb298689cad31e0b4671dfesewardj# if defined(VGP_ppc32_linux) 75217c110443e39c0c63bb298689cad31e0b4671dfesewardj /* acquire cache info */ 75317c110443e39c0c63bb298689cad31e0b4671dfesewardj if (auxv->u.a_val > 0) { 75417c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(machine_ppc32_set_clszB)( auxv->u.a_val ); 75517c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(debugLog)(2, "initimg", 7561a59a921dbfe75f7535d9dff6b76ea43a5ed961aflorian "PPC32 icache line size %u (type %u)\n", 75717c110443e39c0c63bb298689cad31e0b4671dfesewardj (UInt)auxv->u.a_val, (UInt)auxv->a_type ); 75817c110443e39c0c63bb298689cad31e0b4671dfesewardj } 759cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 76017c110443e39c0c63bb298689cad31e0b4671dfesewardj /* acquire cache info */ 76117c110443e39c0c63bb298689cad31e0b4671dfesewardj if (auxv->u.a_val > 0) { 76217c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(machine_ppc64_set_clszB)( auxv->u.a_val ); 76317c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(debugLog)(2, "initimg", 7641a59a921dbfe75f7535d9dff6b76ea43a5ed961aflorian "PPC64 icache line size %u (type %u)\n", 76517c110443e39c0c63bb298689cad31e0b4671dfesewardj (UInt)auxv->u.a_val, (UInt)auxv->a_type ); 76617c110443e39c0c63bb298689cad31e0b4671dfesewardj } 76717c110443e39c0c63bb298689cad31e0b4671dfesewardj# endif 76817c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 76917c110443e39c0c63bb298689cad31e0b4671dfesewardj 770cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \ 771cae0cc22b83ffb260ee8379e92099c5a701944cbcarll || defined(VGP_ppc64le_linux) 77217c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_IGNOREPPC: 77317c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 77417c110443e39c0c63bb298689cad31e0b4671dfesewardj# endif 77517c110443e39c0c63bb298689cad31e0b4671dfesewardj 77617c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_SECURE: 77717c110443e39c0c63bb298689cad31e0b4671dfesewardj /* If this is 1, then it means that this program is 77817c110443e39c0c63bb298689cad31e0b4671dfesewardj running suid, and therefore the dynamic linker should 77917c110443e39c0c63bb298689cad31e0b4671dfesewardj be careful about LD_PRELOAD, etc. However, since 78017c110443e39c0c63bb298689cad31e0b4671dfesewardj stage1 (the thing the kernel actually execve's) should 78117c110443e39c0c63bb298689cad31e0b4671dfesewardj never be SUID, and we need LD_PRELOAD to work for the 78217c110443e39c0c63bb298689cad31e0b4671dfesewardj client, we set AT_SECURE to 0. */ 78317c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv->u.a_val = 0; 78417c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 78517c110443e39c0c63bb298689cad31e0b4671dfesewardj 78617c110443e39c0c63bb298689cad31e0b4671dfesewardj case AT_SYSINFO: 7879bb8119b2ba66c8f93d0ba9e137332382990d6cdtom /* Trash this, because we don't reproduce it */ 7889bb8119b2ba66c8f93d0ba9e137332382990d6cdtom auxv->a_type = AT_IGNORE; 7899bb8119b2ba66c8f93d0ba9e137332382990d6cdtom break; 7909bb8119b2ba66c8f93d0ba9e137332382990d6cdtom 791cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# if !defined(VGP_ppc32_linux) && !defined(VGP_ppc64be_linux) \ 792ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes && !defined(VGP_ppc64le_linux) \ 793ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes && !defined(VGP_mips32_linux) && !defined(VGP_mips64_linux) 794d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj case AT_SYSINFO_EHDR: { 79517c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Trash this, because we don't reproduce it */ 796d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj const NSegment* ehdrseg = VG_(am_find_nsegment)((Addr)auxv->u.a_ptr); 7979bb8119b2ba66c8f93d0ba9e137332382990d6cdtom vg_assert(ehdrseg); 7989bb8119b2ba66c8f93d0ba9e137332382990d6cdtom VG_(am_munmap_valgrind)(ehdrseg->start, ehdrseg->end - ehdrseg->start); 79917c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv->a_type = AT_IGNORE; 80017c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 801d2be8cc17fed04cbd701e9a2cc1cf365ff45cc44sewardj } 8029bb8119b2ba66c8f93d0ba9e137332382990d6cdtom# endif 80317c110443e39c0c63bb298689cad31e0b4671dfesewardj 8049c6533d2c47883f9e491a2a388c5503b3bf4c002tom case AT_RANDOM: 8059c6533d2c47883f9e491a2a388c5503b3bf4c002tom /* points to 16 random bytes - we need to ensure this is 8069c6533d2c47883f9e491a2a388c5503b3bf4c002tom propagated to the client as glibc will assume it is 8079c6533d2c47883f9e491a2a388c5503b3bf4c002tom present if it is built for kernel 2.6.29 or later */ 8089c6533d2c47883f9e491a2a388c5503b3bf4c002tom auxv->u.a_ptr = strtab; 8099c6533d2c47883f9e491a2a388c5503b3bf4c002tom VG_(memcpy)(strtab, orig_auxv->u.a_ptr, 16); 8109c6533d2c47883f9e491a2a388c5503b3bf4c002tom strtab += 16; 8119c6533d2c47883f9e491a2a388c5503b3bf4c002tom break; 8129c6533d2c47883f9e491a2a388c5503b3bf4c002tom 81320a8a6125459a919a9561f8480b38f78f7c91fe9tom case AT_EXECFN: 81420a8a6125459a919a9561f8480b38f78f7c91fe9tom /* points to the executable filename */ 81520a8a6125459a919a9561f8480b38f78f7c91fe9tom auxv->u.a_ptr = copy_str(&strtab, VG_(args_the_exename)); 81620a8a6125459a919a9561f8480b38f78f7c91fe9tom break; 81720a8a6125459a919a9561f8480b38f78f7c91fe9tom 81817c110443e39c0c63bb298689cad31e0b4671dfesewardj default: 81917c110443e39c0c63bb298689cad31e0b4671dfesewardj /* stomp out anything we don't know about */ 82017c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(debugLog)(2, "initimg", 821a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "stomping auxv entry %llu\n", 82217c110443e39c0c63bb298689cad31e0b4671dfesewardj (ULong)auxv->a_type); 82317c110443e39c0c63bb298689cad31e0b4671dfesewardj auxv->a_type = AT_IGNORE; 82417c110443e39c0c63bb298689cad31e0b4671dfesewardj break; 82517c110443e39c0c63bb298689cad31e0b4671dfesewardj } 82617c110443e39c0c63bb298689cad31e0b4671dfesewardj } 82717c110443e39c0c63bb298689cad31e0b4671dfesewardj *auxv = *orig_auxv; 82817c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(auxv->a_type == AT_NULL); 82917c110443e39c0c63bb298689cad31e0b4671dfesewardj 83017c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert((strtab-stringbase) == stringsize); 83117c110443e39c0c63bb298689cad31e0b4671dfesewardj 83217c110443e39c0c63bb298689cad31e0b4671dfesewardj /* client_SP is pointing at client's argc/argv */ 83317c110443e39c0c63bb298689cad31e0b4671dfesewardj 834a0b6b2cf9abc7b0d87be1215a245eaccc0452af9bart if (0) VG_(printf)("startup SP = %#lx\n", client_SP); 83517c110443e39c0c63bb298689cad31e0b4671dfesewardj return client_SP; 83617c110443e39c0c63bb298689cad31e0b4671dfesewardj} 83717c110443e39c0c63bb298689cad31e0b4671dfesewardj 83817c110443e39c0c63bb298689cad31e0b4671dfesewardj 83917c110443e39c0c63bb298689cad31e0b4671dfesewardj/* Allocate the client data segment. It is an expandable anonymous 84017c110443e39c0c63bb298689cad31e0b4671dfesewardj mapping abutting a shrinkable reservation of size max_dseg_size. 84117c110443e39c0c63bb298689cad31e0b4671dfesewardj The data segment starts at VG_(brk_base), which is page-aligned, 84217c110443e39c0c63bb298689cad31e0b4671dfesewardj and runs up to VG_(brk_limit), which isn't. */ 84317c110443e39c0c63bb298689cad31e0b4671dfesewardj 84417c110443e39c0c63bb298689cad31e0b4671dfesewardjstatic void setup_client_dataseg ( SizeT max_size ) 84517c110443e39c0c63bb298689cad31e0b4671dfesewardj{ 84617c110443e39c0c63bb298689cad31e0b4671dfesewardj Bool ok; 84717c110443e39c0c63bb298689cad31e0b4671dfesewardj SysRes sres; 84817c110443e39c0c63bb298689cad31e0b4671dfesewardj Addr anon_start = VG_(brk_base); 84917c110443e39c0c63bb298689cad31e0b4671dfesewardj SizeT anon_size = VKI_PAGE_SIZE; 85017c110443e39c0c63bb298689cad31e0b4671dfesewardj Addr resvn_start = anon_start + anon_size; 85117c110443e39c0c63bb298689cad31e0b4671dfesewardj SizeT resvn_size = max_size - anon_size; 85217c110443e39c0c63bb298689cad31e0b4671dfesewardj 85317c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_IS_PAGE_ALIGNED(anon_size)); 85417c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_IS_PAGE_ALIGNED(resvn_size)); 85517c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_IS_PAGE_ALIGNED(anon_start)); 85617c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_IS_PAGE_ALIGNED(resvn_start)); 85717c110443e39c0c63bb298689cad31e0b4671dfesewardj 85817c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Because there's been no brk activity yet: */ 85917c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(VG_(brk_base) == VG_(brk_limit)); 86017c110443e39c0c63bb298689cad31e0b4671dfesewardj 86117c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Try to create the data seg and associated reservation where 86217c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(brk_base) says. */ 86317c110443e39c0c63bb298689cad31e0b4671dfesewardj ok = VG_(am_create_reservation)( 86417c110443e39c0c63bb298689cad31e0b4671dfesewardj resvn_start, 86517c110443e39c0c63bb298689cad31e0b4671dfesewardj resvn_size, 86617c110443e39c0c63bb298689cad31e0b4671dfesewardj SmLower, 86717c110443e39c0c63bb298689cad31e0b4671dfesewardj anon_size 86817c110443e39c0c63bb298689cad31e0b4671dfesewardj ); 86917c110443e39c0c63bb298689cad31e0b4671dfesewardj 87017c110443e39c0c63bb298689cad31e0b4671dfesewardj if (!ok) { 87117c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Hmm, that didn't work. Well, let aspacem suggest an address 87217c110443e39c0c63bb298689cad31e0b4671dfesewardj it likes better, and try again with that. */ 87317c110443e39c0c63bb298689cad31e0b4671dfesewardj anon_start = VG_(am_get_advisory_client_simple) 87417c110443e39c0c63bb298689cad31e0b4671dfesewardj ( 0/*floating*/, anon_size+resvn_size, &ok ); 87517c110443e39c0c63bb298689cad31e0b4671dfesewardj if (ok) { 87617c110443e39c0c63bb298689cad31e0b4671dfesewardj resvn_start = anon_start + anon_size; 87717c110443e39c0c63bb298689cad31e0b4671dfesewardj ok = VG_(am_create_reservation)( 87817c110443e39c0c63bb298689cad31e0b4671dfesewardj resvn_start, 87917c110443e39c0c63bb298689cad31e0b4671dfesewardj resvn_size, 88017c110443e39c0c63bb298689cad31e0b4671dfesewardj SmLower, 88117c110443e39c0c63bb298689cad31e0b4671dfesewardj anon_size 88217c110443e39c0c63bb298689cad31e0b4671dfesewardj ); 88317c110443e39c0c63bb298689cad31e0b4671dfesewardj if (ok) 88417c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(brk_base) = VG_(brk_limit) = anon_start; 88517c110443e39c0c63bb298689cad31e0b4671dfesewardj } 88617c110443e39c0c63bb298689cad31e0b4671dfesewardj /* that too might have failed, but if it has, we're hosed: there 88717c110443e39c0c63bb298689cad31e0b4671dfesewardj is no Plan C. */ 88817c110443e39c0c63bb298689cad31e0b4671dfesewardj } 88917c110443e39c0c63bb298689cad31e0b4671dfesewardj vg_assert(ok); 89017c110443e39c0c63bb298689cad31e0b4671dfesewardj 89117c110443e39c0c63bb298689cad31e0b4671dfesewardj /* We make the data segment (heap) executable because LinuxThreads on 89217c110443e39c0c63bb298689cad31e0b4671dfesewardj ppc32 creates trampolines in this area. Also, on x86/Linux the data 89317c110443e39c0c63bb298689cad31e0b4671dfesewardj segment is RWX natively, at least according to /proc/self/maps. 89417c110443e39c0c63bb298689cad31e0b4671dfesewardj Also, having a non-executable data seg would kill any program which 89517c110443e39c0c63bb298689cad31e0b4671dfesewardj tried to create code in the data seg and then run it. */ 89617c110443e39c0c63bb298689cad31e0b4671dfesewardj sres = VG_(am_mmap_anon_fixed_client)( 89717c110443e39c0c63bb298689cad31e0b4671dfesewardj anon_start, 89817c110443e39c0c63bb298689cad31e0b4671dfesewardj anon_size, 89917c110443e39c0c63bb298689cad31e0b4671dfesewardj VKI_PROT_READ|VKI_PROT_WRITE|VKI_PROT_EXEC 90017c110443e39c0c63bb298689cad31e0b4671dfesewardj ); 901cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(!sr_isError(sres)); 902cda2f0fbda4c4b2644babc830244be8aed95de1dnjn vg_assert(sr_Res(sres) == anon_start); 90317c110443e39c0c63bb298689cad31e0b4671dfesewardj} 90417c110443e39c0c63bb298689cad31e0b4671dfesewardj 90517c110443e39c0c63bb298689cad31e0b4671dfesewardj 90617c110443e39c0c63bb298689cad31e0b4671dfesewardj/*====================================================================*/ 90717c110443e39c0c63bb298689cad31e0b4671dfesewardj/*=== TOP-LEVEL: VG_(setup_client_initial_image) ===*/ 90817c110443e39c0c63bb298689cad31e0b4671dfesewardj/*====================================================================*/ 90917c110443e39c0c63bb298689cad31e0b4671dfesewardj 91017c110443e39c0c63bb298689cad31e0b4671dfesewardj/* Create the client's initial memory image. */ 91152b284b2fb907204dfae5a067e83eed98ea72dd2carllIIFinaliseImageInfo VG_(ii_create_image)( IICreateImageInfo iicii, 91252b284b2fb907204dfae5a067e83eed98ea72dd2carll const VexArchInfo* vex_archinfo ) 91317c110443e39c0c63bb298689cad31e0b4671dfesewardj{ 914f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj ExeInfo info; 915f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj HChar** env = NULL; 916f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj 917a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes IIFinaliseImageInfo iifii = { 918a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes .clstack_max_size = 0, 919a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes .initial_client_SP = 0, 920a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes .initial_client_IP = 0, 921a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes .initial_client_TOC = 0, 922a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes .client_auxv = NULL, 923a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes .arch_elf_state = VKI_INIT_ARCH_ELF_STATE, 924a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes }; 92517c110443e39c0c63bb298689cad31e0b4671dfesewardj 92617c110443e39c0c63bb298689cad31e0b4671dfesewardj //-------------------------------------------------------------- 92717c110443e39c0c63bb298689cad31e0b4671dfesewardj // Load client executable, finding in $PATH if necessary 92817c110443e39c0c63bb298689cad31e0b4671dfesewardj // p: get_helprequest_and_toolname() [for 'exec', 'need_help'] 92917c110443e39c0c63bb298689cad31e0b4671dfesewardj // p: layout_remaining_space [so there's space] 93017c110443e39c0c63bb298689cad31e0b4671dfesewardj //-------------------------------------------------------------- 93117c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(debugLog)(1, "initimg", "Loading client\n"); 93217c110443e39c0c63bb298689cad31e0b4671dfesewardj 93317c110443e39c0c63bb298689cad31e0b4671dfesewardj if (VG_(args_the_exename) == NULL) 93417c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(err_missing_prog)(); 93517c110443e39c0c63bb298689cad31e0b4671dfesewardj 936a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(memset)(&info, 0, sizeof(info)); 937a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes info.arch_elf_state = &iifii.arch_elf_state; 938a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 939f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj load_client(&info, &iifii.initial_client_IP, &iifii.initial_client_TOC); 94017c110443e39c0c63bb298689cad31e0b4671dfesewardj 94117c110443e39c0c63bb298689cad31e0b4671dfesewardj //-------------------------------------------------------------- 94217c110443e39c0c63bb298689cad31e0b4671dfesewardj // Set up client's environment 94317c110443e39c0c63bb298689cad31e0b4671dfesewardj // p: set-libdir [for VG_(libdir)] 94417c110443e39c0c63bb298689cad31e0b4671dfesewardj // p: get_helprequest_and_toolname [for toolname] 94517c110443e39c0c63bb298689cad31e0b4671dfesewardj //-------------------------------------------------------------- 94617c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(debugLog)(1, "initimg", "Setup client env\n"); 947f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj env = setup_client_env(iicii.envp, iicii.toolname); 94817c110443e39c0c63bb298689cad31e0b4671dfesewardj 94917c110443e39c0c63bb298689cad31e0b4671dfesewardj //-------------------------------------------------------------- 95017c110443e39c0c63bb298689cad31e0b4671dfesewardj // Setup client stack, eip, and VG_(client_arg[cv]) 95117c110443e39c0c63bb298689cad31e0b4671dfesewardj // p: load_client() [for 'info'] 95217c110443e39c0c63bb298689cad31e0b4671dfesewardj // p: fix_environment() [for 'env'] 95317c110443e39c0c63bb298689cad31e0b4671dfesewardj //-------------------------------------------------------------- 95417c110443e39c0c63bb298689cad31e0b4671dfesewardj { 9555bdfbd29e26bc536c0779ec2e6b85bbb0ebd622csewardj /* When allocating space for the client stack on Linux, take 95695d86c091a218e904e912354efa4f952a9712e82sewardj notice of the --main-stacksize value. This makes it possible 9575bdfbd29e26bc536c0779ec2e6b85bbb0ebd622csewardj to run programs with very large (primary) stack requirements 95895d86c091a218e904e912354efa4f952a9712e82sewardj simply by specifying --main-stacksize. */ 95995d86c091a218e904e912354efa4f952a9712e82sewardj /* Logic is as follows: 96095d86c091a218e904e912354efa4f952a9712e82sewardj - by default, use the client's current stack rlimit 96195d86c091a218e904e912354efa4f952a9712e82sewardj - if that exceeds 16M, clamp to 16M 96295d86c091a218e904e912354efa4f952a9712e82sewardj - if a larger --main-stacksize value is specified, use that instead 96395d86c091a218e904e912354efa4f952a9712e82sewardj - in all situations, the minimum allowed stack size is 1M 96495d86c091a218e904e912354efa4f952a9712e82sewardj */ 965f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj void* init_sp = iicii.argv - 1; 96617c110443e39c0c63bb298689cad31e0b4671dfesewardj SizeT m1 = 1024 * 1024; 96717c110443e39c0c63bb298689cad31e0b4671dfesewardj SizeT m16 = 16 * m1; 96895d86c091a218e904e912354efa4f952a9712e82sewardj SizeT szB = (SizeT)VG_(client_rlimit_stack).rlim_cur; 96995d86c091a218e904e912354efa4f952a9712e82sewardj if (szB < m1) szB = m1; 97095d86c091a218e904e912354efa4f952a9712e82sewardj if (szB > m16) szB = m16; 97195d86c091a218e904e912354efa4f952a9712e82sewardj if (VG_(clo_main_stacksize) > 0) szB = VG_(clo_main_stacksize); 97295d86c091a218e904e912354efa4f952a9712e82sewardj if (szB < m1) szB = m1; 97395d86c091a218e904e912354efa4f952a9712e82sewardj szB = VG_PGROUNDUP(szB); 97495d86c091a218e904e912354efa4f952a9712e82sewardj VG_(debugLog)(1, "initimg", 975a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "Setup client stack: size will be %lu\n", szB); 97695d86c091a218e904e912354efa4f952a9712e82sewardj 97795d86c091a218e904e912354efa4f952a9712e82sewardj iifii.clstack_max_size = szB; 97817c110443e39c0c63bb298689cad31e0b4671dfesewardj 979f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj iifii.initial_client_SP 98017c110443e39c0c63bb298689cad31e0b4671dfesewardj = setup_client_stack( init_sp, env, 981f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj &info, &iifii.client_auxv, 98252b284b2fb907204dfae5a067e83eed98ea72dd2carll iicii.clstack_end, iifii.clstack_max_size, 98352b284b2fb907204dfae5a067e83eed98ea72dd2carll vex_archinfo ); 98417c110443e39c0c63bb298689cad31e0b4671dfesewardj 98517c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(free)(env); 98617c110443e39c0c63bb298689cad31e0b4671dfesewardj 98717c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(debugLog)(2, "initimg", 98817c110443e39c0c63bb298689cad31e0b4671dfesewardj "Client info: " 9895bdfbd29e26bc536c0779ec2e6b85bbb0ebd622csewardj "initial_IP=%p initial_TOC=%p brk_base=%p\n", 990f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj (void*)(iifii.initial_client_IP), 991f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj (void*)(iifii.initial_client_TOC), 99217c110443e39c0c63bb298689cad31e0b4671dfesewardj (void*)VG_(brk_base) ); 9935bdfbd29e26bc536c0779ec2e6b85bbb0ebd622csewardj VG_(debugLog)(2, "initimg", 9945bdfbd29e26bc536c0779ec2e6b85bbb0ebd622csewardj "Client info: " 995a5e06c36bf9d93461bc8c4351e960888020ea1c4florian "initial_SP=%p max_stack_size=%lu\n", 9965bdfbd29e26bc536c0779ec2e6b85bbb0ebd622csewardj (void*)(iifii.initial_client_SP), 997a5e06c36bf9d93461bc8c4351e960888020ea1c4florian iifii.clstack_max_size ); 99817c110443e39c0c63bb298689cad31e0b4671dfesewardj } 99917c110443e39c0c63bb298689cad31e0b4671dfesewardj 100017c110443e39c0c63bb298689cad31e0b4671dfesewardj //-------------------------------------------------------------- 100117c110443e39c0c63bb298689cad31e0b4671dfesewardj // Setup client data (brk) segment. Initially a 1-page segment 100217c110443e39c0c63bb298689cad31e0b4671dfesewardj // which abuts a shrinkable reservation. 100317c110443e39c0c63bb298689cad31e0b4671dfesewardj // p: load_client() [for 'info' and hence VG_(brk_base)] 100417c110443e39c0c63bb298689cad31e0b4671dfesewardj //-------------------------------------------------------------- 100517c110443e39c0c63bb298689cad31e0b4671dfesewardj { 100617c110443e39c0c63bb298689cad31e0b4671dfesewardj SizeT m1 = 1024 * 1024; 100717c110443e39c0c63bb298689cad31e0b4671dfesewardj SizeT m8 = 8 * m1; 100817c110443e39c0c63bb298689cad31e0b4671dfesewardj SizeT dseg_max_size = (SizeT)VG_(client_rlimit_data).rlim_cur; 100917c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_(debugLog)(1, "initimg", "Setup client data (brk) segment\n"); 101017c110443e39c0c63bb298689cad31e0b4671dfesewardj if (dseg_max_size < m1) dseg_max_size = m1; 101117c110443e39c0c63bb298689cad31e0b4671dfesewardj if (dseg_max_size > m8) dseg_max_size = m8; 101217c110443e39c0c63bb298689cad31e0b4671dfesewardj dseg_max_size = VG_PGROUNDUP(dseg_max_size); 101317c110443e39c0c63bb298689cad31e0b4671dfesewardj 101417c110443e39c0c63bb298689cad31e0b4671dfesewardj setup_client_dataseg( dseg_max_size ); 101517c110443e39c0c63bb298689cad31e0b4671dfesewardj } 101617c110443e39c0c63bb298689cad31e0b4671dfesewardj 1017a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(free)(info.interp_name); info.interp_name = NULL; 1018a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes VG_(free)(info.interp_args); info.interp_args = NULL; 1019f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj return iifii; 102017c110443e39c0c63bb298689cad31e0b4671dfesewardj} 102117c110443e39c0c63bb298689cad31e0b4671dfesewardj 102217c110443e39c0c63bb298689cad31e0b4671dfesewardj 102317c110443e39c0c63bb298689cad31e0b4671dfesewardj/*====================================================================*/ 102417c110443e39c0c63bb298689cad31e0b4671dfesewardj/*=== TOP-LEVEL: VG_(finalise_thread1state) ===*/ 102517c110443e39c0c63bb298689cad31e0b4671dfesewardj/*====================================================================*/ 102617c110443e39c0c63bb298689cad31e0b4671dfesewardj 1027f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj/* Just before starting the client, we may need to make final 1028f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj adjustments to its initial image. Also we need to set up the VEX 1029f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj guest state for thread 1 (the root thread) and copy in essential 1030f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj starting values. This is handed the IIFinaliseImageInfo created by 1031f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj VG_(ii_create_image). 1032f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj*/ 1033f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardjvoid VG_(ii_finalise_image)( IIFinaliseImageInfo iifii ) 103417c110443e39c0c63bb298689cad31e0b4671dfesewardj{ 1035f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj ThreadArchState* arch = &VG_(threads)[1].arch; 1036f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj 103717c110443e39c0c63bb298689cad31e0b4671dfesewardj /* On Linux we get client_{ip/sp/toc}, and start the client with 103817c110443e39c0c63bb298689cad31e0b4671dfesewardj all other registers zeroed. */ 103917c110443e39c0c63bb298689cad31e0b4671dfesewardj 104017c110443e39c0c63bb298689cad31e0b4671dfesewardj# if defined(VGP_x86_linux) 1041737548c7409e5d46b72a914ae1dc6d1a48199d25florian vg_assert(0 == sizeof(VexGuestX86State) % LibVEX_GUEST_STATE_ALIGN); 104217c110443e39c0c63bb298689cad31e0b4671dfesewardj 104317c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Zero out the initial state, and set up the simulated FPU in a 104417c110443e39c0c63bb298689cad31e0b4671dfesewardj sane way. */ 104517c110443e39c0c63bb298689cad31e0b4671dfesewardj LibVEX_GuestX86_initialise(&arch->vex); 104617c110443e39c0c63bb298689cad31e0b4671dfesewardj 10477cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Zero out the shadow areas. */ 10487cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestX86State)); 10497cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestX86State)); 105017c110443e39c0c63bb298689cad31e0b4671dfesewardj 105117c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Put essential stuff into the new state. */ 1052f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj arch->vex.guest_ESP = iifii.initial_client_SP; 1053f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj arch->vex.guest_EIP = iifii.initial_client_IP; 105417c110443e39c0c63bb298689cad31e0b4671dfesewardj 105517c110443e39c0c63bb298689cad31e0b4671dfesewardj /* initialise %cs, %ds and %ss to point at the operating systems 105690ffbe3cc96002ab396de87fb78930f6059ece82sewardj default code, data and stack segments. Also %es (see #291253). */ 105717c110443e39c0c63bb298689cad31e0b4671dfesewardj asm volatile("movw %%cs, %0" : : "m" (arch->vex.guest_CS)); 105817c110443e39c0c63bb298689cad31e0b4671dfesewardj asm volatile("movw %%ds, %0" : : "m" (arch->vex.guest_DS)); 105917c110443e39c0c63bb298689cad31e0b4671dfesewardj asm volatile("movw %%ss, %0" : : "m" (arch->vex.guest_SS)); 106090ffbe3cc96002ab396de87fb78930f6059ece82sewardj asm volatile("movw %%es, %0" : : "m" (arch->vex.guest_ES)); 106117c110443e39c0c63bb298689cad31e0b4671dfesewardj 106217c110443e39c0c63bb298689cad31e0b4671dfesewardj# elif defined(VGP_amd64_linux) 1063737548c7409e5d46b72a914ae1dc6d1a48199d25florian vg_assert(0 == sizeof(VexGuestAMD64State) % LibVEX_GUEST_STATE_ALIGN); 106417c110443e39c0c63bb298689cad31e0b4671dfesewardj 106517c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Zero out the initial state, and set up the simulated FPU in a 106617c110443e39c0c63bb298689cad31e0b4671dfesewardj sane way. */ 106717c110443e39c0c63bb298689cad31e0b4671dfesewardj LibVEX_GuestAMD64_initialise(&arch->vex); 106817c110443e39c0c63bb298689cad31e0b4671dfesewardj 10697cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Zero out the shadow areas. */ 10707cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestAMD64State)); 10717cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestAMD64State)); 107217c110443e39c0c63bb298689cad31e0b4671dfesewardj 107317c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Put essential stuff into the new state. */ 1074f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj arch->vex.guest_RSP = iifii.initial_client_SP; 1075f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj arch->vex.guest_RIP = iifii.initial_client_IP; 107617c110443e39c0c63bb298689cad31e0b4671dfesewardj 107717c110443e39c0c63bb298689cad31e0b4671dfesewardj# elif defined(VGP_ppc32_linux) 1078737548c7409e5d46b72a914ae1dc6d1a48199d25florian vg_assert(0 == sizeof(VexGuestPPC32State) % LibVEX_GUEST_STATE_ALIGN); 107917c110443e39c0c63bb298689cad31e0b4671dfesewardj 108017c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Zero out the initial state, and set up the simulated FPU in a 108117c110443e39c0c63bb298689cad31e0b4671dfesewardj sane way. */ 108217c110443e39c0c63bb298689cad31e0b4671dfesewardj LibVEX_GuestPPC32_initialise(&arch->vex); 108317c110443e39c0c63bb298689cad31e0b4671dfesewardj 10847cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Zero out the shadow areas. */ 10857cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC32State)); 10867cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC32State)); 108717c110443e39c0c63bb298689cad31e0b4671dfesewardj 108817c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Put essential stuff into the new state. */ 1089f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj arch->vex.guest_GPR1 = iifii.initial_client_SP; 1090f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj arch->vex.guest_CIA = iifii.initial_client_IP; 109117c110443e39c0c63bb298689cad31e0b4671dfesewardj 1092cae0cc22b83ffb260ee8379e92099c5a701944cbcarll# elif defined(VGP_ppc64be_linux) || defined(VGP_ppc64le_linux) 1093737548c7409e5d46b72a914ae1dc6d1a48199d25florian vg_assert(0 == sizeof(VexGuestPPC64State) % LibVEX_GUEST_STATE_ALIGN); 109417c110443e39c0c63bb298689cad31e0b4671dfesewardj 109517c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Zero out the initial state, and set up the simulated FPU in a 109617c110443e39c0c63bb298689cad31e0b4671dfesewardj sane way. */ 109717c110443e39c0c63bb298689cad31e0b4671dfesewardj LibVEX_GuestPPC64_initialise(&arch->vex); 109817c110443e39c0c63bb298689cad31e0b4671dfesewardj 10997cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj /* Zero out the shadow areas. */ 11007cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestPPC64State)); 11017cf4e6b6aed533af53339f36099ed244dc4a5b7fsewardj VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestPPC64State)); 110217c110443e39c0c63bb298689cad31e0b4671dfesewardj 110317c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Put essential stuff into the new state. */ 1104f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj arch->vex.guest_GPR1 = iifii.initial_client_SP; 1105f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj arch->vex.guest_GPR2 = iifii.initial_client_TOC; 1106f9d2f9b5ec3b8febc8465c05e90c8a5f6de3d6a4sewardj arch->vex.guest_CIA = iifii.initial_client_IP; 1107582d58245637ab05272d89fb94b12fd0f18fa0f8carll#if defined(VGP_ppc64le_linux) 1108582d58245637ab05272d89fb94b12fd0f18fa0f8carll arch->vex.guest_GPR12 = iifii.initial_client_IP; 1109582d58245637ab05272d89fb94b12fd0f18fa0f8carll#endif 111017c110443e39c0c63bb298689cad31e0b4671dfesewardj 1111f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm_linux) 111259570ffbe31930ab4d678754daaeec0715117a3dsewardj /* Zero out the initial state, and set up the simulated FPU in a 111359570ffbe31930ab4d678754daaeec0715117a3dsewardj sane way. */ 111459570ffbe31930ab4d678754daaeec0715117a3dsewardj LibVEX_GuestARM_initialise(&arch->vex); 111559570ffbe31930ab4d678754daaeec0715117a3dsewardj 111659570ffbe31930ab4d678754daaeec0715117a3dsewardj /* Zero out the shadow areas. */ 111759570ffbe31930ab4d678754daaeec0715117a3dsewardj VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestARMState)); 111859570ffbe31930ab4d678754daaeec0715117a3dsewardj VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestARMState)); 111959570ffbe31930ab4d678754daaeec0715117a3dsewardj 11209dcfdffec13e259386e088f9be86ea8b8e2756c0sewardj arch->vex.guest_R13 = iifii.initial_client_SP; 11219dcfdffec13e259386e088f9be86ea8b8e2756c0sewardj arch->vex.guest_R15T = iifii.initial_client_IP; 112259570ffbe31930ab4d678754daaeec0715117a3dsewardj 112359570ffbe31930ab4d678754daaeec0715117a3dsewardj /* This is just EABI stuff. */ 112459570ffbe31930ab4d678754daaeec0715117a3dsewardj // FIXME jrs: what's this for? 112559570ffbe31930ab4d678754daaeec0715117a3dsewardj arch->vex.guest_R1 = iifii.initial_client_SP; 112659570ffbe31930ab4d678754daaeec0715117a3dsewardj 1127f0c1250e324f6684757c6a15545366447ef1d64fsewardj# elif defined(VGP_arm64_linux) 1128f0c1250e324f6684757c6a15545366447ef1d64fsewardj /* Zero out the initial state. */ 1129f0c1250e324f6684757c6a15545366447ef1d64fsewardj LibVEX_GuestARM64_initialise(&arch->vex); 1130f0c1250e324f6684757c6a15545366447ef1d64fsewardj 1131f0c1250e324f6684757c6a15545366447ef1d64fsewardj /* Zero out the shadow areas. */ 1132f0c1250e324f6684757c6a15545366447ef1d64fsewardj VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestARM64State)); 1133f0c1250e324f6684757c6a15545366447ef1d64fsewardj VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestARM64State)); 1134f0c1250e324f6684757c6a15545366447ef1d64fsewardj 11350345188cc1524a809b8d7fe8785e1da098d9cbe4sewardj arch->vex.guest_XSP = iifii.initial_client_SP; 11360345188cc1524a809b8d7fe8785e1da098d9cbe4sewardj arch->vex.guest_PC = iifii.initial_client_IP; 1137f0c1250e324f6684757c6a15545366447ef1d64fsewardj 1138b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj# elif defined(VGP_s390x_linux) 1139737548c7409e5d46b72a914ae1dc6d1a48199d25florian vg_assert(0 == sizeof(VexGuestS390XState) % LibVEX_GUEST_STATE_ALIGN); 1140b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1141b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Zero out the initial state. This also sets the guest_fpc to 0, which 1142b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj is also done by the kernel for the fpc during execve. */ 1143b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj LibVEX_GuestS390X_initialise(&arch->vex); 1144b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1145ccb843b2ba2c176708bfa1764ca8e4db31722e90florian /* Mark all registers as undefined ... */ 1146ccb843b2ba2c176708bfa1764ca8e4db31722e90florian VG_(memset)(&arch->vex_shadow1, 0xFF, sizeof(VexGuestS390XState)); 1147ccb843b2ba2c176708bfa1764ca8e4db31722e90florian VG_(memset)(&arch->vex_shadow2, 0x00, sizeof(VexGuestS390XState)); 1148ccb843b2ba2c176708bfa1764ca8e4db31722e90florian /* ... except SP, FPC, and IA */ 11497e5a9c29450b41cba63ac04b9c027d3b97b367eccborntra arch->vex_shadow1.guest_SP = 0; 11507e5a9c29450b41cba63ac04b9c027d3b97b367eccborntra arch->vex_shadow1.guest_fpc = 0; 11517e5a9c29450b41cba63ac04b9c027d3b97b367eccborntra arch->vex_shadow1.guest_IA = 0; 1152b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 1153b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj /* Put essential stuff into the new state. */ 1154b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj arch->vex.guest_SP = iifii.initial_client_SP; 1155b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj arch->vex.guest_IA = iifii.initial_client_IP; 1156ccb843b2ba2c176708bfa1764ca8e4db31722e90florian /* See sys_execve in <linux>/arch/s390/kernel/process.c */ 1157ccb843b2ba2c176708bfa1764ca8e4db31722e90florian arch->vex.guest_fpc = 0; 1158ccb843b2ba2c176708bfa1764ca8e4db31722e90florian 1159ccb843b2ba2c176708bfa1764ca8e4db31722e90florian /* Tell the tool about the registers we just wrote */ 1160ccb843b2ba2c176708bfa1764ca8e4db31722e90florian VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_STACK_PTR, 8); 1161ccb843b2ba2c176708bfa1764ca8e4db31722e90florian VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_FPC_REG, 4); 1162ccb843b2ba2c176708bfa1764ca8e4db31722e90florian VG_TRACK(post_reg_write, Vg_CoreStartup, /*tid*/1, VG_O_INSTR_PTR, 8); 116381de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian 116481de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian /* At the end of this function there is code to mark all guest state 116581de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian registers as defined. For s390 that would be wrong, because the ABI 116681de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian says that all registers except SP, IA, and FPC are undefined upon 116781de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian process startup. */ 116881de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian#define PRECISE_GUEST_REG_DEFINEDNESS_AT_STARTUP 1 1169b5b87408c0c99f9f6938d8cd921e2a5f420577c4sewardj 11705db15403e889d4db339b342bc2a824ef0bfaa654sewardj# elif defined(VGP_mips32_linux) 1171737548c7409e5d46b72a914ae1dc6d1a48199d25florian vg_assert(0 == sizeof(VexGuestMIPS32State) % LibVEX_GUEST_STATE_ALIGN); 11725db15403e889d4db339b342bc2a824ef0bfaa654sewardj /* Zero out the initial state, and set up the simulated FPU in a 11735db15403e889d4db339b342bc2a824ef0bfaa654sewardj sane way. */ 11745db15403e889d4db339b342bc2a824ef0bfaa654sewardj LibVEX_GuestMIPS32_initialise(&arch->vex); 11755db15403e889d4db339b342bc2a824ef0bfaa654sewardj 11765db15403e889d4db339b342bc2a824ef0bfaa654sewardj /* Zero out the shadow areas. */ 11775db15403e889d4db339b342bc2a824ef0bfaa654sewardj VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestMIPS32State)); 11785db15403e889d4db339b342bc2a824ef0bfaa654sewardj VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestMIPS32State)); 11795db15403e889d4db339b342bc2a824ef0bfaa654sewardj 11805db15403e889d4db339b342bc2a824ef0bfaa654sewardj arch->vex.guest_r29 = iifii.initial_client_SP; 11815db15403e889d4db339b342bc2a824ef0bfaa654sewardj arch->vex.guest_PC = iifii.initial_client_IP; 11825db15403e889d4db339b342bc2a824ef0bfaa654sewardj arch->vex.guest_r31 = iifii.initial_client_SP; 11835db15403e889d4db339b342bc2a824ef0bfaa654sewardj 1184a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes if (iifii.arch_elf_state.overall_fp_mode == VKI_FP_FR1) { 1185a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes arch->vex.guest_CP0_status |= MIPS_CP0_STATUS_FR; 1186a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes } 1187a0664b9ca67b594bd6f570a61d3301167a24750cElliott Hughes 11884df0bfc0614379192c780c944415dc420d9cfe8epetarj# elif defined(VGP_mips64_linux) 1189737548c7409e5d46b72a914ae1dc6d1a48199d25florian vg_assert(0 == sizeof(VexGuestMIPS64State) % LibVEX_GUEST_STATE_ALIGN); 11904df0bfc0614379192c780c944415dc420d9cfe8epetarj /* Zero out the initial state, and set up the simulated FPU in a 11914df0bfc0614379192c780c944415dc420d9cfe8epetarj sane way. */ 11924df0bfc0614379192c780c944415dc420d9cfe8epetarj LibVEX_GuestMIPS64_initialise(&arch->vex); 11934df0bfc0614379192c780c944415dc420d9cfe8epetarj 11944df0bfc0614379192c780c944415dc420d9cfe8epetarj /* Zero out the shadow areas. */ 11954df0bfc0614379192c780c944415dc420d9cfe8epetarj VG_(memset)(&arch->vex_shadow1, 0, sizeof(VexGuestMIPS64State)); 11964df0bfc0614379192c780c944415dc420d9cfe8epetarj VG_(memset)(&arch->vex_shadow2, 0, sizeof(VexGuestMIPS64State)); 11974df0bfc0614379192c780c944415dc420d9cfe8epetarj 11984df0bfc0614379192c780c944415dc420d9cfe8epetarj arch->vex.guest_r29 = iifii.initial_client_SP; 11994df0bfc0614379192c780c944415dc420d9cfe8epetarj arch->vex.guest_PC = iifii.initial_client_IP; 12004df0bfc0614379192c780c944415dc420d9cfe8epetarj arch->vex.guest_r31 = iifii.initial_client_SP; 12014df0bfc0614379192c780c944415dc420d9cfe8epetarj 120217c110443e39c0c63bb298689cad31e0b4671dfesewardj# else 120317c110443e39c0c63bb298689cad31e0b4671dfesewardj# error Unknown platform 120417c110443e39c0c63bb298689cad31e0b4671dfesewardj# endif 120517c110443e39c0c63bb298689cad31e0b4671dfesewardj 120681de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian# if !defined(PRECISE_GUEST_REG_DEFINEDNESS_AT_STARTUP) 120717c110443e39c0c63bb298689cad31e0b4671dfesewardj /* Tell the tool that we just wrote to the registers. */ 120817c110443e39c0c63bb298689cad31e0b4671dfesewardj VG_TRACK( post_reg_write, Vg_CoreStartup, /*tid*/1, /*offset*/0, 120917c110443e39c0c63bb298689cad31e0b4671dfesewardj sizeof(VexGuestArchState)); 121081de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian# endif 121181de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian 121281de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian /* Tell the tool about the client data segment and then kill it which will 121381de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian make it inaccessible/unaddressable. */ 121481de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian const NSegment *seg = VG_(am_find_nsegment)(VG_(brk_base)); 121581de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian vg_assert(seg); 121681de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian vg_assert(seg->kind == SkAnonC); 121781de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian VG_TRACK(new_mem_brk, VG_(brk_base), seg->end + 1 - VG_(brk_base), 121881de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian 1/*tid*/); 121981de065f33b4fbcb02a9a5b7fd75fdb6bde1506fflorian VG_TRACK(die_mem_brk, VG_(brk_base), seg->end + 1 - VG_(brk_base)); 122017c110443e39c0c63bb298689cad31e0b4671dfesewardj} 122117c110443e39c0c63bb298689cad31e0b4671dfesewardj 12228b68b64759254d514d98328c496cbd88cde4c9a5njn#endif // defined(VGO_linux) 122317c110443e39c0c63bb298689cad31e0b4671dfesewardj 122417c110443e39c0c63bb298689cad31e0b4671dfesewardj/*--------------------------------------------------------------------*/ 12258b68b64759254d514d98328c496cbd88cde4c9a5njn/*--- ---*/ 122617c110443e39c0c63bb298689cad31e0b4671dfesewardj/*--------------------------------------------------------------------*/ 1227