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
11663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Copyright (C) 2000-2012 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;
101663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#     elif defined(VGP_mips32_linux)
102663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int o_arg1;
103663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int o_arg2;
104663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int o_arg3;
105663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int o_arg4;
106663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int s_arg5;
107663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int s_arg6;
108663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int uu_arg7;
109663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Int uu_arg8;
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#     elif defined(VGP_x86_darwin)
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int s_arg1;
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int s_arg2;
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int s_arg3;
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int s_arg4;
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int s_arg5;
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int s_arg6;
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int s_arg7;
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int s_arg8;
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#     elif defined(VGP_amd64_darwin)
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int o_arg1;
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int o_arg2;
122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int o_arg3;
123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int o_arg4;
124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int o_arg5;
125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int o_arg6;
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int s_arg7;
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int s_arg8;
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#     else
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#       error "Unknown platform"
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#     endif
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SyscallArgLayout;
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Flags describing syscall wrappers */
135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SfMayBlock      (1 << 1) /* may block                         */
136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SfPostOnFail    (1 << 2) /* call POST() function on failure   */
137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SfPollAfter     (1 << 3) /* poll for signals on completion    */
138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SfYieldAfter    (1 << 4) /* yield on completion               */
139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SfNoWriteResult (1 << 5) /* don't write result to guest state */
140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   The syscall table.
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   struct {
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void (*before) ( ThreadId,
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       SyscallArgLayout*,
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       /*MOD*/SyscallArgs*,
151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       /*OUT*/SyscallStatus*,
152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       /*OUT*/UWord*
153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     );
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      void (*after)  ( ThreadId,
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       SyscallArgs*,
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       SyscallStatus*
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                     );
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   SyscallTableEntry;
161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Syscall table entries bind __NR_xxx syscall numbers to the PRE/POST
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   wrappers for the relevant syscall used in the OS kernel for that
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   number.  Note that the constant names don't always match the
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   wrapper names in a straightforward way.  For example, on x86/Linux:
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __NR_lchown       --> sys_lchown16()
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __NR_lchown32     --> sys_lchown()
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __NR_select       --> old_select()
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      __NR__newselect   --> sys_select()
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* A function to find the syscall table entry for a given sysno.  If
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   none is found, return NULL.  This used to be done with a single
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fixed sized table exposed to the caller, but that's too inflexible;
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   hence now use a function which can do arbitrary messing around to
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   find the required entry. */
179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(VGP_mips32_linux)
180663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* Up to 6 parameters, 4 in registers 2 on stack. */
181663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA1(s,t,a) PRRAn(1,s,t,a)
182663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA2(s,t,a) PRRAn(2,s,t,a)
183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA3(s,t,a) PRRAn(3,s,t,a)
184663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA4(s,t,a) PRRAn(4,s,t,a)
185663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA5(s,t,a) PSRAn(5,s,t,a)
186663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA6(s,t,a) PSRAn(6,s,t,a)
187663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
188663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VGO_linux)
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownSyscallTableEntry* ML_(get_linux_syscall_entry)( UInt sysno );
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin)
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* XXX: Darwin still uses the old scheme of exposing the table
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   array(s) and size(s) directly to syswrap-main.c.  This should be
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   fixed. */
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern const SyscallTableEntry ML_(syscall_table)[];
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownextern const UInt ML_(syscall_table_size);
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error Unknown OS
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Declaring and defining wrappers.
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Templates for generating the PRE and POST macros -- that is, the
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   formal parameter lists for the definitions of wrapper functions.
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Since these names exist in the global namespace, 'auxstr' should
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   give an auxiliary string, eg, "generic", "x86_linux", "linux", etc,
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   that ensures the names won't clash with other wrappers.
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   You should create corresponding global declarations using
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DECL_TEMPLATE (indirectly) below.
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Note.  The silly name "arrghs" is used rather than just "args"
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   because a few wrappers declare the name "args" themselves, and
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   renaming those decls can change the name that comes out in error
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   messages (on scalar arg checks).  Hence rename this instead.
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define DEFN_PRE_TEMPLATE(auxstr, name)                          \
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void vgSysWrap_##auxstr##_##name##_before                     \
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 ( ThreadId tid,                 \
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   SyscallArgLayout* layout,     \
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   /*MOD*/SyscallArgs* arrghs,   \
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   /*OUT*/SyscallStatus* status, \
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   /*OUT*/UWord* flags           \
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 )
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define DEFN_POST_TEMPLATE(auxstr, name)                         \
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void vgSysWrap_##auxstr##_##name##_after                      \
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 ( ThreadId tid,                 \
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   SyscallArgs* arrghs,          \
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   SyscallStatus* status         \
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 )
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This macro generates declarations (prototypes) for wrappers.  It
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   declares both the pre-wrapper and the post-wrapper, even though the
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   post-wrapper may not actually exist.
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define DECL_TEMPLATE(auxstr, name)                              \
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   extern                                                        \
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void vgSysWrap_##auxstr##_##name##_before                     \
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 ( ThreadId tid,                 \
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   SyscallArgLayout* layout,     \
251ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   /*MOD*/SyscallArgs* arrghs,   \
252ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   /*OUT*/SyscallStatus* status, \
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   /*OUT*/UWord* flags           \
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 );                              \
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   extern                                                        \
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   void vgSysWrap_##auxstr##_##name##_after                      \
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 ( ThreadId tid,                 \
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   SyscallArgs* arrghs,          \
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                   SyscallStatus* status         \
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                 );
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Macros for conveniently generating entries in the syscall
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   tables.  This first pair are not used directly. */
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRAPPER_ENTRY_X_(auxstr, sysno, name) \
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   [sysno] = { vgSysWrap_##auxstr##_##name##_before, NULL }
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRAPPER_ENTRY_XY(auxstr, sysno, name) \
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   [sysno] = { vgSysWrap_##auxstr##_##name##_before, \
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vgSysWrap_##auxstr##_##name##_after }
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRAPPER_PRE_NAME(auxstr, name) \
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    vgSysWrap_##auxstr##_##name##_before
275ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define WRAPPER_POST_NAME(auxstr, name) \
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    vgSysWrap_##auxstr##_##name##_after
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a generic wrapper to a syscall table. */
279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#if defined(VGO_linux)
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GENX_(sysno, name)  WRAPPER_ENTRY_X_(generic, sysno, name)
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GENXY(sysno, name)  WRAPPER_ENTRY_XY(generic, sysno, name)
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGO_darwin)
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GENX_(sysno, name)  WRAPPER_ENTRY_X_(generic, VG_DARWIN_SYSNO_INDEX(sysno), name)
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define GENXY(sysno, name)  WRAPPER_ENTRY_XY(generic, VG_DARWIN_SYSNO_INDEX(sysno), name)
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error Unknown OS
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Add a Linux-specific, arch-independent wrapper to a syscall
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   table. */
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LINX_(sysno, name)    WRAPPER_ENTRY_X_(linux, sysno, name)
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define LINXY(sysno, name)    WRAPPER_ENTRY_XY(linux, sysno, name)
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* ---------------------------------------------------------------------
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Macros useful for writing wrappers concisely.  These refer to the
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   parameters declared by DEFN_{PRE,POST}_TEMPLATE and so in a way do
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   not help clarity of understanding.  But they are just too useful to
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   omit.
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   ------------------------------------------------------------------ */
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Reference to the syscall's arguments -- the ones which the
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pre-wrapper may have modified, not the original copy. */
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SYSNO  (arrghs->sysno)
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG1   (arrghs->arg1)
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG2   (arrghs->arg2)
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG3   (arrghs->arg3)
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG4   (arrghs->arg4)
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG5   (arrghs->arg5)
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG6   (arrghs->arg6)
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG7   (arrghs->arg7)
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ARG8   (arrghs->arg8)
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Reference to the syscall's current result status/value.  General
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   paranoia all round. */
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SUCCESS       (status->what == SsComplete && !sr_isError(status->sres))
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define FAILURE       (status->what == SsComplete &&  sr_isError(status->sres))
318ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SWHAT         (status->what)
319ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define RES           (getRES(status))
320ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define RESHI         (getRESHI(status))
321ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define ERR           (getERR(status))
322ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
323ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UWord getRES ( SyscallStatus* st ) {
324ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(st->what == SsComplete);
325ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(!sr_isError(st->sres));
326ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sr_Res(st->sres);
327ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
328ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UWord getRESHI ( SyscallStatus* st ) {
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(st->what == SsComplete);
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(!sr_isError(st->sres));
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sr_ResHI(st->sres);
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UWord getERR ( SyscallStatus* st ) {
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(st->what == SsComplete);
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vg_assert(sr_isError(st->sres));
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sr_Err(st->sres);
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Set the current result status/value in various ways. */
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SET_STATUS_Success(zzz)                      \
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { status->what = SsComplete;                   \
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        status->sres = VG_(mk_SysRes_Success)(zzz);  \
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SET_STATUS_Failure(zzz)                      \
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do { Word wzz = (Word)(zzz);                      \
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        /* Catch out wildly bogus error values. */   \
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        vg_assert(wzz >= 0 && wzz < 10000);          \
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        status->what = SsComplete;                   \
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        status->sres = VG_(mk_SysRes_Error)(wzz);    \
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define SET_STATUS_from_SysRes(zzz)                  \
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                              \
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     status->what = SsComplete;                      \
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown     status->sres = (zzz);                           \
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRINT(format, args...)                       \
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(clo_trace_syscalls))                      \
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(printf)(format, ## args)
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
367b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#define FUSE_COMPATIBLE_MAY_BLOCK()                       \
368b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   if (VG_(strstr)(VG_(clo_sim_hints),"fuse-compatible")) \
369b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      *flags |= SfMayBlock
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Macros used to tell tools about uses of scalar arguments.  Note,
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   these assume little-endianness.  These can only be used in
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   pre-wrappers, and they refer to the layout parameter passed in. */
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* PRRSN == "pre-register-read-sysno"
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRRAn == "pre-register-read-argument"
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PSRAn == "pre-stack-read-argument"
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   PRAn  == "pre-read-argument"
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
381663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if defined(VGP_mips32_linux)
382663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* Up to 6 parameters, 4 in registers 2 on stack. */
383663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA1(s,t,a) PRRAn(1,s,t,a)
384663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA2(s,t,a) PRRAn(2,s,t,a)
385663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA3(s,t,a) PRRAn(3,s,t,a)
386663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA4(s,t,a) PRRAn(4,s,t,a)
387663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA5(s,t,a) PSRAn(5,s,t,a)
388663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#  define PRA6(s,t,a) PSRAn(6,s,t,a)
389663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
390663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#elif defined(VGO_linux) && !defined(VGP_mips32_linux)
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Up to 6 parameters, all in registers. */
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA1(s,t,a) PRRAn(1,s,t,a)
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA2(s,t,a) PRRAn(2,s,t,a)
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA3(s,t,a) PRRAn(3,s,t,a)
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA4(s,t,a) PRRAn(4,s,t,a)
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA5(s,t,a) PRRAn(5,s,t,a)
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA6(s,t,a) PRRAn(6,s,t,a)
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_x86_darwin)
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Up to 8 parameters, all on the stack. */
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA1(s,t,a) PSRAn(1,s,t,a)
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA2(s,t,a) PSRAn(2,s,t,a)
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA3(s,t,a) PSRAn(3,s,t,a)
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA4(s,t,a) PSRAn(4,s,t,a)
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA5(s,t,a) PSRAn(5,s,t,a)
406ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA6(s,t,a) PSRAn(6,s,t,a)
407ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA7(s,t,a) PSRAn(7,s,t,a)
408ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA8(s,t,a) PSRAn(8,s,t,a)
409ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
410ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VGP_amd64_darwin)
411ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Up to 8 parameters, 6 in registers, 2 on the stack. */
412ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA1(s,t,a) PRRAn(1,s,t,a)
413ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA2(s,t,a) PRRAn(2,s,t,a)
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA3(s,t,a) PRRAn(3,s,t,a)
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA4(s,t,a) PRRAn(4,s,t,a)
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA5(s,t,a) PRRAn(5,s,t,a)
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA6(s,t,a) PRRAn(6,s,t,a)
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA7(s,t,a) PSRAn(7,s,t,a)
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRA8(s,t,a) PSRAn(8,s,t,a)
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error Unknown platform
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Tell the tool that the syscall number is being read. */
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRRSN \
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(tdict).track_pre_reg_read(Vg_CoreSysCall, tid, "(syscallno)", \
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                                    layout->o_sysno, sizeof(UWord));
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* REGISTER PARAMETERS */
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* PRRAn: Tell the tool that the register holding the n-th syscall
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   argument is being read, at type 't' which must be at most the size
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   of a register but can be smaller.  In the latter case we need to be
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   careful about endianness. */
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
438ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* little-endian: the part of the guest state being read is
439ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      let here = offset_of_reg
440ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in  [here .. here + sizeof(t) - 1]
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   since the least significant parts of the guest register are stored
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in memory at the lowest address.
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRRAn_LE(n,s,t,a)                          \
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                            \
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int here = layout->o_arg##n;                 \
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(sizeof(t) <= sizeof(UWord));       \
448ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(here >= 0);                        \
449ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(tdict).track_pre_reg_read(               \
450ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Vg_CoreSysCall, tid, s"("#a")",           \
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         here, sizeof(t)                           \
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                           \
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* big-endian: the part of the guest state being read is
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      let next = offset_of_reg + sizeof(reg)
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in  [next - sizeof(t) .. next - 1]
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   since the least significant parts of the guest register are stored
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in memory at the highest address.
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRRAn_BE(n,s,t,a)                          \
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                            \
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int here = layout->o_arg##n;                 \
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Int next = layout->o_arg##n + sizeof(UWord); \
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(sizeof(t) <= sizeof(UWord));       \
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(here >= 0);                        \
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(tdict).track_pre_reg_read(               \
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Vg_CoreSysCall, tid, s"("#a")",           \
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         next-sizeof(t), sizeof(t)                 \
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                           \
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VG_BIGENDIAN)
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRRAn(n,s,t,a) PRRAn_BE(n,s,t,a)
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VG_LITTLEENDIAN)
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PRRAn(n,s,t,a) PRRAn_LE(n,s,t,a)
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error "Unknown endianness"
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* STACK PARAMETERS */
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* PSRAn: Tell the tool that the memory holding the n-th syscall
485ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   argument is being read, at type 't' which must be at most the size
486ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   of a register but can be smaller.  In the latter case we need to be
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   careful about endianness. */
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* little-endian: the part of the guest state being read is
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      let here = offset_of_reg
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in  [here .. here + sizeof(t) - 1]
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   since the least significant parts of the guest register are stored
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in memory at the lowest address.
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PSRAn_LE(n,s,t,a)                          \
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                            \
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr here = layout->s_arg##n + VG_(get_SP)(tid); \
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(sizeof(t) <= sizeof(UWord));       \
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(tdict).track_pre_mem_read(               \
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Vg_CoreSysCallArgInMem, tid, s"("#a")",   \
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         here, sizeof(t)                           \
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                           \
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* big-endian: the part of the guest state being read is
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      let next = offset_of_reg + sizeof(reg)
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      in  [next - sizeof(t) .. next - 1]
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   since the least significant parts of the guest register are stored
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   in memory at the highest address.
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown*/
511663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#if (defined(VGP_mips32_linux) && defined (_MIPSEB))
512663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng #define PSRAn_BE(n,s,t,a)                                        \
513663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng    do {                                                          \
514663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Addr next = layout->s_arg##n + sizeof(UWord) +              \
515663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                  VG_(get_SP)(tid);                               \
516663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vg_assert(sizeof(t) <= sizeof(UWord));                      \
517663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      VG_(tdict).track_pre_mem_read(                              \
518663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         Vg_CoreSysCallArgInMem, tid, s"("#a")",                  \
519663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         next-sizeof(t), sizeof(t)                                \
520663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      );                                                          \
521663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } while (0)
522663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#else
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PSRAn_BE(n,s,t,a)                                         \
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   do {                                                           \
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Addr next = layout->o_arg##n + sizeof(UWord) +              \
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                  VG_(threads)[tid].arch.vex.VG_STACK_PTR;        \
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vg_assert(sizeof(t) <= sizeof(UWord));                      \
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      VG_(tdict).track_pre_mem_read(                              \
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         Vg_CoreSysCallArgInMem, tid, s"("#a")",                  \
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         next-sizeof(t), sizeof(t)                                \
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      );                                                          \
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   } while (0)
533663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng#endif
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#if defined(VG_BIGENDIAN)
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PSRAn(n,s,t,a) PSRAn_BE(n,s,t,a)
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#elif defined(VG_LITTLEENDIAN)
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  define PSRAn(n,s,t,a) PSRAn_LE(n,s,t,a)
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  error "Unknown endianness"
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ0(tr, s) \
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(tdict).track_pre_reg_read) { \
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRRSN; \
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ1(tr, s, t1, a1) \
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(tdict).track_pre_reg_read) { \
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRRSN; \
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA1(s,t1,a1);                            \
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ2(tr, s, t1, a1, t2, a2) \
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(tdict).track_pre_reg_read) { \
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRRSN; \
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA1(s,t1,a1); PRA2(s,t2,a2);           \
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ3(tr, s, t1, a1, t2, a2, t3, a3) \
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(tdict).track_pre_reg_read) { \
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRRSN; \
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3);  \
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ4(tr, s, t1, a1, t2, a2, t3, a3, t4, a4) \
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(tdict).track_pre_reg_read) { \
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRRSN; \
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3);  \
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA4(s,t4,a4);                                    \
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ5(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(tdict).track_pre_reg_read) { \
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRRSN; \
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3);  \
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA4(s,t4,a4); PRA5(s,t5,a5);                   \
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ6(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6) \
576ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(tdict).track_pre_reg_read) { \
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRRSN; \
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3);   \
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6);   \
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
581ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ7(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6, t7, a7) \
582ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(tdict).track_pre_reg_read) { \
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRRSN; \
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3);   \
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6);   \
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA7(s,t7,a7);                                     \
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_REG_READ8(tr, s, t1, a1, t2, a2, t3, a3, t4, a4, t5, a5, t6, a6, t7, a7, t8, a8) \
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (VG_(tdict).track_pre_reg_read) { \
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRRSN; \
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA1(s,t1,a1); PRA2(s,t2,a2); PRA3(s,t3,a3);   \
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA4(s,t4,a4); PRA5(s,t5,a5); PRA6(s,t6,a6);   \
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      PRA7(s,t7,a7); PRA8(s,t8,a8);                    \
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_MEM_READ(zzname, zzaddr, zzlen) \
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_TRACK( pre_mem_read, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_MEM_RASCIIZ(zzname, zzaddr) \
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_TRACK( pre_mem_read_asciiz, Vg_CoreSysCall, tid, zzname, zzaddr)
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_MEM_WRITE(zzname, zzaddr, zzlen) \
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_TRACK( pre_mem_write, Vg_CoreSysCall, tid, zzname, zzaddr, zzlen)
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define POST_MEM_WRITE(zzaddr, zzlen) \
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   VG_TRACK( post_mem_write, Vg_CoreSysCall, tid, zzaddr, zzlen)
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_FIELD_READ(zzname, zzfield) \
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRE_MEM_READ(zzname, (UWord)&zzfield, sizeof(zzfield))
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define PRE_FIELD_WRITE(zzname, zzfield) \
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    PRE_MEM_WRITE(zzname, (UWord)&zzfield, sizeof(zzfield))
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define POST_FIELD_WRITE(zzfield) \
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    POST_MEM_WRITE((UWord)&zzfield, sizeof(zzfield))
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif   // __PRIV_TYPES_N_MACROS_H
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                                          ---*/
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
625