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