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