Home | History | Annotate | Download | only in memcheck
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Contains machine-specific (guest-state-layout-specific)      ---*/
      4 /*--- support for origin tracking.                                 ---*/
      5 /*---                                                 mc_machine.c ---*/
      6 /*--------------------------------------------------------------------*/
      7 
      8 /*
      9    This file is part of MemCheck, a heavyweight Valgrind tool for
     10    detecting memory errors.
     11 
     12    Copyright (C) 2008-2012 OpenWorks Ltd
     13       info (at) open-works.co.uk
     14 
     15    This program is free software; you can redistribute it and/or
     16    modify it under the terms of the GNU General Public License as
     17    published by the Free Software Foundation; either version 2 of the
     18    License, or (at your option) any later version.
     19 
     20    This program is distributed in the hope that it will be useful, but
     21    WITHOUT ANY WARRANTY; without even the implied warranty of
     22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     23    General Public License for more details.
     24 
     25    You should have received a copy of the GNU General Public License
     26    along with this program; if not, write to the Free Software
     27    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     28    02111-1307, USA.
     29 
     30    The GNU General Public License is contained in the file COPYING.
     31 
     32    Neither the names of the U.S. Department of Energy nor the
     33    University of California nor the names of its contributors may be
     34    used to endorse or promote products derived from this software
     35    without prior written permission.
     36 */
     37 
     38 #include "pub_tool_basics.h"
     39 #include "pub_tool_poolalloc.h"     // For mc_include.h
     40 #include "pub_tool_hashtable.h"     // For mc_include.h
     41 #include "pub_tool_libcassert.h"
     42 #include "pub_tool_libcprint.h"
     43 #include "pub_tool_tooliface.h"
     44 
     45 #include "mc_include.h"
     46 
     47 #undef MC_SIZEOF_GUEST_STATE
     48 
     49 #if defined(VGA_x86)
     50 # include "libvex_guest_x86.h"
     51 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestX86State)
     52 #endif
     53 
     54 #if defined(VGA_amd64)
     55 # include "libvex_guest_amd64.h"
     56 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestAMD64State)
     57 #endif
     58 
     59 #if defined(VGA_ppc32)
     60 # include "libvex_guest_ppc32.h"
     61 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC32State)
     62 #endif
     63 
     64 #if defined(VGA_ppc64)
     65 # include "libvex_guest_ppc64.h"
     66 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC64State)
     67 #endif
     68 
     69 #if defined(VGA_s390x)
     70 # include "libvex_guest_s390x.h"
     71 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestS390XState)
     72 #endif
     73 
     74 #if defined(VGA_arm)
     75 # include "libvex_guest_arm.h"
     76 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestARMState)
     77 #endif
     78 
     79 #if defined(VGA_mips32)
     80 # include "libvex_guest_mips32.h"
     81 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestMIPS32State)
     82 #endif
     83 
     84 static inline Bool host_is_big_endian ( void ) {
     85    UInt x = 0x11223344;
     86    return 0x1122 == *(UShort*)(&x);
     87 }
     88 static inline Bool host_is_little_endian ( void ) {
     89    UInt x = 0x11223344;
     90    return 0x3344 == *(UShort*)(&x);
     91 }
     92 
     93 
     94 /* Let (offset,szB) describe a reference to the guest state section
     95    [offset, offset+szB).
     96 
     97    This function returns the corresponding guest state reference to be
     98    used for the origin tag (which of course will be in the second
     99    shadow area), or -1 if this piece of guest state is not to be
    100    tracked.
    101 
    102    Since origin tags are 32-bits long, we expect any returned value
    103    (except -1) to be a multiple of 4, between 0 and
    104    sizeof(guest-state)-4 inclusive.
    105 
    106    This is inherently (guest-)architecture specific.  For x86 and
    107    amd64 we do some somewhat tricky things to give %AH .. %DH their
    108    own tags.  On ppc32/64 we do some marginally tricky things to give
    109    all 16 %CR components their own tags.
    110 
    111    This function only deals with references to the guest state whose
    112    offsets are known at translation time (that is, references arising
    113    from Put and Get).  References whose offset is not known until run
    114    time (that is, arise from PutI and GetI) are handled by
    115    MC_(get_otrack_reg_array_equiv_int_type) below.
    116 
    117    Note that since some guest state arrays (eg, the x86 FP reg stack)
    118    are accessed both as arrays (eg, x87 insns) and directly (eg, MMX
    119    insns), the two functions must be consistent for those sections of
    120    guest state -- that is, they must both say the area is shadowed, or
    121    both say it is not.
    122 
    123    This function is dependent on the host's endianness, hence we
    124    assert that the use case is supported.
    125 */
    126 static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ); /*fwds*/
    127 
    128 Int MC_(get_otrack_shadow_offset) ( Int offset, Int szB )
    129 {
    130    Int cand = get_otrack_shadow_offset_wrk( offset, szB );
    131    if (cand == -1)
    132       return cand;
    133    tl_assert(0 == (cand & 3));
    134    tl_assert(cand <= MC_SIZEOF_GUEST_STATE-4);
    135    return cand;
    136 }
    137 
    138 
    139 static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
    140 {
    141    /* -------------------- ppc64 -------------------- */
    142 
    143 #  if defined(VGA_ppc64)
    144 
    145 #  define GOF(_fieldname) \
    146       (offsetof(VexGuestPPC64State,guest_##_fieldname))
    147 #  define SZB(_fieldname) \
    148       (sizeof(((VexGuestPPC64State*)0)->guest_##_fieldname))
    149 
    150    Int  sz   = szB;
    151    Int  o    = offset;
    152    tl_assert(sz > 0);
    153    tl_assert(host_is_big_endian());
    154 
    155    if (sz == 8 || sz == 4) {
    156       /* The point of this is to achieve
    157          if ((o == GOF(GPRn) && sz == 8) || (o == 4+GOF(GPRn) && sz == 4))
    158             return GOF(GPRn);
    159          by testing ox instead of o, and setting ox back 4 bytes when sz == 4.
    160       */
    161       Int ox = sz == 8 ? o : (o - 4);
    162       if (ox == GOF(GPR0)) return ox;
    163       if (ox == GOF(GPR1)) return ox;
    164       if (ox == GOF(GPR2)) return ox;
    165       if (ox == GOF(GPR3)) return ox;
    166       if (ox == GOF(GPR4)) return ox;
    167       if (ox == GOF(GPR5)) return ox;
    168       if (ox == GOF(GPR6)) return ox;
    169       if (ox == GOF(GPR7)) return ox;
    170       if (ox == GOF(GPR8)) return ox;
    171       if (ox == GOF(GPR9)) return ox;
    172       if (ox == GOF(GPR10)) return ox;
    173       if (ox == GOF(GPR11)) return ox;
    174       if (ox == GOF(GPR12)) return ox;
    175       if (ox == GOF(GPR13)) return ox;
    176       if (ox == GOF(GPR14)) return ox;
    177       if (ox == GOF(GPR15)) return ox;
    178       if (ox == GOF(GPR16)) return ox;
    179       if (ox == GOF(GPR17)) return ox;
    180       if (ox == GOF(GPR18)) return ox;
    181       if (ox == GOF(GPR19)) return ox;
    182       if (ox == GOF(GPR20)) return ox;
    183       if (ox == GOF(GPR21)) return ox;
    184       if (ox == GOF(GPR22)) return ox;
    185       if (ox == GOF(GPR23)) return ox;
    186       if (ox == GOF(GPR24)) return ox;
    187       if (ox == GOF(GPR25)) return ox;
    188       if (ox == GOF(GPR26)) return ox;
    189       if (ox == GOF(GPR27)) return ox;
    190       if (ox == GOF(GPR28)) return ox;
    191       if (ox == GOF(GPR29)) return ox;
    192       if (ox == GOF(GPR30)) return ox;
    193       if (ox == GOF(GPR31)) return ox;
    194    }
    195 
    196    if (o == GOF(LR)  && sz == 8) return o;
    197    if (o == GOF(CTR) && sz == 8) return o;
    198 
    199    if (o == GOF(CIA)       && sz == 8) return -1;
    200    if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
    201    if (o == GOF(FPROUND)   && sz == 1) return -1;
    202    if (o == GOF(DFPROUND)  && sz == 1) return -1;
    203    if (o == GOF(EMWARN)    && sz == 4) return -1;
    204    if (o == GOF(TISTART)   && sz == 8) return -1;
    205    if (o == GOF(TILEN)     && sz == 8) return -1;
    206    if (o == GOF(VSCR)      && sz == 4) return -1;
    207    if (o == GOF(VRSAVE)    && sz == 4) return -1;
    208    if (o == GOF(REDIR_SP)  && sz == 8) return -1;
    209 
    210    // With ISA 2.06, the "Vector-Scalar Floating-point" category
    211    // provides facilities to support vector and scalar binary floating-
    212    // point operations.  A unified register file is an integral part
    213    // of this new facility, combining floating point and vector registers
    214    // using a 64x128-bit vector.  These are referred to as VSR[0..63].
    215    // The floating point registers are now mapped into double word element 0
    216    // of VSR[0..31]. The 32x128-bit vector registers defined by the "Vector
    217    // Facility [Category: Vector]" are now mapped to VSR[32..63].
    218 
    219    //  Floating point registers . . .
    220    if (o == GOF(VSR0) && sz == 8) return o;
    221    if (o == GOF(VSR1) && sz == 8) return o;
    222    if (o == GOF(VSR2) && sz == 8) return o;
    223    if (o == GOF(VSR3) && sz == 8) return o;
    224    if (o == GOF(VSR4) && sz == 8) return o;
    225    if (o == GOF(VSR5) && sz == 8) return o;
    226    if (o == GOF(VSR6) && sz == 8) return o;
    227    if (o == GOF(VSR7) && sz == 8) return o;
    228    if (o == GOF(VSR8) && sz == 8) return o;
    229    if (o == GOF(VSR9) && sz == 8) return o;
    230    if (o == GOF(VSR10) && sz == 8) return o;
    231    if (o == GOF(VSR11) && sz == 8) return o;
    232    if (o == GOF(VSR12) && sz == 8) return o;
    233    if (o == GOF(VSR13) && sz == 8) return o;
    234    if (o == GOF(VSR14) && sz == 8) return o;
    235    if (o == GOF(VSR15) && sz == 8) return o;
    236    if (o == GOF(VSR16) && sz == 8) return o;
    237    if (o == GOF(VSR17) && sz == 8) return o;
    238    if (o == GOF(VSR18) && sz == 8) return o;
    239    if (o == GOF(VSR19) && sz == 8) return o;
    240    if (o == GOF(VSR20) && sz == 8) return o;
    241    if (o == GOF(VSR21) && sz == 8) return o;
    242    if (o == GOF(VSR22) && sz == 8) return o;
    243    if (o == GOF(VSR23) && sz == 8) return o;
    244    if (o == GOF(VSR24) && sz == 8) return o;
    245    if (o == GOF(VSR25) && sz == 8) return o;
    246    if (o == GOF(VSR26) && sz == 8) return o;
    247    if (o == GOF(VSR27) && sz == 8) return o;
    248    if (o == GOF(VSR28) && sz == 8) return o;
    249    if (o == GOF(VSR29) && sz == 8) return o;
    250    if (o == GOF(VSR30) && sz == 8) return o;
    251    if (o == GOF(VSR31) && sz == 8) return o;
    252 
    253    /* For the various byte sized XER/CR pieces, use offset 8
    254       in VSR0 .. VSR19. */
    255    tl_assert(SZB(VSR0) == 16);
    256    if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VSR0);
    257    if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VSR1);
    258    if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VSR2);
    259    if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VSR3);
    260 
    261    if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VSR4);
    262    if (o == GOF(CR0_0)   && sz == 1) return 8 +GOF(VSR5);
    263    if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VSR6);
    264    if (o == GOF(CR1_0)   && sz == 1) return 8 +GOF(VSR7);
    265    if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VSR8);
    266    if (o == GOF(CR2_0)   && sz == 1) return 8 +GOF(VSR9);
    267    if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VSR10);
    268    if (o == GOF(CR3_0)   && sz == 1) return 8 +GOF(VSR11);
    269    if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VSR12);
    270    if (o == GOF(CR4_0)   && sz == 1) return 8 +GOF(VSR13);
    271    if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VSR14);
    272    if (o == GOF(CR5_0)   && sz == 1) return 8 +GOF(VSR15);
    273    if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VSR16);
    274    if (o == GOF(CR6_0)   && sz == 1) return 8 +GOF(VSR17);
    275    if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VSR18);
    276    if (o == GOF(CR7_0)   && sz == 1) return 8 +GOF(VSR19);
    277 
    278    /* Vector registers .. use offset 0 in VSR0 .. VSR63. */
    279    if (o >= GOF(VSR0)  && o+sz <= GOF(VSR0) +SZB(VSR0))  return 0+ GOF(VSR0);
    280    if (o >= GOF(VSR1)  && o+sz <= GOF(VSR1) +SZB(VSR1))  return 0+ GOF(VSR1);
    281    if (o >= GOF(VSR2)  && o+sz <= GOF(VSR2) +SZB(VSR2))  return 0+ GOF(VSR2);
    282    if (o >= GOF(VSR3)  && o+sz <= GOF(VSR3) +SZB(VSR3))  return 0+ GOF(VSR3);
    283    if (o >= GOF(VSR4)  && o+sz <= GOF(VSR4) +SZB(VSR4))  return 0+ GOF(VSR4);
    284    if (o >= GOF(VSR5)  && o+sz <= GOF(VSR5) +SZB(VSR5))  return 0+ GOF(VSR5);
    285    if (o >= GOF(VSR6)  && o+sz <= GOF(VSR6) +SZB(VSR6))  return 0+ GOF(VSR6);
    286    if (o >= GOF(VSR7)  && o+sz <= GOF(VSR7) +SZB(VSR7))  return 0+ GOF(VSR7);
    287    if (o >= GOF(VSR8)  && o+sz <= GOF(VSR8) +SZB(VSR8))  return 0+ GOF(VSR8);
    288    if (o >= GOF(VSR9)  && o+sz <= GOF(VSR9) +SZB(VSR9))  return 0+ GOF(VSR9);
    289    if (o >= GOF(VSR10) && o+sz <= GOF(VSR10)+SZB(VSR10)) return 0+ GOF(VSR10);
    290    if (o >= GOF(VSR11) && o+sz <= GOF(VSR11)+SZB(VSR11)) return 0+ GOF(VSR11);
    291    if (o >= GOF(VSR12) && o+sz <= GOF(VSR12)+SZB(VSR12)) return 0+ GOF(VSR12);
    292    if (o >= GOF(VSR13) && o+sz <= GOF(VSR13)+SZB(VSR13)) return 0+ GOF(VSR13);
    293    if (o >= GOF(VSR14) && o+sz <= GOF(VSR14)+SZB(VSR14)) return 0+ GOF(VSR14);
    294    if (o >= GOF(VSR15) && o+sz <= GOF(VSR15)+SZB(VSR15)) return 0+ GOF(VSR15);
    295    if (o >= GOF(VSR16) && o+sz <= GOF(VSR16)+SZB(VSR16)) return 0+ GOF(VSR16);
    296    if (o >= GOF(VSR17) && o+sz <= GOF(VSR17)+SZB(VSR17)) return 0+ GOF(VSR17);
    297    if (o >= GOF(VSR18) && o+sz <= GOF(VSR18)+SZB(VSR18)) return 0+ GOF(VSR18);
    298    if (o >= GOF(VSR19) && o+sz <= GOF(VSR19)+SZB(VSR19)) return 0+ GOF(VSR19);
    299    if (o >= GOF(VSR20) && o+sz <= GOF(VSR20)+SZB(VSR20)) return 0+ GOF(VSR20);
    300    if (o >= GOF(VSR21) && o+sz <= GOF(VSR21)+SZB(VSR21)) return 0+ GOF(VSR21);
    301    if (o >= GOF(VSR22) && o+sz <= GOF(VSR22)+SZB(VSR22)) return 0+ GOF(VSR22);
    302    if (o >= GOF(VSR23) && o+sz <= GOF(VSR23)+SZB(VSR23)) return 0+ GOF(VSR23);
    303    if (o >= GOF(VSR24) && o+sz <= GOF(VSR24)+SZB(VSR24)) return 0+ GOF(VSR24);
    304    if (o >= GOF(VSR25) && o+sz <= GOF(VSR25)+SZB(VSR25)) return 0+ GOF(VSR25);
    305    if (o >= GOF(VSR26) && o+sz <= GOF(VSR26)+SZB(VSR26)) return 0+ GOF(VSR26);
    306    if (o >= GOF(VSR27) && o+sz <= GOF(VSR27)+SZB(VSR27)) return 0+ GOF(VSR27);
    307    if (o >= GOF(VSR28) && o+sz <= GOF(VSR28)+SZB(VSR28)) return 0+ GOF(VSR28);
    308    if (o >= GOF(VSR29) && o+sz <= GOF(VSR29)+SZB(VSR29)) return 0+ GOF(VSR29);
    309    if (o >= GOF(VSR30) && o+sz <= GOF(VSR30)+SZB(VSR30)) return 0+ GOF(VSR30);
    310    if (o >= GOF(VSR31) && o+sz <= GOF(VSR31)+SZB(VSR31)) return 0+ GOF(VSR31);
    311    if (o >= GOF(VSR32) && o+sz <= GOF(VSR32)+SZB(VSR32)) return 0+ GOF(VSR32);
    312    if (o >= GOF(VSR33) && o+sz <= GOF(VSR33)+SZB(VSR33)) return 0+ GOF(VSR33);
    313    if (o >= GOF(VSR34) && o+sz <= GOF(VSR34)+SZB(VSR34)) return 0+ GOF(VSR34);
    314    if (o >= GOF(VSR35) && o+sz <= GOF(VSR35)+SZB(VSR35)) return 0+ GOF(VSR35);
    315    if (o >= GOF(VSR36) && o+sz <= GOF(VSR36)+SZB(VSR36)) return 0+ GOF(VSR36);
    316    if (o >= GOF(VSR37) && o+sz <= GOF(VSR37)+SZB(VSR37)) return 0+ GOF(VSR37);
    317    if (o >= GOF(VSR38) && o+sz <= GOF(VSR38)+SZB(VSR38)) return 0+ GOF(VSR38);
    318    if (o >= GOF(VSR39) && o+sz <= GOF(VSR39)+SZB(VSR39)) return 0+ GOF(VSR39);
    319    if (o >= GOF(VSR40) && o+sz <= GOF(VSR40)+SZB(VSR40)) return 0+ GOF(VSR40);
    320    if (o >= GOF(VSR41) && o+sz <= GOF(VSR41)+SZB(VSR41)) return 0+ GOF(VSR41);
    321    if (o >= GOF(VSR42) && o+sz <= GOF(VSR42)+SZB(VSR42)) return 0+ GOF(VSR42);
    322    if (o >= GOF(VSR43) && o+sz <= GOF(VSR43)+SZB(VSR43)) return 0+ GOF(VSR43);
    323    if (o >= GOF(VSR44) && o+sz <= GOF(VSR44)+SZB(VSR44)) return 0+ GOF(VSR44);
    324    if (o >= GOF(VSR45) && o+sz <= GOF(VSR45)+SZB(VSR45)) return 0+ GOF(VSR45);
    325    if (o >= GOF(VSR46) && o+sz <= GOF(VSR46)+SZB(VSR46)) return 0+ GOF(VSR46);
    326    if (o >= GOF(VSR47) && o+sz <= GOF(VSR47)+SZB(VSR47)) return 0+ GOF(VSR47);
    327    if (o >= GOF(VSR48) && o+sz <= GOF(VSR48)+SZB(VSR48)) return 0+ GOF(VSR48);
    328    if (o >= GOF(VSR49) && o+sz <= GOF(VSR49)+SZB(VSR49)) return 0+ GOF(VSR49);
    329    if (o >= GOF(VSR50) && o+sz <= GOF(VSR50)+SZB(VSR50)) return 0+ GOF(VSR50);
    330    if (o >= GOF(VSR51) && o+sz <= GOF(VSR51)+SZB(VSR51)) return 0+ GOF(VSR51);
    331    if (o >= GOF(VSR52) && o+sz <= GOF(VSR52)+SZB(VSR52)) return 0+ GOF(VSR52);
    332    if (o >= GOF(VSR53) && o+sz <= GOF(VSR53)+SZB(VSR53)) return 0+ GOF(VSR53);
    333    if (o >= GOF(VSR54) && o+sz <= GOF(VSR54)+SZB(VSR54)) return 0+ GOF(VSR54);
    334    if (o >= GOF(VSR55) && o+sz <= GOF(VSR55)+SZB(VSR55)) return 0+ GOF(VSR55);
    335    if (o >= GOF(VSR56) && o+sz <= GOF(VSR56)+SZB(VSR56)) return 0+ GOF(VSR56);
    336    if (o >= GOF(VSR57) && o+sz <= GOF(VSR57)+SZB(VSR57)) return 0+ GOF(VSR57);
    337    if (o >= GOF(VSR58) && o+sz <= GOF(VSR58)+SZB(VSR58)) return 0+ GOF(VSR58);
    338    if (o >= GOF(VSR59) && o+sz <= GOF(VSR59)+SZB(VSR59)) return 0+ GOF(VSR59);
    339    if (o >= GOF(VSR60) && o+sz <= GOF(VSR60)+SZB(VSR60)) return 0+ GOF(VSR60);
    340    if (o >= GOF(VSR61) && o+sz <= GOF(VSR61)+SZB(VSR61)) return 0+ GOF(VSR61);
    341    if (o >= GOF(VSR62) && o+sz <= GOF(VSR62)+SZB(VSR62)) return 0+ GOF(VSR62);
    342    if (o >= GOF(VSR63) && o+sz <= GOF(VSR63)+SZB(VSR63)) return 0+ GOF(VSR63);
    343 
    344    VG_(printf)("MC_(get_otrack_shadow_offset)(ppc64)(off=%d,sz=%d)\n",
    345                offset,szB);
    346    tl_assert(0);
    347 #  undef GOF
    348 #  undef SZB
    349 
    350    /* -------------------- ppc32 -------------------- */
    351 
    352 #  elif defined(VGA_ppc32)
    353 
    354 #  define GOF(_fieldname) \
    355       (offsetof(VexGuestPPC32State,guest_##_fieldname))
    356 #  define SZB(_fieldname) \
    357       (sizeof(((VexGuestPPC32State*)0)->guest_##_fieldname))
    358    Int  o  = offset;
    359    Int  sz = szB;
    360    tl_assert(sz > 0);
    361    tl_assert(host_is_big_endian());
    362 
    363    if (o == GOF(GPR0) && sz == 4) return o;
    364    if (o == GOF(GPR1) && sz == 4) return o;
    365    if (o == GOF(GPR2) && sz == 4) return o;
    366    if (o == GOF(GPR3) && sz == 4) return o;
    367    if (o == GOF(GPR4) && sz == 4) return o;
    368    if (o == GOF(GPR5) && sz == 4) return o;
    369    if (o == GOF(GPR6) && sz == 4) return o;
    370    if (o == GOF(GPR7) && sz == 4) return o;
    371    if (o == GOF(GPR8) && sz == 4) return o;
    372    if (o == GOF(GPR9) && sz == 4) return o;
    373    if (o == GOF(GPR10) && sz == 4) return o;
    374    if (o == GOF(GPR11) && sz == 4) return o;
    375    if (o == GOF(GPR12) && sz == 4) return o;
    376    if (o == GOF(GPR13) && sz == 4) return o;
    377    if (o == GOF(GPR14) && sz == 4) return o;
    378    if (o == GOF(GPR15) && sz == 4) return o;
    379    if (o == GOF(GPR16) && sz == 4) return o;
    380    if (o == GOF(GPR17) && sz == 4) return o;
    381    if (o == GOF(GPR18) && sz == 4) return o;
    382    if (o == GOF(GPR19) && sz == 4) return o;
    383    if (o == GOF(GPR20) && sz == 4) return o;
    384    if (o == GOF(GPR21) && sz == 4) return o;
    385    if (o == GOF(GPR22) && sz == 4) return o;
    386    if (o == GOF(GPR23) && sz == 4) return o;
    387    if (o == GOF(GPR24) && sz == 4) return o;
    388    if (o == GOF(GPR25) && sz == 4) return o;
    389    if (o == GOF(GPR26) && sz == 4) return o;
    390    if (o == GOF(GPR27) && sz == 4) return o;
    391    if (o == GOF(GPR28) && sz == 4) return o;
    392    if (o == GOF(GPR29) && sz == 4) return o;
    393    if (o == GOF(GPR30) && sz == 4) return o;
    394    if (o == GOF(GPR31) && sz == 4) return o;
    395 
    396    if (o == GOF(LR)  && sz == 4) return o;
    397    if (o == GOF(CTR) && sz == 4) return o;
    398 
    399    if (o == GOF(CIA)       && sz == 4) return -1;
    400    if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
    401    if (o == GOF(FPROUND)   && sz == 1) return -1;
    402    if (o == GOF(DFPROUND)  && sz == 1) return -1;
    403    if (o == GOF(VRSAVE)    && sz == 4) return -1;
    404    if (o == GOF(EMWARN)    && sz == 4) return -1;
    405    if (o == GOF(TISTART)   && sz == 4) return -1;
    406    if (o == GOF(TILEN)     && sz == 4) return -1;
    407    if (o == GOF(VSCR)      && sz == 4) return -1;
    408    if (o == GOF(REDIR_SP)  && sz == 4) return -1;
    409    if (o == GOF(SPRG3_RO)  && sz == 4) return -1;
    410 
    411    // With ISA 2.06, the "Vector-Scalar Floating-point" category
    412    // provides facilities to support vector and scalar binary floating-
    413    // point operations.  A unified register file is an integral part
    414    // of this new facility, combining floating point and vector registers
    415    // using a 64x128-bit vector.  These are referred to as VSR[0..63].
    416    // The floating point registers are now mapped into double word element 0
    417    // of VSR[0..31]. The 32x128-bit vector registers defined by the "Vector
    418    // Facility [Category: Vector]" are now mapped to VSR[32..63].
    419 
    420    //  Floating point registers . . .
    421    if (o == GOF(VSR0) && sz == 8) return o;
    422    if (o == GOF(VSR1) && sz == 8) return o;
    423    if (o == GOF(VSR2) && sz == 8) return o;
    424    if (o == GOF(VSR3) && sz == 8) return o;
    425    if (o == GOF(VSR4) && sz == 8) return o;
    426    if (o == GOF(VSR5) && sz == 8) return o;
    427    if (o == GOF(VSR6) && sz == 8) return o;
    428    if (o == GOF(VSR7) && sz == 8) return o;
    429    if (o == GOF(VSR8) && sz == 8) return o;
    430    if (o == GOF(VSR9) && sz == 8) return o;
    431    if (o == GOF(VSR10) && sz == 8) return o;
    432    if (o == GOF(VSR11) && sz == 8) return o;
    433    if (o == GOF(VSR12) && sz == 8) return o;
    434    if (o == GOF(VSR13) && sz == 8) return o;
    435    if (o == GOF(VSR14) && sz == 8) return o;
    436    if (o == GOF(VSR15) && sz == 8) return o;
    437    if (o == GOF(VSR16) && sz == 8) return o;
    438    if (o == GOF(VSR17) && sz == 8) return o;
    439    if (o == GOF(VSR18) && sz == 8) return o;
    440    if (o == GOF(VSR19) && sz == 8) return o;
    441    if (o == GOF(VSR20) && sz == 8) return o;
    442    if (o == GOF(VSR21) && sz == 8) return o;
    443    if (o == GOF(VSR22) && sz == 8) return o;
    444    if (o == GOF(VSR23) && sz == 8) return o;
    445    if (o == GOF(VSR24) && sz == 8) return o;
    446    if (o == GOF(VSR25) && sz == 8) return o;
    447    if (o == GOF(VSR26) && sz == 8) return o;
    448    if (o == GOF(VSR27) && sz == 8) return o;
    449    if (o == GOF(VSR28) && sz == 8) return o;
    450    if (o == GOF(VSR29) && sz == 8) return o;
    451    if (o == GOF(VSR30) && sz == 8) return o;
    452    if (o == GOF(VSR31) && sz == 8) return o;
    453 
    454    /* For the various byte sized XER/CR pieces, use offset 8
    455       in VSR0 .. VSR19. */
    456    tl_assert(SZB(VSR0) == 16);
    457    if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VSR0);
    458    if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VSR1);
    459    if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VSR2);
    460    if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VSR3);
    461 
    462    if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VSR4);
    463    if (o == GOF(CR0_0)   && sz == 1) return 8 +GOF(VSR5);
    464    if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VSR6);
    465    if (o == GOF(CR1_0)   && sz == 1) return 8 +GOF(VSR7);
    466    if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VSR8);
    467    if (o == GOF(CR2_0)   && sz == 1) return 8 +GOF(VSR9);
    468    if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VSR10);
    469    if (o == GOF(CR3_0)   && sz == 1) return 8 +GOF(VSR11);
    470    if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VSR12);
    471    if (o == GOF(CR4_0)   && sz == 1) return 8 +GOF(VSR13);
    472    if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VSR14);
    473    if (o == GOF(CR5_0)   && sz == 1) return 8 +GOF(VSR15);
    474    if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VSR16);
    475    if (o == GOF(CR6_0)   && sz == 1) return 8 +GOF(VSR17);
    476    if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VSR18);
    477    if (o == GOF(CR7_0)   && sz == 1) return 8 +GOF(VSR19);
    478 
    479    /* Vector registers .. use offset 0 in VSR0 .. VSR63. */
    480    if (o >= GOF(VSR0)  && o+sz <= GOF(VSR0) +SZB(VSR0))  return 0+ GOF(VSR0);
    481    if (o >= GOF(VSR1)  && o+sz <= GOF(VSR1) +SZB(VSR1))  return 0+ GOF(VSR1);
    482    if (o >= GOF(VSR2)  && o+sz <= GOF(VSR2) +SZB(VSR2))  return 0+ GOF(VSR2);
    483    if (o >= GOF(VSR3)  && o+sz <= GOF(VSR3) +SZB(VSR3))  return 0+ GOF(VSR3);
    484    if (o >= GOF(VSR4)  && o+sz <= GOF(VSR4) +SZB(VSR4))  return 0+ GOF(VSR4);
    485    if (o >= GOF(VSR5)  && o+sz <= GOF(VSR5) +SZB(VSR5))  return 0+ GOF(VSR5);
    486    if (o >= GOF(VSR6)  && o+sz <= GOF(VSR6) +SZB(VSR6))  return 0+ GOF(VSR6);
    487    if (o >= GOF(VSR7)  && o+sz <= GOF(VSR7) +SZB(VSR7))  return 0+ GOF(VSR7);
    488    if (o >= GOF(VSR8)  && o+sz <= GOF(VSR8) +SZB(VSR8))  return 0+ GOF(VSR8);
    489    if (o >= GOF(VSR9)  && o+sz <= GOF(VSR9) +SZB(VSR9))  return 0+ GOF(VSR9);
    490    if (o >= GOF(VSR10) && o+sz <= GOF(VSR10)+SZB(VSR10)) return 0+ GOF(VSR10);
    491    if (o >= GOF(VSR11) && o+sz <= GOF(VSR11)+SZB(VSR11)) return 0+ GOF(VSR11);
    492    if (o >= GOF(VSR12) && o+sz <= GOF(VSR12)+SZB(VSR12)) return 0+ GOF(VSR12);
    493    if (o >= GOF(VSR13) && o+sz <= GOF(VSR13)+SZB(VSR13)) return 0+ GOF(VSR13);
    494    if (o >= GOF(VSR14) && o+sz <= GOF(VSR14)+SZB(VSR14)) return 0+ GOF(VSR14);
    495    if (o >= GOF(VSR15) && o+sz <= GOF(VSR15)+SZB(VSR15)) return 0+ GOF(VSR15);
    496    if (o >= GOF(VSR16) && o+sz <= GOF(VSR16)+SZB(VSR16)) return 0+ GOF(VSR16);
    497    if (o >= GOF(VSR17) && o+sz <= GOF(VSR17)+SZB(VSR17)) return 0+ GOF(VSR17);
    498    if (o >= GOF(VSR18) && o+sz <= GOF(VSR18)+SZB(VSR18)) return 0+ GOF(VSR18);
    499    if (o >= GOF(VSR19) && o+sz <= GOF(VSR19)+SZB(VSR19)) return 0+ GOF(VSR19);
    500    if (o >= GOF(VSR20) && o+sz <= GOF(VSR20)+SZB(VSR20)) return 0+ GOF(VSR20);
    501    if (o >= GOF(VSR21) && o+sz <= GOF(VSR21)+SZB(VSR21)) return 0+ GOF(VSR21);
    502    if (o >= GOF(VSR22) && o+sz <= GOF(VSR22)+SZB(VSR22)) return 0+ GOF(VSR22);
    503    if (o >= GOF(VSR23) && o+sz <= GOF(VSR23)+SZB(VSR23)) return 0+ GOF(VSR23);
    504    if (o >= GOF(VSR24) && o+sz <= GOF(VSR24)+SZB(VSR24)) return 0+ GOF(VSR24);
    505    if (o >= GOF(VSR25) && o+sz <= GOF(VSR25)+SZB(VSR25)) return 0+ GOF(VSR25);
    506    if (o >= GOF(VSR26) && o+sz <= GOF(VSR26)+SZB(VSR26)) return 0+ GOF(VSR26);
    507    if (o >= GOF(VSR27) && o+sz <= GOF(VSR27)+SZB(VSR27)) return 0+ GOF(VSR27);
    508    if (o >= GOF(VSR28) && o+sz <= GOF(VSR28)+SZB(VSR28)) return 0+ GOF(VSR28);
    509    if (o >= GOF(VSR29) && o+sz <= GOF(VSR29)+SZB(VSR29)) return 0+ GOF(VSR29);
    510    if (o >= GOF(VSR30) && o+sz <= GOF(VSR30)+SZB(VSR30)) return 0+ GOF(VSR30);
    511    if (o >= GOF(VSR31) && o+sz <= GOF(VSR31)+SZB(VSR31)) return 0+ GOF(VSR31);
    512    if (o >= GOF(VSR32) && o+sz <= GOF(VSR32)+SZB(VSR32)) return 0+ GOF(VSR32);
    513    if (o >= GOF(VSR33) && o+sz <= GOF(VSR33)+SZB(VSR33)) return 0+ GOF(VSR33);
    514    if (o >= GOF(VSR34) && o+sz <= GOF(VSR34)+SZB(VSR34)) return 0+ GOF(VSR34);
    515    if (o >= GOF(VSR35) && o+sz <= GOF(VSR35)+SZB(VSR35)) return 0+ GOF(VSR35);
    516    if (o >= GOF(VSR36) && o+sz <= GOF(VSR36)+SZB(VSR36)) return 0+ GOF(VSR36);
    517    if (o >= GOF(VSR37) && o+sz <= GOF(VSR37)+SZB(VSR37)) return 0+ GOF(VSR37);
    518    if (o >= GOF(VSR38) && o+sz <= GOF(VSR38)+SZB(VSR38)) return 0+ GOF(VSR38);
    519    if (o >= GOF(VSR39) && o+sz <= GOF(VSR39)+SZB(VSR39)) return 0+ GOF(VSR39);
    520    if (o >= GOF(VSR40) && o+sz <= GOF(VSR40)+SZB(VSR40)) return 0+ GOF(VSR40);
    521    if (o >= GOF(VSR41) && o+sz <= GOF(VSR41)+SZB(VSR41)) return 0+ GOF(VSR41);
    522    if (o >= GOF(VSR42) && o+sz <= GOF(VSR42)+SZB(VSR42)) return 0+ GOF(VSR42);
    523    if (o >= GOF(VSR43) && o+sz <= GOF(VSR43)+SZB(VSR43)) return 0+ GOF(VSR43);
    524    if (o >= GOF(VSR44) && o+sz <= GOF(VSR44)+SZB(VSR44)) return 0+ GOF(VSR44);
    525    if (o >= GOF(VSR45) && o+sz <= GOF(VSR45)+SZB(VSR45)) return 0+ GOF(VSR45);
    526    if (o >= GOF(VSR46) && o+sz <= GOF(VSR46)+SZB(VSR46)) return 0+ GOF(VSR46);
    527    if (o >= GOF(VSR47) && o+sz <= GOF(VSR47)+SZB(VSR47)) return 0+ GOF(VSR47);
    528    if (o >= GOF(VSR48) && o+sz <= GOF(VSR48)+SZB(VSR48)) return 0+ GOF(VSR48);
    529    if (o >= GOF(VSR49) && o+sz <= GOF(VSR49)+SZB(VSR49)) return 0+ GOF(VSR49);
    530    if (o >= GOF(VSR50) && o+sz <= GOF(VSR50)+SZB(VSR50)) return 0+ GOF(VSR50);
    531    if (o >= GOF(VSR51) && o+sz <= GOF(VSR51)+SZB(VSR51)) return 0+ GOF(VSR51);
    532    if (o >= GOF(VSR52) && o+sz <= GOF(VSR52)+SZB(VSR52)) return 0+ GOF(VSR52);
    533    if (o >= GOF(VSR53) && o+sz <= GOF(VSR53)+SZB(VSR53)) return 0+ GOF(VSR53);
    534    if (o >= GOF(VSR54) && o+sz <= GOF(VSR54)+SZB(VSR54)) return 0+ GOF(VSR54);
    535    if (o >= GOF(VSR55) && o+sz <= GOF(VSR55)+SZB(VSR55)) return 0+ GOF(VSR55);
    536    if (o >= GOF(VSR56) && o+sz <= GOF(VSR56)+SZB(VSR56)) return 0+ GOF(VSR56);
    537    if (o >= GOF(VSR57) && o+sz <= GOF(VSR57)+SZB(VSR57)) return 0+ GOF(VSR57);
    538    if (o >= GOF(VSR58) && o+sz <= GOF(VSR58)+SZB(VSR58)) return 0+ GOF(VSR58);
    539    if (o >= GOF(VSR59) && o+sz <= GOF(VSR59)+SZB(VSR59)) return 0+ GOF(VSR59);
    540    if (o >= GOF(VSR60) && o+sz <= GOF(VSR60)+SZB(VSR60)) return 0+ GOF(VSR60);
    541    if (o >= GOF(VSR61) && o+sz <= GOF(VSR61)+SZB(VSR61)) return 0+ GOF(VSR61);
    542    if (o >= GOF(VSR62) && o+sz <= GOF(VSR62)+SZB(VSR62)) return 0+ GOF(VSR62);
    543    if (o >= GOF(VSR63) && o+sz <= GOF(VSR63)+SZB(VSR63)) return 0+ GOF(VSR63);
    544 
    545    VG_(printf)("MC_(get_otrack_shadow_offset)(ppc32)(off=%d,sz=%d)\n",
    546                offset,szB);
    547    tl_assert(0);
    548 #  undef GOF
    549 #  undef SZB
    550 
    551    /* -------------------- amd64 -------------------- */
    552 
    553 #  elif defined(VGA_amd64)
    554 
    555 #  define GOF(_fieldname) \
    556       (offsetof(VexGuestAMD64State,guest_##_fieldname))
    557 #  define SZB(_fieldname) \
    558       (sizeof(((VexGuestAMD64State*)0)->guest_##_fieldname))
    559    Int  o      = offset;
    560    Int  sz     = szB;
    561    Bool is1248 = sz == 8 || sz == 4 || sz == 2 || sz == 1;
    562    tl_assert(sz > 0);
    563    tl_assert(host_is_little_endian());
    564 
    565    if (o == GOF(RAX) && is1248) return o;
    566    if (o == GOF(RCX) && is1248) return o;
    567    if (o == GOF(RDX) && is1248) return o;
    568    if (o == GOF(RBX) && is1248) return o;
    569    if (o == GOF(RSP) && is1248) return o;
    570    if (o == GOF(RBP) && is1248) return o;
    571    if (o == GOF(RSI) && is1248) return o;
    572    if (o == GOF(RDI) && is1248) return o;
    573    if (o == GOF(R8)  && is1248) return o;
    574    if (o == GOF(R9)  && is1248) return o;
    575    if (o == GOF(R10) && is1248) return o;
    576    if (o == GOF(R11) && is1248) return o;
    577    if (o == GOF(R12) && is1248) return o;
    578    if (o == GOF(R13) && is1248) return o;
    579    if (o == GOF(R14) && is1248) return o;
    580    if (o == GOF(R15) && is1248) return o;
    581 
    582    if (o == GOF(CC_DEP1) && sz == 8) return o;
    583    if (o == GOF(CC_DEP2) && sz == 8) return o;
    584 
    585    if (o == GOF(CC_OP)   && sz == 8) return -1; /* slot used for %AH */
    586    if (o == GOF(CC_NDEP) && sz == 8) return -1; /* slot used for %BH */
    587    if (o == GOF(DFLAG)   && sz == 8) return -1; /* slot used for %CH */
    588    if (o == GOF(RIP)     && sz == 8) return -1; /* slot unused */
    589    if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
    590    if (o == GOF(IDFLAG)  && sz == 8) return -1; /* slot used for %DH */
    591    if (o == GOF(ACFLAG)  && sz == 8) return -1; /* slot unused */
    592    if (o == GOF(FS_ZERO) && sz == 8) return -1; /* slot unused */
    593    if (o == GOF(GS_0x60) && sz == 8) return -1; /* slot unused */
    594    if (o == GOF(TISTART) && sz == 8) return -1; /* slot unused */
    595    if (o == GOF(TILEN)   && sz == 8) return -1; /* slot unused */
    596 
    597    /* Treat %AH, %BH, %CH, %DH as independent registers.  To do this
    598       requires finding 4 unused 32-bit slots in the second-shadow
    599       guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG, since
    600       none of those are tracked. */
    601    tl_assert(SZB(CC_OP)   == 8);
    602    tl_assert(SZB(CC_NDEP) == 8);
    603    tl_assert(SZB(IDFLAG)  == 8);
    604    tl_assert(SZB(DFLAG)   == 8);
    605 
    606    if (o == 1+ GOF(RAX) && szB == 1) return GOF(CC_OP);
    607    if (o == 1+ GOF(RBX) && szB == 1) return GOF(CC_NDEP);
    608    if (o == 1+ GOF(RCX) && szB == 1) return GOF(DFLAG);
    609    if (o == 1+ GOF(RDX) && szB == 1) return GOF(IDFLAG);
    610 
    611    /* skip XMM and FP admin stuff */
    612    if (o == GOF(SSEROUND) && szB == 8) return -1;
    613    if (o == GOF(FTOP)     && szB == 4) return -1;
    614    if (o == GOF(FPROUND)  && szB == 8) return -1;
    615    if (o == GOF(EMWARN)   && szB == 4) return -1;
    616    if (o == GOF(FC3210)   && szB == 8) return -1;
    617 
    618    /* XMM registers */
    619    if (o >= GOF(YMM0)  && o+sz <= GOF(YMM0) +SZB(YMM0))  return GOF(YMM0);
    620    if (o >= GOF(YMM1)  && o+sz <= GOF(YMM1) +SZB(YMM1))  return GOF(YMM1);
    621    if (o >= GOF(YMM2)  && o+sz <= GOF(YMM2) +SZB(YMM2))  return GOF(YMM2);
    622    if (o >= GOF(YMM3)  && o+sz <= GOF(YMM3) +SZB(YMM3))  return GOF(YMM3);
    623    if (o >= GOF(YMM4)  && o+sz <= GOF(YMM4) +SZB(YMM4))  return GOF(YMM4);
    624    if (o >= GOF(YMM5)  && o+sz <= GOF(YMM5) +SZB(YMM5))  return GOF(YMM5);
    625    if (o >= GOF(YMM6)  && o+sz <= GOF(YMM6) +SZB(YMM6))  return GOF(YMM6);
    626    if (o >= GOF(YMM7)  && o+sz <= GOF(YMM7) +SZB(YMM7))  return GOF(YMM7);
    627    if (o >= GOF(YMM8)  && o+sz <= GOF(YMM8) +SZB(YMM8))  return GOF(YMM8);
    628    if (o >= GOF(YMM9)  && o+sz <= GOF(YMM9) +SZB(YMM9))  return GOF(YMM9);
    629    if (o >= GOF(YMM10) && o+sz <= GOF(YMM10)+SZB(YMM10)) return GOF(YMM10);
    630    if (o >= GOF(YMM11) && o+sz <= GOF(YMM11)+SZB(YMM11)) return GOF(YMM11);
    631    if (o >= GOF(YMM12) && o+sz <= GOF(YMM12)+SZB(YMM12)) return GOF(YMM12);
    632    if (o >= GOF(YMM13) && o+sz <= GOF(YMM13)+SZB(YMM13)) return GOF(YMM13);
    633    if (o >= GOF(YMM14) && o+sz <= GOF(YMM14)+SZB(YMM14)) return GOF(YMM14);
    634    if (o >= GOF(YMM15) && o+sz <= GOF(YMM15)+SZB(YMM15)) return GOF(YMM15);
    635    if (o >= GOF(YMM16) && o+sz <= GOF(YMM16)+SZB(YMM16)) return GOF(YMM16);
    636 
    637    /* MMX accesses to FP regs.  Need to allow for 32-bit references
    638       due to dirty helpers for frstor etc, which reference the entire
    639       64-byte block in one go. */
    640    if (o >= GOF(FPREG[0])
    641        && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
    642    if (o >= GOF(FPREG[1])
    643        && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
    644    if (o >= GOF(FPREG[2])
    645        && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
    646    if (o >= GOF(FPREG[3])
    647        && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
    648    if (o >= GOF(FPREG[4])
    649        && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
    650    if (o >= GOF(FPREG[5])
    651        && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
    652    if (o >= GOF(FPREG[6])
    653        && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
    654    if (o >= GOF(FPREG[7])
    655        && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
    656 
    657    /* Map high halves of %RAX,%RCX,%RDX,%RBX to the whole register.
    658       This is needed because the general handling of dirty helper
    659       calls is done in 4 byte chunks.  Hence we will see these.
    660       Currently we only expect to see artefacts from CPUID. */
    661    if (o == 4+ GOF(RAX) && sz == 4) return GOF(RAX);
    662    if (o == 4+ GOF(RCX) && sz == 4) return GOF(RCX);
    663    if (o == 4+ GOF(RDX) && sz == 4) return GOF(RDX);
    664    if (o == 4+ GOF(RBX) && sz == 4) return GOF(RBX);
    665 
    666    VG_(printf)("MC_(get_otrack_shadow_offset)(amd64)(off=%d,sz=%d)\n",
    667                offset,szB);
    668    tl_assert(0);
    669 #  undef GOF
    670 #  undef SZB
    671 
    672    /* --------------------- x86 --------------------- */
    673 
    674 #  elif defined(VGA_x86)
    675 
    676 #  define GOF(_fieldname) \
    677       (offsetof(VexGuestX86State,guest_##_fieldname))
    678 #  define SZB(_fieldname) \
    679       (sizeof(((VexGuestX86State*)0)->guest_##_fieldname))
    680 
    681    Int  o     = offset;
    682    Int  sz    = szB;
    683    Bool is124 = sz == 4 || sz == 2 || sz == 1;
    684    tl_assert(sz > 0);
    685    tl_assert(host_is_little_endian());
    686 
    687    if (o == GOF(EAX) && is124) return o;
    688    if (o == GOF(ECX) && is124) return o;
    689    if (o == GOF(EDX) && is124) return o;
    690    if (o == GOF(EBX) && is124) return o;
    691    if (o == GOF(ESP) && is124) return o;
    692    if (o == GOF(EBP) && is124) return o;
    693    if (o == GOF(ESI) && is124) return o;
    694    if (o == GOF(EDI) && is124) return o;
    695 
    696    if (o == GOF(CC_DEP1) && sz == 4) return o;
    697    if (o == GOF(CC_DEP2) && sz == 4) return o;
    698 
    699    if (o == GOF(CC_OP)   && sz == 4) return -1; /* slot used for %AH */
    700    if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot used for %BH */
    701    if (o == GOF(DFLAG)   && sz == 4) return -1; /* slot used for %CH */
    702    if (o == GOF(EIP)     && sz == 4) return -1; /* slot unused */
    703    if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
    704    if (o == GOF(IDFLAG)  && sz == 4) return -1; /* slot used for %DH */
    705    if (o == GOF(ACFLAG)  && sz == 4) return -1; /* slot unused */
    706    if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
    707    if (o == GOF(TILEN)   && sz == 4) return -1; /* slot unused */
    708    if (o == GOF(NRADDR)  && sz == 4) return -1; /* slot unused */
    709 
    710    /* Treat %AH, %BH, %CH, %DH as independent registers.  To do this
    711       requires finding 4 unused 32-bit slots in the second-shadow
    712       guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG since none
    713       of those are tracked. */
    714    tl_assert(SZB(CC_OP)   == 4);
    715    tl_assert(SZB(CC_NDEP) == 4);
    716    tl_assert(SZB(DFLAG)   == 4);
    717    tl_assert(SZB(IDFLAG)  == 4);
    718    if (o == 1+ GOF(EAX) && szB == 1) return GOF(CC_OP);
    719    if (o == 1+ GOF(EBX) && szB == 1) return GOF(CC_NDEP);
    720    if (o == 1+ GOF(ECX) && szB == 1) return GOF(DFLAG);
    721    if (o == 1+ GOF(EDX) && szB == 1) return GOF(IDFLAG);
    722 
    723    /* skip XMM and FP admin stuff */
    724    if (o == GOF(SSEROUND) && szB == 4) return -1;
    725    if (o == GOF(FTOP)     && szB == 4) return -1;
    726    if (o == GOF(FPROUND)  && szB == 4) return -1;
    727    if (o == GOF(EMWARN)   && szB == 4) return -1;
    728    if (o == GOF(FC3210)   && szB == 4) return -1;
    729 
    730    /* XMM registers */
    731    if (o >= GOF(XMM0)  && o+sz <= GOF(XMM0)+SZB(XMM0)) return GOF(XMM0);
    732    if (o >= GOF(XMM1)  && o+sz <= GOF(XMM1)+SZB(XMM1)) return GOF(XMM1);
    733    if (o >= GOF(XMM2)  && o+sz <= GOF(XMM2)+SZB(XMM2)) return GOF(XMM2);
    734    if (o >= GOF(XMM3)  && o+sz <= GOF(XMM3)+SZB(XMM3)) return GOF(XMM3);
    735    if (o >= GOF(XMM4)  && o+sz <= GOF(XMM4)+SZB(XMM4)) return GOF(XMM4);
    736    if (o >= GOF(XMM5)  && o+sz <= GOF(XMM5)+SZB(XMM5)) return GOF(XMM5);
    737    if (o >= GOF(XMM6)  && o+sz <= GOF(XMM6)+SZB(XMM6)) return GOF(XMM6);
    738    if (o >= GOF(XMM7)  && o+sz <= GOF(XMM7)+SZB(XMM7)) return GOF(XMM7);
    739 
    740    /* MMX accesses to FP regs.  Need to allow for 32-bit references
    741       due to dirty helpers for frstor etc, which reference the entire
    742       64-byte block in one go. */
    743    if (o >= GOF(FPREG[0])
    744        && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
    745    if (o >= GOF(FPREG[1])
    746        && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
    747    if (o >= GOF(FPREG[2])
    748        && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
    749    if (o >= GOF(FPREG[3])
    750        && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
    751    if (o >= GOF(FPREG[4])
    752        && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
    753    if (o >= GOF(FPREG[5])
    754        && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
    755    if (o >= GOF(FPREG[6])
    756        && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
    757    if (o >= GOF(FPREG[7])
    758        && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
    759 
    760    /* skip %GS and other segment related stuff.  We could shadow
    761       guest_LDT and guest_GDT, although it seems pointless.
    762       guest_CS .. guest_SS are too small to shadow directly and it
    763       also seems pointless to shadow them indirectly (that is, in
    764       the style of %AH .. %DH). */
    765    if (o == GOF(CS) && sz == 2) return -1;
    766    if (o == GOF(DS) && sz == 2) return -1;
    767    if (o == GOF(ES) && sz == 2) return -1;
    768    if (o == GOF(FS) && sz == 2) return -1;
    769    if (o == GOF(GS) && sz == 2) return -1;
    770    if (o == GOF(SS) && sz == 2) return -1;
    771    if (o == GOF(LDT) && sz == 4) return -1;
    772    if (o == GOF(GDT) && sz == 4) return -1;
    773 
    774    VG_(printf)("MC_(get_otrack_shadow_offset)(x86)(off=%d,sz=%d)\n",
    775                offset,szB);
    776    tl_assert(0);
    777 #  undef GOF
    778 #  undef SZB
    779 
    780    /* -------------------- s390x -------------------- */
    781 
    782 #  elif defined(VGA_s390x)
    783 #  define GOF(_fieldname) \
    784       (offsetof(VexGuestS390XState,guest_##_fieldname))
    785    Int  o      = offset;
    786    Int  sz     = szB;
    787    tl_assert(sz > 0);
    788    tl_assert(host_is_big_endian());
    789 
    790    /* no matter what byte(s) we change, we have changed the full 8 byte value
    791       and need to track this change for the whole register */
    792    if (o >= GOF(r0) && sz <= 8 && o <= (GOF(r15) + 8 - sz))
    793       return GOF(r0) + ((o-GOF(r0)) & -8) ;
    794 
    795 
    796    /* fprs are accessed 4 or 8 byte at once. Again, we track that change for
    797       the full register */
    798    if ((sz == 8 || sz == 4) && o >= GOF(f0) && o <= GOF(f15)+8-sz)
    799       return GOF(f0) + ((o-GOF(f0)) & -8) ;
    800 
    801    /* access registers are accessed 4 bytes at once */
    802    if (sz == 4 && o >= GOF(a0) && o <= GOF(a15))
    803          return o;
    804 
    805    /* we access the guest counter either fully or one of the 4byte words */
    806    if (o == GOF(counter) && (sz == 8 || sz ==4))
    807       return o;
    808    if (o == GOF(counter) + 4 && sz == 4)
    809       return o;
    810 
    811    if (o == GOF(CC_OP)) return -1;
    812    if (o == GOF(CC_DEP1)) return o;
    813    if (o == GOF(CC_DEP2)) return o;
    814    if (o == GOF(CC_NDEP)) return -1;
    815    if (o == GOF(TISTART)) return -1;
    816    if (o == GOF(TILEN)) return -1;
    817    if (o == GOF(NRADDR)) return -1;
    818    if (o == GOF(IP_AT_SYSCALL)) return -1;
    819    if (o == GOF(fpc)) return -1;
    820    if (o == GOF(IA)) return -1;
    821    if (o == GOF(IA) + 4) return -1;
    822    if (o == GOF(SYSNO)) return -1;
    823    VG_(printf)("MC_(get_otrack_shadow_offset)(s390x)(off=%d,sz=%d)\n",
    824                offset,szB);
    825    tl_assert(0);
    826 #  undef GOF
    827 
    828 
    829    /* --------------------- arm --------------------- */
    830 
    831 #  elif defined(VGA_arm)
    832 
    833 #  define GOF(_fieldname) \
    834       (offsetof(VexGuestARMState,guest_##_fieldname))
    835 #  define SZB(_fieldname) \
    836       (sizeof(((VexGuestARMState*)0)->guest_##_fieldname))
    837 
    838    Int  o     = offset;
    839    Int  sz    = szB;
    840    tl_assert(sz > 0);
    841    tl_assert(host_is_little_endian());
    842 
    843    if (o == GOF(R0)  && sz == 4) return o;
    844    if (o == GOF(R1)  && sz == 4) return o;
    845    if (o == GOF(R2)  && sz == 4) return o;
    846    if (o == GOF(R3)  && sz == 4) return o;
    847    if (o == GOF(R4)  && sz == 4) return o;
    848    if (o == GOF(R5)  && sz == 4) return o;
    849    if (o == GOF(R6)  && sz == 4) return o;
    850    if (o == GOF(R7)  && sz == 4) return o;
    851    if (o == GOF(R8)  && sz == 4) return o;
    852    if (o == GOF(R9)  && sz == 4) return o;
    853    if (o == GOF(R10) && sz == 4) return o;
    854    if (o == GOF(R11) && sz == 4) return o;
    855    if (o == GOF(R12) && sz == 4) return o;
    856    if (o == GOF(R13) && sz == 4) return o;
    857    if (o == GOF(R14) && sz == 4) return o;
    858 
    859    /* EAZG: These may be completely wrong. */
    860    if (o == GOF(R15T)  && sz == 4) return -1; /* slot unused */
    861    if (o == GOF(CC_OP) && sz == 4) return -1; /* slot unused */
    862 
    863    if (o == GOF(CC_DEP1) && sz == 4) return o;
    864    if (o == GOF(CC_DEP2) && sz == 4) return o;
    865 
    866    if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot unused */
    867 
    868    if (o == GOF(QFLAG32) && sz == 4) return o;
    869 
    870    if (o == GOF(GEFLAG0) && sz == 4) return o;
    871    if (o == GOF(GEFLAG1) && sz == 4) return o;
    872    if (o == GOF(GEFLAG2) && sz == 4) return o;
    873    if (o == GOF(GEFLAG3) && sz == 4) return o;
    874 
    875    //if (o == GOF(SYSCALLNO)     && sz == 4) return -1; /* slot unused */
    876    //if (o == GOF(CC)     && sz == 4) return -1; /* slot unused */
    877    //if (o == GOF(EMWARN)     && sz == 4) return -1; /* slot unused */
    878    //if (o == GOF(TISTART)     && sz == 4) return -1; /* slot unused */
    879    //if (o == GOF(NRADDR)     && sz == 4) return -1; /* slot unused */
    880 
    881    if (o == GOF(FPSCR)    && sz == 4) return -1;
    882    if (o == GOF(TPIDRURO) && sz == 4) return -1;
    883    if (o == GOF(ITSTATE)  && sz == 4) return -1;
    884 
    885    /* Accesses to F or D registers */
    886    if (sz == 4 || sz == 8) {
    887       if (o >= GOF(D0)  && o+sz <= GOF(D0) +SZB(D0))  return GOF(D0);
    888       if (o >= GOF(D1)  && o+sz <= GOF(D1) +SZB(D1))  return GOF(D1);
    889       if (o >= GOF(D2)  && o+sz <= GOF(D2) +SZB(D2))  return GOF(D2);
    890       if (o >= GOF(D3)  && o+sz <= GOF(D3) +SZB(D3))  return GOF(D3);
    891       if (o >= GOF(D4)  && o+sz <= GOF(D4) +SZB(D4))  return GOF(D4);
    892       if (o >= GOF(D5)  && o+sz <= GOF(D5) +SZB(D5))  return GOF(D5);
    893       if (o >= GOF(D6)  && o+sz <= GOF(D6) +SZB(D6))  return GOF(D6);
    894       if (o >= GOF(D7)  && o+sz <= GOF(D7) +SZB(D7))  return GOF(D7);
    895       if (o >= GOF(D8)  && o+sz <= GOF(D8) +SZB(D8))  return GOF(D8);
    896       if (o >= GOF(D9)  && o+sz <= GOF(D9) +SZB(D9))  return GOF(D9);
    897       if (o >= GOF(D10) && o+sz <= GOF(D10)+SZB(D10)) return GOF(D10);
    898       if (o >= GOF(D11) && o+sz <= GOF(D11)+SZB(D11)) return GOF(D11);
    899       if (o >= GOF(D12) && o+sz <= GOF(D12)+SZB(D12)) return GOF(D12);
    900       if (o >= GOF(D13) && o+sz <= GOF(D13)+SZB(D13)) return GOF(D13);
    901       if (o >= GOF(D14) && o+sz <= GOF(D14)+SZB(D14)) return GOF(D14);
    902       if (o >= GOF(D15) && o+sz <= GOF(D15)+SZB(D15)) return GOF(D15);
    903       if (o >= GOF(D16) && o+sz <= GOF(D16)+SZB(D16)) return GOF(D16);
    904       if (o >= GOF(D17) && o+sz <= GOF(D17)+SZB(D17)) return GOF(D17);
    905       if (o >= GOF(D18) && o+sz <= GOF(D18)+SZB(D18)) return GOF(D18);
    906       if (o >= GOF(D19) && o+sz <= GOF(D19)+SZB(D19)) return GOF(D19);
    907       if (o >= GOF(D20) && o+sz <= GOF(D20)+SZB(D20)) return GOF(D20);
    908       if (o >= GOF(D21) && o+sz <= GOF(D21)+SZB(D21)) return GOF(D21);
    909       if (o >= GOF(D22) && o+sz <= GOF(D22)+SZB(D22)) return GOF(D22);
    910       if (o >= GOF(D23) && o+sz <= GOF(D23)+SZB(D23)) return GOF(D23);
    911       if (o >= GOF(D24) && o+sz <= GOF(D24)+SZB(D24)) return GOF(D24);
    912       if (o >= GOF(D25) && o+sz <= GOF(D25)+SZB(D25)) return GOF(D25);
    913       if (o >= GOF(D26) && o+sz <= GOF(D26)+SZB(D26)) return GOF(D26);
    914       if (o >= GOF(D27) && o+sz <= GOF(D27)+SZB(D27)) return GOF(D27);
    915       if (o >= GOF(D28) && o+sz <= GOF(D28)+SZB(D28)) return GOF(D28);
    916       if (o >= GOF(D29) && o+sz <= GOF(D29)+SZB(D29)) return GOF(D29);
    917       if (o >= GOF(D30) && o+sz <= GOF(D30)+SZB(D30)) return GOF(D30);
    918       if (o >= GOF(D31) && o+sz <= GOF(D31)+SZB(D31)) return GOF(D31);
    919    }
    920 
    921    /* Accesses to Q registers */
    922    if (sz == 16) {
    923       if (o >= GOF(D0)  && o+sz <= GOF(D0) +2*SZB(D0))  return GOF(D0);  // Q0
    924       if (o >= GOF(D2)  && o+sz <= GOF(D2) +2*SZB(D2))  return GOF(D2);  // Q1
    925       if (o >= GOF(D4)  && o+sz <= GOF(D4) +2*SZB(D4))  return GOF(D4);  // Q2
    926       if (o >= GOF(D6)  && o+sz <= GOF(D6) +2*SZB(D6))  return GOF(D6);  // Q3
    927       if (o >= GOF(D8)  && o+sz <= GOF(D8) +2*SZB(D8))  return GOF(D8);  // Q4
    928       if (o >= GOF(D10) && o+sz <= GOF(D10)+2*SZB(D10)) return GOF(D10); // Q5
    929       if (o >= GOF(D12) && o+sz <= GOF(D12)+2*SZB(D12)) return GOF(D12); // Q6
    930       if (o >= GOF(D14) && o+sz <= GOF(D14)+2*SZB(D14)) return GOF(D14); // Q7
    931       if (o >= GOF(D16) && o+sz <= GOF(D16)+2*SZB(D16)) return GOF(D16); // Q8
    932       if (o >= GOF(D18) && o+sz <= GOF(D18)+2*SZB(D18)) return GOF(D18); // Q9
    933       if (o >= GOF(D20) && o+sz <= GOF(D20)+2*SZB(D20)) return GOF(D20); // Q10
    934       if (o >= GOF(D22) && o+sz <= GOF(D22)+2*SZB(D22)) return GOF(D22); // Q11
    935       if (o >= GOF(D24) && o+sz <= GOF(D24)+2*SZB(D24)) return GOF(D24); // Q12
    936       if (o >= GOF(D26) && o+sz <= GOF(D26)+2*SZB(D26)) return GOF(D26); // Q13
    937       if (o >= GOF(D28) && o+sz <= GOF(D28)+2*SZB(D28)) return GOF(D28); // Q14
    938       if (o >= GOF(D30) && o+sz <= GOF(D30)+2*SZB(D30)) return GOF(D30); // Q15
    939    }
    940 
    941    VG_(printf)("MC_(get_otrack_shadow_offset)(arm)(off=%d,sz=%d)\n",
    942                offset,szB);
    943    tl_assert(0);
    944 #  undef GOF
    945 #  undef SZB
    946 
    947    /* --------------------- mips32 --------------------- */
    948 
    949 #  elif defined(VGA_mips32)
    950 
    951 #  define GOF(_fieldname) \
    952       (offsetof(VexGuestMIPS32State,guest_##_fieldname))
    953 #  define SZB(_fieldname) \
    954       (sizeof(((VexGuestMIPS32State*)0)->guest_##_fieldname))
    955 
    956    Int  o     = offset;
    957    Int  sz    = szB;
    958    tl_assert(sz > 0);
    959 #  if defined (VG_LITTLEENDIAN)
    960    tl_assert(host_is_little_endian());
    961 #  elif defined (VG_BIGENDIAN)
    962    tl_assert(host_is_big_endian());
    963 #  else
    964 #     error "Unknown endianness"
    965 #  endif
    966 
    967    if (o == GOF(r0)  && sz == 4) return o;
    968    if (o == GOF(r1)  && sz == 4) return o;
    969    if (o == GOF(r2)  && sz == 4) return o;
    970    if (o == GOF(r3)  && sz == 4) return o;
    971    if (o == GOF(r4)  && sz == 4) return o;
    972    if (o == GOF(r5)  && sz == 4) return o;
    973    if (o == GOF(r6)  && sz == 4) return o;
    974    if (o == GOF(r7)  && sz == 4) return o;
    975    if (o == GOF(r8)  && sz == 4) return o;
    976    if (o == GOF(r9)  && sz == 4) return o;
    977    if (o == GOF(r10)  && sz == 4) return o;
    978    if (o == GOF(r11)  && sz == 4) return o;
    979    if (o == GOF(r12)  && sz == 4) return o;
    980    if (o == GOF(r13)  && sz == 4) return o;
    981    if (o == GOF(r14)  && sz == 4) return o;
    982    if (o == GOF(r15)  && sz == 4) return o;
    983    if (o == GOF(r16)  && sz == 4) return o;
    984    if (o == GOF(r17)  && sz == 4) return o;
    985    if (o == GOF(r18)  && sz == 4) return o;
    986    if (o == GOF(r19)  && sz == 4) return o;
    987    if (o == GOF(r20)  && sz == 4) return o;
    988    if (o == GOF(r21)  && sz == 4) return o;
    989    if (o == GOF(r22)  && sz == 4) return o;
    990    if (o == GOF(r23)  && sz == 4) return o;
    991    if (o == GOF(r24)  && sz == 4) return o;
    992    if (o == GOF(r25)  && sz == 4) return o;
    993    if (o == GOF(r26)  && sz == 4) return o;
    994    if (o == GOF(r27)  && sz == 4) return o;
    995    if (o == GOF(r28)  && sz == 4) return o;
    996    if (o == GOF(r29)  && sz == 4) return o;
    997    if (o == GOF(r30)  && sz == 4) return o;
    998    if (o == GOF(r31)  && sz == 4) return o;
    999    if (o == GOF(PC)  && sz == 4) return -1; /* slot unused */
   1000 
   1001    if (o == GOF(HI)  && sz == 4) return o;
   1002    if (o == GOF(LO)  && sz == 4) return o;
   1003 
   1004    if (o == GOF(FIR)     && sz == 4) return -1; /* slot unused */
   1005    if (o == GOF(FCCR)     && sz == 4) return -1; /* slot unused */
   1006    if (o == GOF(FEXR)     && sz == 4) return -1; /* slot unused */
   1007    if (o == GOF(FENR)     && sz == 4) return -1; /* slot unused */
   1008    if (o == GOF(FCSR)     && sz == 4) return -1; /* slot unused */
   1009    if (o == GOF(ULR) && sz == 4) return -1;
   1010 
   1011    if (o == GOF(EMWARN)     && sz == 4) return -1; /* slot unused */
   1012    if (o == GOF(TISTART)     && sz == 4) return -1; /* slot unused */
   1013    if (o == GOF(TILEN)     && sz == 4) return -1; /* slot unused */
   1014    if (o == GOF(NRADDR)     && sz == 4) return -1; /* slot unused */
   1015 
   1016    if (o >= GOF(f0)  && o+sz <= GOF(f0) +SZB(f0))  return GOF(f0);
   1017    if (o >= GOF(f1)  && o+sz <= GOF(f1) +SZB(f1))  return GOF(f1);
   1018    if (o >= GOF(f2)  && o+sz <= GOF(f2) +SZB(f2))  return GOF(f2);
   1019    if (o >= GOF(f3)  && o+sz <= GOF(f3) +SZB(f3))  return GOF(f3);
   1020    if (o >= GOF(f4)  && o+sz <= GOF(f4) +SZB(f4))  return GOF(f4);
   1021    if (o >= GOF(f5)  && o+sz <= GOF(f5) +SZB(f5))  return GOF(f5);
   1022    if (o >= GOF(f6)  && o+sz <= GOF(f6) +SZB(f6))  return GOF(f6);
   1023    if (o >= GOF(f7)  && o+sz <= GOF(f7) +SZB(f7))  return GOF(f7);
   1024    if (o >= GOF(f8)  && o+sz <= GOF(f8) +SZB(f8))  return GOF(f8);
   1025    if (o >= GOF(f9)  && o+sz <= GOF(f9) +SZB(f9))  return GOF(f9);
   1026    if (o >= GOF(f10) && o+sz <= GOF(f10)+SZB(f10)) return GOF(f10);
   1027    if (o >= GOF(f11) && o+sz <= GOF(f11)+SZB(f11)) return GOF(f11);
   1028    if (o >= GOF(f12) && o+sz <= GOF(f12)+SZB(f12)) return GOF(f12);
   1029    if (o >= GOF(f13) && o+sz <= GOF(f13)+SZB(f13)) return GOF(f13);
   1030    if (o >= GOF(f14) && o+sz <= GOF(f14)+SZB(f14)) return GOF(f14);
   1031    if (o >= GOF(f15) && o+sz <= GOF(f15)+SZB(f15)) return GOF(f15);
   1032 
   1033    if (o >= GOF(f16) && o+sz <= GOF(f16)+SZB(f16)) return GOF(f16);
   1034    if (o >= GOF(f17)  && o+sz <= GOF(f17) +SZB(f17))  return GOF(f17);
   1035    if (o >= GOF(f18)  && o+sz <= GOF(f18) +SZB(f18))  return GOF(f18);
   1036    if (o >= GOF(f19)  && o+sz <= GOF(f19) +SZB(f19))  return GOF(f19);
   1037    if (o >= GOF(f20)  && o+sz <= GOF(f20) +SZB(f20))  return GOF(f20);
   1038    if (o >= GOF(f21)  && o+sz <= GOF(f21) +SZB(f21))  return GOF(f21);
   1039    if (o >= GOF(f22)  && o+sz <= GOF(f22) +SZB(f22))  return GOF(f22);
   1040    if (o >= GOF(f23)  && o+sz <= GOF(f23) +SZB(f23))  return GOF(f23);
   1041    if (o >= GOF(f24)  && o+sz <= GOF(f24) +SZB(f24))  return GOF(f24);
   1042    if (o >= GOF(f25)  && o+sz <= GOF(f25) +SZB(f25))  return GOF(f25);
   1043    if (o >= GOF(f26) && o+sz <= GOF(f26)+SZB(f26)) return GOF(f26);
   1044    if (o >= GOF(f27) && o+sz <= GOF(f27)+SZB(f27)) return GOF(f27);
   1045    if (o >= GOF(f28) && o+sz <= GOF(f28)+SZB(f28)) return GOF(f28);
   1046    if (o >= GOF(f29) && o+sz <= GOF(f29)+SZB(f29)) return GOF(f29);
   1047    if (o >= GOF(f30) && o+sz <= GOF(f30)+SZB(f30)) return GOF(f30);
   1048    if (o >= GOF(f31) && o+sz <= GOF(f31)+SZB(f31)) return GOF(f31);
   1049 
   1050    if ((o > GOF(NRADDR)) && (o <= GOF(NRADDR) +12 )) return -1; /*padding registers*/
   1051 
   1052    VG_(printf)("MC_(get_otrack_shadow_offset)(mips)(off=%d,sz=%d)\n",
   1053                offset,szB);
   1054    tl_assert(0);
   1055 #  undef GOF
   1056 #  undef SZB
   1057 
   1058 #  else
   1059 #    error "FIXME: not implemented for this architecture"
   1060 #  endif
   1061 }
   1062 
   1063 
   1064 /* Let 'arr' describe an indexed reference to a guest state section
   1065    (guest state array).
   1066 
   1067    This function returns the corresponding guest state type to be used
   1068    when indexing the corresponding array in the second shadow (origin
   1069    tracking) area.  If the array is not to be origin-tracked, return
   1070    Ity_INVALID.
   1071 
   1072    This function must agree with MC_(get_otrack_shadow_offset) above.
   1073    See comments at the start of MC_(get_otrack_shadow_offset).
   1074 */
   1075 IRType MC_(get_otrack_reg_array_equiv_int_type) ( IRRegArray* arr )
   1076 {
   1077    /* -------------------- ppc64 -------------------- */
   1078 #  if defined(VGA_ppc64)
   1079    /* The redir stack. */
   1080    if (arr->base == offsetof(VexGuestPPC64State,guest_REDIR_STACK[0])
   1081        && arr->elemTy == Ity_I64
   1082        && arr->nElems == VEX_GUEST_PPC64_REDIR_STACK_SIZE)
   1083       return Ity_I64;
   1084 
   1085    VG_(printf)("get_reg_array_equiv_int_type(ppc64): unhandled: ");
   1086    ppIRRegArray(arr);
   1087    VG_(printf)("\n");
   1088    tl_assert(0);
   1089 
   1090    /* -------------------- ppc32 -------------------- */
   1091 #  elif defined(VGA_ppc32)
   1092    /* The redir stack. */
   1093    if (arr->base == offsetof(VexGuestPPC32State,guest_REDIR_STACK[0])
   1094        && arr->elemTy == Ity_I32
   1095        && arr->nElems == VEX_GUEST_PPC32_REDIR_STACK_SIZE)
   1096       return Ity_I32;
   1097 
   1098    VG_(printf)("get_reg_array_equiv_int_type(ppc32): unhandled: ");
   1099    ppIRRegArray(arr);
   1100    VG_(printf)("\n");
   1101    tl_assert(0);
   1102 
   1103    /* -------------------- amd64 -------------------- */
   1104 #  elif defined(VGA_amd64)
   1105    /* Ignore the FP tag array - pointless to shadow, and in any case
   1106       the elements are too small */
   1107    if (arr->base == offsetof(VexGuestAMD64State,guest_FPTAG)
   1108        && arr->elemTy == Ity_I8 && arr->nElems == 8)
   1109       return Ity_INVALID;
   1110 
   1111    /* The FP register array */
   1112    if (arr->base == offsetof(VexGuestAMD64State,guest_FPREG[0])
   1113        && arr->elemTy == Ity_F64 && arr->nElems == 8)
   1114       return Ity_I64;
   1115 
   1116    VG_(printf)("get_reg_array_equiv_int_type(amd64): unhandled: ");
   1117    ppIRRegArray(arr);
   1118    VG_(printf)("\n");
   1119    tl_assert(0);
   1120 
   1121    /* --------------------- x86 --------------------- */
   1122 #  elif defined(VGA_x86)
   1123    /* Ignore the FP tag array - pointless to shadow, and in any case
   1124       the elements are too small */
   1125    if (arr->base == offsetof(VexGuestX86State,guest_FPTAG)
   1126        && arr->elemTy == Ity_I8 && arr->nElems == 8)
   1127       return Ity_INVALID;
   1128 
   1129    /* The FP register array */
   1130    if (arr->base == offsetof(VexGuestX86State,guest_FPREG[0])
   1131        && arr->elemTy == Ity_F64 && arr->nElems == 8)
   1132       return Ity_I64;
   1133 
   1134    VG_(printf)("get_reg_array_equiv_int_type(x86): unhandled: ");
   1135    ppIRRegArray(arr);
   1136    VG_(printf)("\n");
   1137    tl_assert(0);
   1138 
   1139    /* --------------------- arm --------------------- */
   1140 #  elif defined(VGA_arm)
   1141    VG_(printf)("get_reg_array_equiv_int_type(arm): unhandled: ");
   1142    ppIRRegArray(arr);
   1143    VG_(printf)("\n");
   1144    tl_assert(0);
   1145 
   1146    /* --------------------- s390x --------------------- */
   1147 #  elif defined(VGA_s390x)
   1148    /* Should never het here because s390x does not use Ist_PutI
   1149       and Iex_GetI. */
   1150    tl_assert(0);
   1151 
   1152 /* --------------------- mips32 --------------------- */
   1153 #  elif defined(VGA_mips32)
   1154    VG_(printf)("get_reg_array_equiv_int_type(mips32): unhandled: ");
   1155    ppIRRegArray(arr);
   1156    VG_(printf)("\n");
   1157    tl_assert(0);
   1158 
   1159 #  else
   1160 #    error "FIXME: not implemented for this architecture"
   1161 #  endif
   1162 }
   1163 
   1164 
   1165 /*--------------------------------------------------------------------*/
   1166 /*--- end                                             mc_machine.c ---*/
   1167 /*--------------------------------------------------------------------*/
   1168