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