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