1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- Types and macros for writing syscall wrappers. ---*/ 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- priv_types_n_macros.h ---*/ 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This file is part of Valgrind, a dynamic binary instrumentation 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown framework. 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 11b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov Copyright (C) 2000-2011 Julian Seward 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown jseward@acm.org 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is free software; you can redistribute it and/or 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modify it under the terms of the GNU General Public License as 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown published by the Free Software Foundation; either version 2 of the 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown License, or (at your option) any later version. 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This program is distributed in the hope that it will be useful, but 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown WITHOUT ANY WARRANTY; without even the implied warranty of 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown General Public License for more details. 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should have received a copy of the GNU General Public License 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown along with this program; if not, write to the Free Software 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 02111-1307, USA. 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The GNU General Public License is contained in the file COPYING. 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifndef __PRIV_TYPES_N_MACROS_H 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define __PRIV_TYPES_N_MACROS_H 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* requires #include "pub_core_options.h" */ 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* requires #include "pub_core_signals.h" */ 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This header defines types and macros which are useful for writing 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown syscall wrappers. It does not give prototypes for any such 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown headers, though: that is the job of the priv_syswrap-*.h headers. 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown This header gets included in any file which defines or declares 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wrappers, and as such should only contain stuff which is relevant 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown to all such files. 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------------------------------------------------------- 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Types that are used in syscall wrappers. 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ------------------------------------------------------------------ */ 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Arguments for a syscall. */ 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct SyscallArgs { 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Word sysno; 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord arg1; 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord arg2; 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord arg3; 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord arg4; 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord arg5; 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord arg6; 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord arg7; 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UWord arg8; 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallArgs; 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Current status of a syscall being done on behalf of the client. */ 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct SyscallStatus { 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown enum { 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* call is complete, result is in 'res' */ 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SsComplete=1, 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* syscall not yet completed; must be handed to the kernel */ 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SsHandToKernel, 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* not currently handling a syscall for this thread */ 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SsIdle 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } what; 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SysRes sres; /* only meaningful for .what == SsComplete */ 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallStatus; 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Guest state layout info for syscall args. */ 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Note that, depending on the platform, arguments may be found in 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // registers or on the stack. (See the comment at the top of 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // syswrap-main.c for per-platform details.) For register arguments 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // (which have o_arg field names) the o_arg value is the offset into 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // the vex register state. For stack arguments (which have s_arg 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // field names), the s_arg value is the offset from the stack pointer. 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_sysno; 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# if defined(VGP_x86_linux) || defined(VGP_amd64_linux) \ 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown || defined(VGP_ppc32_linux) || defined(VGP_ppc64_linux) \ 92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov || defined(VGP_arm_linux) || defined(VGP_s390x_linux) 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg1; 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg2; 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg3; 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg4; 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg5; 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg6; 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int uu_arg7; 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int uu_arg8; 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# elif defined(VGP_x86_darwin) 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s_arg1; 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s_arg2; 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s_arg3; 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s_arg4; 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s_arg5; 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s_arg6; 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s_arg7; 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s_arg8; 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# elif defined(VGP_amd64_darwin) 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg1; 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg2; 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg3; 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg4; 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg5; 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int o_arg6; 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s_arg7; 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int s_arg8; 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# else 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error "Unknown platform" 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# endif 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallArgLayout; 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Flags describing syscall wrappers */ 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SfMayBlock (1 << 1) /* may block */ 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SfPostOnFail (1 << 2) /* call POST() function on failure */ 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SfPollAfter (1 << 3) /* poll for signals on completion */ 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SfYieldAfter (1 << 4) /* yield on completion */ 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SfNoWriteResult (1 << 5) /* don't write result to guest state */ 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------------------------------------------------------- 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown The syscall table. 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ------------------------------------------------------------------ */ 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct { 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*before) ( ThreadId, 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallArgLayout*, 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/SyscallArgs*, 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/SyscallStatus*, 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/UWord* 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void (*after) ( ThreadId, 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallArgs*, 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallStatus* 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallTableEntry; 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Syscall table entries bind __NR_xxx syscall numbers to the PRE/POST 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wrappers for the relevant syscall used in the OS kernel for that 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown number. Note that the constant names don't always match the 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown wrapper names in a straightforward way. For example, on x86/Linux: 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __NR_lchown --> sys_lchown16() 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __NR_lchown32 --> sys_lchown() 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __NR_select --> old_select() 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __NR__newselect --> sys_select() 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A function to find the syscall table entry for a given sysno. If 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown none is found, return NULL. This used to be done with a single 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fixed sized table exposed to the caller, but that's too inflexible; 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown hence now use a function which can do arbitrary messing around to 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown find the required entry. */ 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSyscallTableEntry* ML_(get_linux_syscall_entry)( UInt sysno ); 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* XXX: Darwin still uses the old scheme of exposing the table 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown array(s) and size(s) directly to syswrap-main.c. This should be 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fixed. */ 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern const SyscallTableEntry ML_(syscall_table)[]; 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern const UInt ML_(syscall_table_size); 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error Unknown OS 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------------------------------------------------------- 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Declaring and defining wrappers. 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ------------------------------------------------------------------ */ 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Templates for generating the PRE and POST macros -- that is, the 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown formal parameter lists for the definitions of wrapper functions. 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Since these names exist in the global namespace, 'auxstr' should 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown give an auxiliary string, eg, "generic", "x86_linux", "linux", etc, 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown that ensures the names won't clash with other wrappers. 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown You should create corresponding global declarations using 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown DECL_TEMPLATE (indirectly) below. 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Note. The silly name "arrghs" is used rather than just "args" 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown because a few wrappers declare the name "args" themselves, and 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown renaming those decls can change the name that comes out in error 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown messages (on scalar arg checks). Hence rename this instead. 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define DEFN_PRE_TEMPLATE(auxstr, name) \ 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void vgSysWrap_##auxstr##_##name##_before \ 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( ThreadId tid, \ 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallArgLayout* layout, \ 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/SyscallArgs* arrghs, \ 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/SyscallStatus* status, \ 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/UWord* flags \ 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define DEFN_POST_TEMPLATE(auxstr, name) \ 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void vgSysWrap_##auxstr##_##name##_after \ 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( ThreadId tid, \ 218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallArgs* arrghs, \ 219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallStatus* status \ 220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ) 221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This macro generates declarations (prototypes) for wrappers. It 224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown declares both the pre-wrapper and the post-wrapper, even though the 225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown post-wrapper may not actually exist. 226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define DECL_TEMPLATE(auxstr, name) \ 228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extern \ 229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void vgSysWrap_##auxstr##_##name##_before \ 230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( ThreadId tid, \ 231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallArgLayout* layout, \ 232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*MOD*/SyscallArgs* arrghs, \ 233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/SyscallStatus* status, \ 234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*OUT*/UWord* flags \ 235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown extern \ 237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown void vgSysWrap_##auxstr##_##name##_after \ 238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ( ThreadId tid, \ 239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallArgs* arrghs, \ 240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown SyscallStatus* status \ 241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); 242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Macros for conveniently generating entries in the syscall 246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tables. This first pair are not used directly. */ 247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRAPPER_ENTRY_X_(auxstr, sysno, name) \ 249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [sysno] = { vgSysWrap_##auxstr##_##name##_before, NULL } 250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRAPPER_ENTRY_XY(auxstr, sysno, name) \ 251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown [sysno] = { vgSysWrap_##auxstr##_##name##_before, \ 252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vgSysWrap_##auxstr##_##name##_after } 253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRAPPER_PRE_NAME(auxstr, name) \ 255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vgSysWrap_##auxstr##_##name##_before 256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRAPPER_POST_NAME(auxstr, name) \ 257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vgSysWrap_##auxstr##_##name##_after 258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a generic wrapper to a syscall table. */ 260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux) 261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define GENX_(sysno, name) WRAPPER_ENTRY_X_(generic, sysno, name) 262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define GENXY(sysno, name) WRAPPER_ENTRY_XY(generic, sysno, name) 263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin) 264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define GENX_(sysno, name) WRAPPER_ENTRY_X_(generic, VG_DARWIN_SYSNO_INDEX(sysno), name) 265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define GENXY(sysno, name) WRAPPER_ENTRY_XY(generic, VG_DARWIN_SYSNO_INDEX(sysno), name) 266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error Unknown OS 268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a Linux-specific, arch-independent wrapper to a syscall 271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown table. */ 272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LINX_(sysno, name) WRAPPER_ENTRY_X_(linux, sysno, name) 273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LINXY(sysno, name) WRAPPER_ENTRY_XY(linux, sysno, name) 274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* --------------------------------------------------------------------- 277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Macros useful for writing wrappers concisely. These refer to the 278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown parameters declared by DEFN_{PRE,POST}_TEMPLATE and so in a way do 279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown not help clarity of understanding. But they are just too useful to 280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown omit. 281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ------------------------------------------------------------------ */ 282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Reference to the syscall's arguments -- the ones which the 284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pre-wrapper may have modified, not the original copy. */ 285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SYSNO (arrghs->sysno) 286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG1 (arrghs->arg1) 287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG2 (arrghs->arg2) 288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG3 (arrghs->arg3) 289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG4 (arrghs->arg4) 290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG5 (arrghs->arg5) 291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG6 (arrghs->arg6) 292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG7 (arrghs->arg7) 293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG8 (arrghs->arg8) 294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Reference to the syscall's current result status/value. General 296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown paranoia all round. */ 297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SUCCESS (status->what == SsComplete && !sr_isError(status->sres)) 298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define FAILURE (status->what == SsComplete && sr_isError(status->sres)) 299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SWHAT (status->what) 300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define RES (getRES(status)) 301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define RESHI (getRESHI(status)) 302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ERR (getERR(status)) 303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UWord getRES ( SyscallStatus* st ) { 305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(st->what == SsComplete); 306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!sr_isError(st->sres)); 307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sr_Res(st->sres); 308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UWord getRESHI ( SyscallStatus* st ) { 311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(st->what == SsComplete); 312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(!sr_isError(st->sres)); 313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sr_ResHI(st->sres); 314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UWord getERR ( SyscallStatus* st ) { 317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(st->what == SsComplete); 318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sr_isError(st->sres)); 319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return sr_Err(st->sres); 320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Set the current result status/value in various ways. */ 324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SET_STATUS_Success(zzz) \ 325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { status->what = SsComplete; \ 326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown status->sres = VG_(mk_SysRes_Success)(zzz); \ 327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SET_STATUS_Failure(zzz) \ 330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { Word wzz = (Word)(zzz); \ 331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Catch out wildly bogus error values. */ \ 332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(wzz >= 0 && wzz < 10000); \ 333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown status->what = SsComplete; \ 334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown status->sres = VG_(mk_SysRes_Error)(wzz); \ 335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SET_STATUS_from_SysRes(zzz) \ 338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown status->what = SsComplete; \ 340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown status->sres = (zzz); \ 341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRINT(format, args...) \ 345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(clo_trace_syscalls)) \ 346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(printf)(format, ## args) 347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 348b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FUSE_COMPATIBLE_MAY_BLOCK() \ 349b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov if (VG_(strstr)(VG_(clo_sim_hints),"fuse-compatible")) \ 350b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov *flags |= SfMayBlock 351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Macros used to tell tools about uses of scalar arguments. Note, 354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown these assume little-endianness. These can only be used in 355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pre-wrappers, and they refer to the layout parameter passed in. */ 356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* PRRSN == "pre-register-read-sysno" 357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRRAn == "pre-register-read-argument" 358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PSRAn == "pre-stack-read-argument" 359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRAn == "pre-read-argument" 360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux) 363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Up to 6 parameters, all in registers. */ 364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA1(s,t,a) PRRAn(1,s,t,a) 365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA2(s,t,a) PRRAn(2,s,t,a) 366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA3(s,t,a) PRRAn(3,s,t,a) 367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA4(s,t,a) PRRAn(4,s,t,a) 368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA5(s,t,a) PRRAn(5,s,t,a) 369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA6(s,t,a) PRRAn(6,s,t,a) 370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_x86_darwin) 372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Up to 8 parameters, all on the stack. */ 373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA1(s,t,a) PSRAn(1,s,t,a) 374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA2(s,t,a) PSRAn(2,s,t,a) 375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA3(s,t,a) PSRAn(3,s,t,a) 376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA4(s,t,a) PSRAn(4,s,t,a) 377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA5(s,t,a) PSRAn(5,s,t,a) 378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA6(s,t,a) PSRAn(6,s,t,a) 379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA7(s,t,a) PSRAn(7,s,t,a) 380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA8(s,t,a) PSRAn(8,s,t,a) 381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_amd64_darwin) 383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Up to 8 parameters, 6 in registers, 2 on the stack. */ 384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA1(s,t,a) PRRAn(1,s,t,a) 385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA2(s,t,a) PRRAn(2,s,t,a) 386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA3(s,t,a) PRRAn(3,s,t,a) 387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA4(s,t,a) PRRAn(4,s,t,a) 388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA5(s,t,a) PRRAn(5,s,t,a) 389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA6(s,t,a) PRRAn(6,s,t,a) 390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA7(s,t,a) PSRAn(7,s,t,a) 391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRA8(s,t,a) PSRAn(8,s,t,a) 392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error Unknown platform 395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Tell the tool that the syscall number is being read. */ 399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRRSN \ 400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, "(syscallno)", \ 401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown layout->o_sysno, sizeof(UWord)); 402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* REGISTER PARAMETERS */ 404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* PRRAn: Tell the tool that the register holding the n-th syscall 406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argument is being read, at type 't' which must be at most the size 407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of a register but can be smaller. In the latter case we need to be 408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown careful about endianness. */ 409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* little-endian: the part of the guest state being read is 411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown let here = offset_of_reg 412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in [here .. here + sizeof(t) - 1] 413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown since the least significant parts of the guest register are stored 414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in memory at the lowest address. 415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRRAn_LE(n,s,t,a) \ 417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int here = layout->o_arg##n; \ 419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sizeof(t) <= sizeof(UWord)); \ 420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(here >= 0); \ 421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tdict).track_pre_reg_read( \ 422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vg_CoreSysCall, tid, s"("#a")", \ 423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown here, sizeof(t) \ 424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* big-endian: the part of the guest state being read is 428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown let next = offset_of_reg + sizeof(reg) 429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in [next - sizeof(t) .. next - 1] 430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown since the least significant parts of the guest register are stored 431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in memory at the highest address. 432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRRAn_BE(n,s,t,a) \ 434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int here = layout->o_arg##n; \ 436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Int next = layout->o_arg##n + sizeof(UWord); \ 437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sizeof(t) <= sizeof(UWord)); \ 438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(here >= 0); \ 439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tdict).track_pre_reg_read( \ 440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vg_CoreSysCall, tid, s"("#a")", \ 441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown next-sizeof(t), sizeof(t) \ 442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VG_BIGENDIAN) 446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRRAn(n,s,t,a) PRRAn_BE(n,s,t,a) 447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VG_LITTLEENDIAN) 448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PRRAn(n,s,t,a) PRRAn_LE(n,s,t,a) 449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error "Unknown endianness" 451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* STACK PARAMETERS */ 455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* PSRAn: Tell the tool that the memory holding the n-th syscall 457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown argument is being read, at type 't' which must be at most the size 458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown of a register but can be smaller. In the latter case we need to be 459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown careful about endianness. */ 460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* little-endian: the part of the guest state being read is 462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown let here = offset_of_reg 463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in [here .. here + sizeof(t) - 1] 464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown since the least significant parts of the guest register are stored 465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in memory at the lowest address. 466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PSRAn_LE(n,s,t,a) \ 468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr here = layout->s_arg##n + VG_(get_SP)(tid); \ 470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sizeof(t) <= sizeof(UWord)); \ 471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tdict).track_pre_mem_read( \ 472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vg_CoreSysCallArgInMem, tid, s"("#a")", \ 473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown here, sizeof(t) \ 474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* big-endian: the part of the guest state being read is 478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown let next = offset_of_reg + sizeof(reg) 479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in [next - sizeof(t) .. next - 1] 480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown since the least significant parts of the guest register are stored 481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown in memory at the highest address. 482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/ 483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PSRAn_BE(n,s,t,a) \ 484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown do { \ 485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Addr next = layout->o_arg##n + sizeof(UWord) + \ 486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(threads)[tid].arch.vex.VG_STACK_PTR; \ 487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown vg_assert(sizeof(t) <= sizeof(UWord)); \ 488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_(tdict).track_pre_mem_read( \ 489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown Vg_CoreSysCallArgInMem, tid, s"("#a")", \ 490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown next-sizeof(t), sizeof(t) \ 491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown ); \ 492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } while (0) 493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VG_BIGENDIAN) 495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PSRAn(n,s,t,a) PSRAn_BE(n,s,t,a) 496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VG_LITTLEENDIAN) 497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# define PSRAn(n,s,t,a) PSRAn_LE(n,s,t,a) 498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# error "Unknown endianness" 500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ0(tr, s) \ 504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(tdict).track_pre_reg_read) { \ 505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRRSN; \ 506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ1(tr, s, t1, a1) \ 508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(tdict).track_pre_reg_read) { \ 509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRRSN; \ 510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA1(s,t1,a1); \ 511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ2(tr, s, t1, a1, t2, a2) \ 513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(tdict).track_pre_reg_read) { \ 514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRRSN; \ 515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA1(s,t1,a1); PRA2(s,t2,a2); \ 516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) \ 518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(tdict).track_pre_reg_read) { \ 519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRRSN; \ 520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \ 521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ4(tr, s, t1, a1, t2, a2, t3, a3, t4, a4) \ 523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(tdict).track_pre_reg_read) { \ 524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRRSN; \ 525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \ 526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA4(s,t4,a4); \ 527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ5(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \ 529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(tdict).track_pre_reg_read) { \ 530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRRSN; \ 531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \ 532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA4(s,t4,a4); PRA5(s,t5,a5); \ 533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ6(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \ 535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(tdict).track_pre_reg_read) { \ 536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRRSN; \ 537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \ 538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6); \ 539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ7(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6, t7, a7) \ 541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(tdict).track_pre_reg_read) { \ 542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRRSN; \ 543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \ 544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6); \ 545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA7(s,t7,a7); \ 546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ8(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6, t7, a7, t8, a8) \ 549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (VG_(tdict).track_pre_reg_read) { \ 550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRRSN; \ 551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3); \ 552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6); \ 553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRA7(s,t7,a7); PRA8(s,t8,a8); \ 554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_MEM_READ(zzname, zzaddr, zzlen) \ 557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( pre_mem_read, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen) 558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_MEM_RASCIIZ(zzname, zzaddr) \ 560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( pre_mem_read_asciiz, Vg_CoreSysCall, tid, zzname, zzaddr) 561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_MEM_WRITE(zzname, zzaddr, zzlen) \ 563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen) 564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define POST_MEM_WRITE(zzaddr, zzlen) \ 566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, zzaddr, zzlen) 567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_FIELD_READ(zzname, zzfield) \ 570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRE_MEM_READ(zzname, (UWord)&zzfield, sizeof(zzfield)) 571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_FIELD_WRITE(zzname, zzfield) \ 573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown PRE_MEM_WRITE(zzname, (UWord)&zzfield, sizeof(zzfield)) 574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define POST_FIELD_WRITE(zzfield) \ 576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown POST_MEM_WRITE((UWord)&zzfield, sizeof(zzfield)) 577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif // __PRIV_TYPES_N_MACROS_H 580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end ---*/ 583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/ 584