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