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-2010 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_hashtable.h"     // For mc_include.h
     40 #include "pub_tool_libcassert.h"
     41 #include "pub_tool_libcprint.h"
     42 #include "pub_tool_tooliface.h"
     43 
     44 #include "mc_include.h"
     45 
     46 #undef MC_SIZEOF_GUEST_STATE
     47 
     48 #if defined(VGA_x86)
     49 # include "libvex_guest_x86.h"
     50 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestX86State)
     51 #endif
     52 
     53 #if defined(VGA_amd64)
     54 # include "libvex_guest_amd64.h"
     55 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestAMD64State)
     56 #endif
     57 
     58 #if defined(VGA_ppc32)
     59 # include "libvex_guest_ppc32.h"
     60 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC32State)
     61 #endif
     62 
     63 #if defined(VGA_ppc64)
     64 # include "libvex_guest_ppc64.h"
     65 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC64State)
     66 #endif
     67 
     68 #if defined(VGA_arm)
     69 # include "libvex_guest_arm.h"
     70 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestARMState)
     71 #endif
     72 
     73 static inline Bool host_is_big_endian ( void ) {
     74    UInt x = 0x11223344;
     75    return 0x1122 == *(UShort*)(&x);
     76 }
     77 static inline Bool host_is_little_endian ( void ) {
     78    UInt x = 0x11223344;
     79    return 0x3344 == *(UShort*)(&x);
     80 }
     81 
     82 
     83 /* Let (offset,szB) describe a reference to the guest state section
     84    [offset, offset+szB).
     85 
     86    This function returns the corresponding guest state reference to be
     87    used for the origin tag (which of course will be in the second
     88    shadow area), or -1 if this piece of guest state is not to be
     89    tracked.
     90 
     91    Since origin tags are 32-bits long, we expect any returned value
     92    (except -1) to be a multiple of 4, between 0 and
     93    sizeof(guest-state)-4 inclusive.
     94 
     95    This is inherently (guest-)architecture specific.  For x86 and
     96    amd64 we do some somewhat tricky things to give %AH .. %DH their
     97    own tags.  On ppc32/64 we do some marginally tricky things to give
     98    all 16 %CR components their own tags.
     99 
    100    This function only deals with references to the guest state whose
    101    offsets are known at translation time (that is, references arising
    102    from Put and Get).  References whose offset is not known until run
    103    time (that is, arise from PutI and GetI) are handled by
    104    MC_(get_otrack_reg_array_equiv_int_type) below.
    105 
    106    Note that since some guest state arrays (eg, the x86 FP reg stack)
    107    are accessed both as arrays (eg, x87 insns) and directly (eg, MMX
    108    insns), the two functions must be consistent for those sections of
    109    guest state -- that is, they must both say the area is shadowed, or
    110    both say it is not.
    111 
    112    This function is dependent on the host's endianness, hence we
    113    assert that the use case is supported.
    114 */
    115 static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ); /*fwds*/
    116 
    117 Int MC_(get_otrack_shadow_offset) ( Int offset, Int szB )
    118 {
    119    Int cand = get_otrack_shadow_offset_wrk( offset, szB );
    120    if (cand == -1)
    121       return cand;
    122    tl_assert(0 == (cand & 3));
    123    tl_assert(cand <= MC_SIZEOF_GUEST_STATE-4);
    124    return cand;
    125 }
    126 
    127 
    128 static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
    129 {
    130    /* -------------------- ppc64 -------------------- */
    131 
    132 #  if defined(VGA_ppc64)
    133 
    134 #  define GOF(_fieldname) \
    135       (offsetof(VexGuestPPC64State,guest_##_fieldname))
    136 #  define SZB(_fieldname) \
    137       (sizeof(((VexGuestPPC64State*)0)->guest_##_fieldname))
    138 
    139    Int  sz   = szB;
    140    Int  o    = offset;
    141    tl_assert(sz > 0);
    142    tl_assert(host_is_big_endian());
    143 
    144    if (sz == 8 || sz == 4) {
    145       /* The point of this is to achieve
    146          if ((o == GOF(GPRn) && sz == 8) || (o == 4+GOF(GPRn) && sz == 4))
    147             return GOF(GPRn);
    148          by testing ox instead of o, and setting ox back 4 bytes when sz == 4.
    149       */
    150       Int ox = sz == 8 ? o : (o - 4);
    151       if (ox == GOF(GPR0)) return ox;
    152       if (ox == GOF(GPR1)) return ox;
    153       if (ox == GOF(GPR2)) return ox;
    154       if (ox == GOF(GPR3)) return ox;
    155       if (ox == GOF(GPR4)) return ox;
    156       if (ox == GOF(GPR5)) return ox;
    157       if (ox == GOF(GPR6)) return ox;
    158       if (ox == GOF(GPR7)) return ox;
    159       if (ox == GOF(GPR8)) return ox;
    160       if (ox == GOF(GPR9)) return ox;
    161       if (ox == GOF(GPR10)) return ox;
    162       if (ox == GOF(GPR11)) return ox;
    163       if (ox == GOF(GPR12)) return ox;
    164       if (ox == GOF(GPR13)) return ox;
    165       if (ox == GOF(GPR14)) return ox;
    166       if (ox == GOF(GPR15)) return ox;
    167       if (ox == GOF(GPR16)) return ox;
    168       if (ox == GOF(GPR17)) return ox;
    169       if (ox == GOF(GPR18)) return ox;
    170       if (ox == GOF(GPR19)) return ox;
    171       if (ox == GOF(GPR20)) return ox;
    172       if (ox == GOF(GPR21)) return ox;
    173       if (ox == GOF(GPR22)) return ox;
    174       if (ox == GOF(GPR23)) return ox;
    175       if (ox == GOF(GPR24)) return ox;
    176       if (ox == GOF(GPR25)) return ox;
    177       if (ox == GOF(GPR26)) return ox;
    178       if (ox == GOF(GPR27)) return ox;
    179       if (ox == GOF(GPR28)) return ox;
    180       if (ox == GOF(GPR29)) return ox;
    181       if (ox == GOF(GPR30)) return ox;
    182       if (ox == GOF(GPR31)) return ox;
    183    }
    184 
    185    if (o == GOF(LR)  && sz == 8) return o;
    186    if (o == GOF(CTR) && sz == 8) return o;
    187 
    188    if (o == GOF(CIA)       && sz == 8) return -1;
    189    if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
    190    if (o == GOF(FPROUND)   && sz == 4) return -1;
    191    if (o == GOF(EMWARN)    && sz == 4) return -1;
    192    if (o == GOF(TISTART)   && sz == 8) return -1;
    193    if (o == GOF(TILEN)     && sz == 8) return -1;
    194    if (o == GOF(VSCR)      && sz == 4) return -1;
    195    if (o == GOF(VRSAVE)    && sz == 4) return -1;
    196    if (o == GOF(REDIR_SP)  && sz == 8) return -1;
    197 
    198    tl_assert(SZB(FPR0) == 8);
    199    if (o == GOF(FPR0) && sz == 8) return o;
    200    if (o == GOF(FPR1) && sz == 8) return o;
    201    if (o == GOF(FPR2) && sz == 8) return o;
    202    if (o == GOF(FPR3) && sz == 8) return o;
    203    if (o == GOF(FPR4) && sz == 8) return o;
    204    if (o == GOF(FPR5) && sz == 8) return o;
    205    if (o == GOF(FPR6) && sz == 8) return o;
    206    if (o == GOF(FPR7) && sz == 8) return o;
    207    if (o == GOF(FPR8) && sz == 8) return o;
    208    if (o == GOF(FPR9) && sz == 8) return o;
    209    if (o == GOF(FPR10) && sz == 8) return o;
    210    if (o == GOF(FPR11) && sz == 8) return o;
    211    if (o == GOF(FPR12) && sz == 8) return o;
    212    if (o == GOF(FPR13) && sz == 8) return o;
    213    if (o == GOF(FPR14) && sz == 8) return o;
    214    if (o == GOF(FPR15) && sz == 8) return o;
    215    if (o == GOF(FPR16) && sz == 8) return o;
    216    if (o == GOF(FPR17) && sz == 8) return o;
    217    if (o == GOF(FPR18) && sz == 8) return o;
    218    if (o == GOF(FPR19) && sz == 8) return o;
    219    if (o == GOF(FPR20) && sz == 8) return o;
    220    if (o == GOF(FPR21) && sz == 8) return o;
    221    if (o == GOF(FPR22) && sz == 8) return o;
    222    if (o == GOF(FPR23) && sz == 8) return o;
    223    if (o == GOF(FPR24) && sz == 8) return o;
    224    if (o == GOF(FPR25) && sz == 8) return o;
    225    if (o == GOF(FPR26) && sz == 8) return o;
    226    if (o == GOF(FPR27) && sz == 8) return o;
    227    if (o == GOF(FPR28) && sz == 8) return o;
    228    if (o == GOF(FPR29) && sz == 8) return o;
    229    if (o == GOF(FPR30) && sz == 8) return o;
    230    if (o == GOF(FPR31) && sz == 8) return o;
    231 
    232    /* For the various byte sized XER/CR pieces, use offset 8
    233       in VR0 .. VR31. */
    234    tl_assert(SZB(VR0) == 16);
    235    if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VR0);
    236    if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VR1);
    237    if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VR2);
    238    if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VR3);
    239 
    240    if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VR4);
    241    if (o == GOF(CR0_0)   && sz == 1) return 8 +GOF(VR5);
    242    if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VR6);
    243    if (o == GOF(CR1_0)   && sz == 1) return 8 +GOF(VR7);
    244    if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VR8);
    245    if (o == GOF(CR2_0)   && sz == 1) return 8 +GOF(VR9);
    246    if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VR10);
    247    if (o == GOF(CR3_0)   && sz == 1) return 8 +GOF(VR11);
    248    if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VR12);
    249    if (o == GOF(CR4_0)   && sz == 1) return 8 +GOF(VR13);
    250    if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VR14);
    251    if (o == GOF(CR5_0)   && sz == 1) return 8 +GOF(VR15);
    252    if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VR16);
    253    if (o == GOF(CR6_0)   && sz == 1) return 8 +GOF(VR17);
    254    if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VR18);
    255    if (o == GOF(CR7_0)   && sz == 1) return 8 +GOF(VR19);
    256 
    257    /* Vector registers .. use offset 0 in VR0 .. VR31. */
    258    if (o >= GOF(VR0)  && o+sz <= GOF(VR0) +SZB(VR0))  return 0+ GOF(VR0);
    259    if (o >= GOF(VR1)  && o+sz <= GOF(VR1) +SZB(VR1))  return 0+ GOF(VR1);
    260    if (o >= GOF(VR2)  && o+sz <= GOF(VR2) +SZB(VR2))  return 0+ GOF(VR2);
    261    if (o >= GOF(VR3)  && o+sz <= GOF(VR3) +SZB(VR3))  return 0+ GOF(VR3);
    262    if (o >= GOF(VR4)  && o+sz <= GOF(VR4) +SZB(VR4))  return 0+ GOF(VR4);
    263    if (o >= GOF(VR5)  && o+sz <= GOF(VR5) +SZB(VR5))  return 0+ GOF(VR5);
    264    if (o >= GOF(VR6)  && o+sz <= GOF(VR6) +SZB(VR6))  return 0+ GOF(VR6);
    265    if (o >= GOF(VR7)  && o+sz <= GOF(VR7) +SZB(VR7))  return 0+ GOF(VR7);
    266    if (o >= GOF(VR8)  && o+sz <= GOF(VR8) +SZB(VR8))  return 0+ GOF(VR8);
    267    if (o >= GOF(VR9)  && o+sz <= GOF(VR9) +SZB(VR9))  return 0+ GOF(VR9);
    268    if (o >= GOF(VR10) && o+sz <= GOF(VR10)+SZB(VR10)) return 0+ GOF(VR10);
    269    if (o >= GOF(VR11) && o+sz <= GOF(VR11)+SZB(VR11)) return 0+ GOF(VR11);
    270    if (o >= GOF(VR12) && o+sz <= GOF(VR12)+SZB(VR12)) return 0+ GOF(VR12);
    271    if (o >= GOF(VR13) && o+sz <= GOF(VR13)+SZB(VR13)) return 0+ GOF(VR13);
    272    if (o >= GOF(VR14) && o+sz <= GOF(VR14)+SZB(VR14)) return 0+ GOF(VR14);
    273    if (o >= GOF(VR15) && o+sz <= GOF(VR15)+SZB(VR15)) return 0+ GOF(VR15);
    274    if (o >= GOF(VR16) && o+sz <= GOF(VR16)+SZB(VR16)) return 0+ GOF(VR16);
    275    if (o >= GOF(VR17) && o+sz <= GOF(VR17)+SZB(VR17)) return 0+ GOF(VR17);
    276    if (o >= GOF(VR18) && o+sz <= GOF(VR18)+SZB(VR18)) return 0+ GOF(VR18);
    277    if (o >= GOF(VR19) && o+sz <= GOF(VR19)+SZB(VR19)) return 0+ GOF(VR19);
    278    if (o >= GOF(VR20) && o+sz <= GOF(VR20)+SZB(VR20)) return 0+ GOF(VR20);
    279    if (o >= GOF(VR21) && o+sz <= GOF(VR21)+SZB(VR21)) return 0+ GOF(VR21);
    280    if (o >= GOF(VR22) && o+sz <= GOF(VR22)+SZB(VR22)) return 0+ GOF(VR22);
    281    if (o >= GOF(VR23) && o+sz <= GOF(VR23)+SZB(VR23)) return 0+ GOF(VR23);
    282    if (o >= GOF(VR24) && o+sz <= GOF(VR24)+SZB(VR24)) return 0+ GOF(VR24);
    283    if (o >= GOF(VR25) && o+sz <= GOF(VR25)+SZB(VR25)) return 0+ GOF(VR25);
    284    if (o >= GOF(VR26) && o+sz <= GOF(VR26)+SZB(VR26)) return 0+ GOF(VR26);
    285    if (o >= GOF(VR27) && o+sz <= GOF(VR27)+SZB(VR27)) return 0+ GOF(VR27);
    286    if (o >= GOF(VR28) && o+sz <= GOF(VR28)+SZB(VR28)) return 0+ GOF(VR28);
    287    if (o >= GOF(VR29) && o+sz <= GOF(VR29)+SZB(VR29)) return 0+ GOF(VR29);
    288    if (o >= GOF(VR30) && o+sz <= GOF(VR30)+SZB(VR30)) return 0+ GOF(VR30);
    289    if (o >= GOF(VR31) && o+sz <= GOF(VR31)+SZB(VR31)) return 0+ GOF(VR31);
    290 
    291    VG_(printf)("MC_(get_otrack_shadow_offset)(ppc64)(off=%d,sz=%d)\n",
    292                offset,szB);
    293    tl_assert(0);
    294 #  undef GOF
    295 #  undef SZB
    296 
    297    /* -------------------- ppc32 -------------------- */
    298 
    299 #  elif defined(VGA_ppc32)
    300 
    301 #  define GOF(_fieldname) \
    302       (offsetof(VexGuestPPC32State,guest_##_fieldname))
    303 #  define SZB(_fieldname) \
    304       (sizeof(((VexGuestPPC32State*)0)->guest_##_fieldname))
    305    Int  o  = offset;
    306    Int  sz = szB;
    307    tl_assert(sz > 0);
    308    tl_assert(host_is_big_endian());
    309 
    310    if (o == GOF(GPR0) && sz == 4) return o;
    311    if (o == GOF(GPR1) && sz == 4) return o;
    312    if (o == GOF(GPR2) && sz == 4) return o;
    313    if (o == GOF(GPR3) && sz == 4) return o;
    314    if (o == GOF(GPR4) && sz == 4) return o;
    315    if (o == GOF(GPR5) && sz == 4) return o;
    316    if (o == GOF(GPR6) && sz == 4) return o;
    317    if (o == GOF(GPR7) && sz == 4) return o;
    318    if (o == GOF(GPR8) && sz == 4) return o;
    319    if (o == GOF(GPR9) && sz == 4) return o;
    320    if (o == GOF(GPR10) && sz == 4) return o;
    321    if (o == GOF(GPR11) && sz == 4) return o;
    322    if (o == GOF(GPR12) && sz == 4) return o;
    323    if (o == GOF(GPR13) && sz == 4) return o;
    324    if (o == GOF(GPR14) && sz == 4) return o;
    325    if (o == GOF(GPR15) && sz == 4) return o;
    326    if (o == GOF(GPR16) && sz == 4) return o;
    327    if (o == GOF(GPR17) && sz == 4) return o;
    328    if (o == GOF(GPR18) && sz == 4) return o;
    329    if (o == GOF(GPR19) && sz == 4) return o;
    330    if (o == GOF(GPR20) && sz == 4) return o;
    331    if (o == GOF(GPR21) && sz == 4) return o;
    332    if (o == GOF(GPR22) && sz == 4) return o;
    333    if (o == GOF(GPR23) && sz == 4) return o;
    334    if (o == GOF(GPR24) && sz == 4) return o;
    335    if (o == GOF(GPR25) && sz == 4) return o;
    336    if (o == GOF(GPR26) && sz == 4) return o;
    337    if (o == GOF(GPR27) && sz == 4) return o;
    338    if (o == GOF(GPR28) && sz == 4) return o;
    339    if (o == GOF(GPR29) && sz == 4) return o;
    340    if (o == GOF(GPR30) && sz == 4) return o;
    341    if (o == GOF(GPR31) && sz == 4) return o;
    342 
    343    if (o == GOF(LR)  && sz == 4) return o;
    344    if (o == GOF(CTR) && sz == 4) return o;
    345 
    346    if (o == GOF(CIA)       && sz == 4) return -1;
    347    if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
    348    if (o == GOF(FPROUND)   && sz == 4) return -1;
    349    if (o == GOF(VRSAVE)    && sz == 4) return -1;
    350    if (o == GOF(EMWARN)    && sz == 4) return -1;
    351    if (o == GOF(TISTART)   && sz == 4) return -1;
    352    if (o == GOF(TILEN)     && sz == 4) return -1;
    353    if (o == GOF(VSCR)      && sz == 4) return -1;
    354    if (o == GOF(REDIR_SP)  && sz == 4) return -1;
    355    if (o == GOF(SPRG3_RO)  && sz == 4) return -1;
    356 
    357    tl_assert(SZB(FPR0) == 8);
    358    if (o == GOF(FPR0) && sz == 8) return o;
    359    if (o == GOF(FPR1) && sz == 8) return o;
    360    if (o == GOF(FPR2) && sz == 8) return o;
    361    if (o == GOF(FPR3) && sz == 8) return o;
    362    if (o == GOF(FPR4) && sz == 8) return o;
    363    if (o == GOF(FPR5) && sz == 8) return o;
    364    if (o == GOF(FPR6) && sz == 8) return o;
    365    if (o == GOF(FPR7) && sz == 8) return o;
    366    if (o == GOF(FPR8) && sz == 8) return o;
    367    if (o == GOF(FPR9) && sz == 8) return o;
    368    if (o == GOF(FPR10) && sz == 8) return o;
    369    if (o == GOF(FPR11) && sz == 8) return o;
    370    if (o == GOF(FPR12) && sz == 8) return o;
    371    if (o == GOF(FPR13) && sz == 8) return o;
    372    if (o == GOF(FPR14) && sz == 8) return o;
    373    if (o == GOF(FPR15) && sz == 8) return o;
    374    if (o == GOF(FPR16) && sz == 8) return o;
    375    if (o == GOF(FPR17) && sz == 8) return o;
    376    if (o == GOF(FPR18) && sz == 8) return o;
    377    if (o == GOF(FPR19) && sz == 8) return o;
    378    if (o == GOF(FPR20) && sz == 8) return o;
    379    if (o == GOF(FPR21) && sz == 8) return o;
    380    if (o == GOF(FPR22) && sz == 8) return o;
    381    if (o == GOF(FPR23) && sz == 8) return o;
    382    if (o == GOF(FPR24) && sz == 8) return o;
    383    if (o == GOF(FPR25) && sz == 8) return o;
    384    if (o == GOF(FPR26) && sz == 8) return o;
    385    if (o == GOF(FPR27) && sz == 8) return o;
    386    if (o == GOF(FPR28) && sz == 8) return o;
    387    if (o == GOF(FPR29) && sz == 8) return o;
    388    if (o == GOF(FPR30) && sz == 8) return o;
    389    if (o == GOF(FPR31) && sz == 8) return o;
    390 
    391    /* For the various byte sized XER/CR pieces, use offset 8
    392       in VR0 .. VR31. */
    393    tl_assert(SZB(VR0) == 16);
    394    if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VR0);
    395    if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VR1);
    396    if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VR2);
    397    if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VR3);
    398 
    399    if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VR4);
    400    if (o == GOF(CR0_0)   && sz == 1) return 8 +GOF(VR5);
    401    if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VR6);
    402    if (o == GOF(CR1_0)   && sz == 1) return 8 +GOF(VR7);
    403    if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VR8);
    404    if (o == GOF(CR2_0)   && sz == 1) return 8 +GOF(VR9);
    405    if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VR10);
    406    if (o == GOF(CR3_0)   && sz == 1) return 8 +GOF(VR11);
    407    if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VR12);
    408    if (o == GOF(CR4_0)   && sz == 1) return 8 +GOF(VR13);
    409    if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VR14);
    410    if (o == GOF(CR5_0)   && sz == 1) return 8 +GOF(VR15);
    411    if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VR16);
    412    if (o == GOF(CR6_0)   && sz == 1) return 8 +GOF(VR17);
    413    if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VR18);
    414    if (o == GOF(CR7_0)   && sz == 1) return 8 +GOF(VR19);
    415 
    416    /* Vector registers .. use offset 0 in VR0 .. VR31. */
    417    if (o >= GOF(VR0)  && o+sz <= GOF(VR0) +SZB(VR0))  return 0+ GOF(VR0);
    418    if (o >= GOF(VR1)  && o+sz <= GOF(VR1) +SZB(VR1))  return 0+ GOF(VR1);
    419    if (o >= GOF(VR2)  && o+sz <= GOF(VR2) +SZB(VR2))  return 0+ GOF(VR2);
    420    if (o >= GOF(VR3)  && o+sz <= GOF(VR3) +SZB(VR3))  return 0+ GOF(VR3);
    421    if (o >= GOF(VR4)  && o+sz <= GOF(VR4) +SZB(VR4))  return 0+ GOF(VR4);
    422    if (o >= GOF(VR5)  && o+sz <= GOF(VR5) +SZB(VR5))  return 0+ GOF(VR5);
    423    if (o >= GOF(VR6)  && o+sz <= GOF(VR6) +SZB(VR6))  return 0+ GOF(VR6);
    424    if (o >= GOF(VR7)  && o+sz <= GOF(VR7) +SZB(VR7))  return 0+ GOF(VR7);
    425    if (o >= GOF(VR8)  && o+sz <= GOF(VR8) +SZB(VR8))  return 0+ GOF(VR8);
    426    if (o >= GOF(VR9)  && o+sz <= GOF(VR9) +SZB(VR9))  return 0+ GOF(VR9);
    427    if (o >= GOF(VR10) && o+sz <= GOF(VR10)+SZB(VR10)) return 0+ GOF(VR10);
    428    if (o >= GOF(VR11) && o+sz <= GOF(VR11)+SZB(VR11)) return 0+ GOF(VR11);
    429    if (o >= GOF(VR12) && o+sz <= GOF(VR12)+SZB(VR12)) return 0+ GOF(VR12);
    430    if (o >= GOF(VR13) && o+sz <= GOF(VR13)+SZB(VR13)) return 0+ GOF(VR13);
    431    if (o >= GOF(VR14) && o+sz <= GOF(VR14)+SZB(VR14)) return 0+ GOF(VR14);
    432    if (o >= GOF(VR15) && o+sz <= GOF(VR15)+SZB(VR15)) return 0+ GOF(VR15);
    433    if (o >= GOF(VR16) && o+sz <= GOF(VR16)+SZB(VR16)) return 0+ GOF(VR16);
    434    if (o >= GOF(VR17) && o+sz <= GOF(VR17)+SZB(VR17)) return 0+ GOF(VR17);
    435    if (o >= GOF(VR18) && o+sz <= GOF(VR18)+SZB(VR18)) return 0+ GOF(VR18);
    436    if (o >= GOF(VR19) && o+sz <= GOF(VR19)+SZB(VR19)) return 0+ GOF(VR19);
    437    if (o >= GOF(VR20) && o+sz <= GOF(VR20)+SZB(VR20)) return 0+ GOF(VR20);
    438    if (o >= GOF(VR21) && o+sz <= GOF(VR21)+SZB(VR21)) return 0+ GOF(VR21);
    439    if (o >= GOF(VR22) && o+sz <= GOF(VR22)+SZB(VR22)) return 0+ GOF(VR22);
    440    if (o >= GOF(VR23) && o+sz <= GOF(VR23)+SZB(VR23)) return 0+ GOF(VR23);
    441    if (o >= GOF(VR24) && o+sz <= GOF(VR24)+SZB(VR24)) return 0+ GOF(VR24);
    442    if (o >= GOF(VR25) && o+sz <= GOF(VR25)+SZB(VR25)) return 0+ GOF(VR25);
    443    if (o >= GOF(VR26) && o+sz <= GOF(VR26)+SZB(VR26)) return 0+ GOF(VR26);
    444    if (o >= GOF(VR27) && o+sz <= GOF(VR27)+SZB(VR27)) return 0+ GOF(VR27);
    445    if (o >= GOF(VR28) && o+sz <= GOF(VR28)+SZB(VR28)) return 0+ GOF(VR28);
    446    if (o >= GOF(VR29) && o+sz <= GOF(VR29)+SZB(VR29)) return 0+ GOF(VR29);
    447    if (o >= GOF(VR30) && o+sz <= GOF(VR30)+SZB(VR30)) return 0+ GOF(VR30);
    448    if (o >= GOF(VR31) && o+sz <= GOF(VR31)+SZB(VR31)) return 0+ GOF(VR31);
    449 
    450    VG_(printf)("MC_(get_otrack_shadow_offset)(ppc32)(off=%d,sz=%d)\n",
    451                offset,szB);
    452    tl_assert(0);
    453 #  undef GOF
    454 #  undef SZB
    455 
    456    /* -------------------- amd64 -------------------- */
    457 
    458 #  elif defined(VGA_amd64)
    459 
    460 #  define GOF(_fieldname) \
    461       (offsetof(VexGuestAMD64State,guest_##_fieldname))
    462 #  define SZB(_fieldname) \
    463       (sizeof(((VexGuestAMD64State*)0)->guest_##_fieldname))
    464    Int  o      = offset;
    465    Int  sz     = szB;
    466    Bool is1248 = sz == 8 || sz == 4 || sz == 2 || sz == 1;
    467    tl_assert(sz > 0);
    468    tl_assert(host_is_little_endian());
    469 
    470    if (o == GOF(RAX) && is1248) return o;
    471    if (o == GOF(RCX) && is1248) return o;
    472    if (o == GOF(RDX) && is1248) return o;
    473    if (o == GOF(RBX) && is1248) return o;
    474    if (o == GOF(RSP) && is1248) return o;
    475    if (o == GOF(RBP) && is1248) return o;
    476    if (o == GOF(RSI) && is1248) return o;
    477    if (o == GOF(RDI) && is1248) return o;
    478    if (o == GOF(R8)  && is1248) return o;
    479    if (o == GOF(R9)  && is1248) return o;
    480    if (o == GOF(R10) && is1248) return o;
    481    if (o == GOF(R11) && is1248) return o;
    482    if (o == GOF(R12) && is1248) return o;
    483    if (o == GOF(R13) && is1248) return o;
    484    if (o == GOF(R14) && is1248) return o;
    485    if (o == GOF(R15) && is1248) return o;
    486 
    487    if (o == GOF(CC_DEP1) && sz == 8) return o;
    488    if (o == GOF(CC_DEP2) && sz == 8) return o;
    489 
    490    if (o == GOF(CC_OP)   && sz == 8) return -1; /* slot used for %AH */
    491    if (o == GOF(CC_NDEP) && sz == 8) return -1; /* slot used for %BH */
    492    if (o == GOF(DFLAG)   && sz == 8) return -1; /* slot used for %CH */
    493    if (o == GOF(RIP)     && sz == 8) return -1; /* slot unused */
    494    if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
    495    if (o == GOF(IDFLAG)  && sz == 8) return -1; /* slot used for %DH */
    496    if (o == GOF(ACFLAG)  && sz == 8) return -1; /* slot unused */
    497    if (o == GOF(FS_ZERO) && sz == 8) return -1; /* slot unused */
    498    if (o == GOF(GS_0x60) && sz == 8) return -1; /* slot unused */
    499    if (o == GOF(TISTART) && sz == 8) return -1; /* slot unused */
    500    if (o == GOF(TILEN)   && sz == 8) return -1; /* slot unused */
    501 
    502    /* Treat %AH, %BH, %CH, %DH as independent registers.  To do this
    503       requires finding 4 unused 32-bit slots in the second-shadow
    504       guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG, since
    505       none of those are tracked. */
    506    tl_assert(SZB(CC_OP)   == 8);
    507    tl_assert(SZB(CC_NDEP) == 8);
    508    tl_assert(SZB(IDFLAG)  == 8);
    509    tl_assert(SZB(DFLAG)   == 8);
    510 
    511    if (o == 1+ GOF(RAX) && szB == 1) return GOF(CC_OP);
    512    if (o == 1+ GOF(RBX) && szB == 1) return GOF(CC_NDEP);
    513    if (o == 1+ GOF(RCX) && szB == 1) return GOF(DFLAG);
    514    if (o == 1+ GOF(RDX) && szB == 1) return GOF(IDFLAG);
    515 
    516    /* skip XMM and FP admin stuff */
    517    if (o == GOF(SSEROUND) && szB == 8) return -1;
    518    if (o == GOF(FTOP)     && szB == 4) return -1;
    519    if (o == GOF(FPROUND)  && szB == 8) return -1;
    520    if (o == GOF(EMWARN)   && szB == 4) return -1;
    521    if (o == GOF(FC3210)   && szB == 8) return -1;
    522 
    523    /* XMM registers */
    524    if (o >= GOF(XMM0)  && o+sz <= GOF(XMM0) +SZB(XMM0))  return GOF(XMM0);
    525    if (o >= GOF(XMM1)  && o+sz <= GOF(XMM1) +SZB(XMM1))  return GOF(XMM1);
    526    if (o >= GOF(XMM2)  && o+sz <= GOF(XMM2) +SZB(XMM2))  return GOF(XMM2);
    527    if (o >= GOF(XMM3)  && o+sz <= GOF(XMM3) +SZB(XMM3))  return GOF(XMM3);
    528    if (o >= GOF(XMM4)  && o+sz <= GOF(XMM4) +SZB(XMM4))  return GOF(XMM4);
    529    if (o >= GOF(XMM5)  && o+sz <= GOF(XMM5) +SZB(XMM5))  return GOF(XMM5);
    530    if (o >= GOF(XMM6)  && o+sz <= GOF(XMM6) +SZB(XMM6))  return GOF(XMM6);
    531    if (o >= GOF(XMM7)  && o+sz <= GOF(XMM7) +SZB(XMM7))  return GOF(XMM7);
    532    if (o >= GOF(XMM8)  && o+sz <= GOF(XMM8) +SZB(XMM8))  return GOF(XMM8);
    533    if (o >= GOF(XMM9)  && o+sz <= GOF(XMM9) +SZB(XMM9))  return GOF(XMM9);
    534    if (o >= GOF(XMM10) && o+sz <= GOF(XMM10)+SZB(XMM10)) return GOF(XMM10);
    535    if (o >= GOF(XMM11) && o+sz <= GOF(XMM11)+SZB(XMM11)) return GOF(XMM11);
    536    if (o >= GOF(XMM12) && o+sz <= GOF(XMM12)+SZB(XMM12)) return GOF(XMM12);
    537    if (o >= GOF(XMM13) && o+sz <= GOF(XMM13)+SZB(XMM13)) return GOF(XMM13);
    538    if (o >= GOF(XMM14) && o+sz <= GOF(XMM14)+SZB(XMM14)) return GOF(XMM14);
    539    if (o >= GOF(XMM15) && o+sz <= GOF(XMM15)+SZB(XMM15)) return GOF(XMM15);
    540    if (o >= GOF(XMM16) && o+sz <= GOF(XMM16)+SZB(XMM16)) return GOF(XMM16);
    541 
    542    /* MMX accesses to FP regs.  Need to allow for 32-bit references
    543       due to dirty helpers for frstor etc, which reference the entire
    544       64-byte block in one go. */
    545    if (o >= GOF(FPREG[0])
    546        && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
    547    if (o >= GOF(FPREG[1])
    548        && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
    549    if (o >= GOF(FPREG[2])
    550        && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
    551    if (o >= GOF(FPREG[3])
    552        && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
    553    if (o >= GOF(FPREG[4])
    554        && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
    555    if (o >= GOF(FPREG[5])
    556        && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
    557    if (o >= GOF(FPREG[6])
    558        && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
    559    if (o >= GOF(FPREG[7])
    560        && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
    561 
    562    /* Map high halves of %RAX,%RCX,%RDX,%RBX to the whole register.
    563       This is needed because the general handling of dirty helper
    564       calls is done in 4 byte chunks.  Hence we will see these.
    565       Currently we only expect to see artefacts from CPUID. */
    566    if (o == 4+ GOF(RAX) && sz == 4) return GOF(RAX);
    567    if (o == 4+ GOF(RCX) && sz == 4) return GOF(RCX);
    568    if (o == 4+ GOF(RDX) && sz == 4) return GOF(RDX);
    569    if (o == 4+ GOF(RBX) && sz == 4) return GOF(RBX);
    570 
    571    VG_(printf)("MC_(get_otrack_shadow_offset)(amd64)(off=%d,sz=%d)\n",
    572                offset,szB);
    573    tl_assert(0);
    574 #  undef GOF
    575 #  undef SZB
    576 
    577    /* --------------------- x86 --------------------- */
    578 
    579 #  elif defined(VGA_x86)
    580 
    581 #  define GOF(_fieldname) \
    582       (offsetof(VexGuestX86State,guest_##_fieldname))
    583 #  define SZB(_fieldname) \
    584       (sizeof(((VexGuestX86State*)0)->guest_##_fieldname))
    585 
    586    Int  o     = offset;
    587    Int  sz    = szB;
    588    Bool is124 = sz == 4 || sz == 2 || sz == 1;
    589    tl_assert(sz > 0);
    590    tl_assert(host_is_little_endian());
    591 
    592    if (o == GOF(EAX) && is124) return o;
    593    if (o == GOF(ECX) && is124) return o;
    594    if (o == GOF(EDX) && is124) return o;
    595    if (o == GOF(EBX) && is124) return o;
    596    if (o == GOF(ESP) && is124) return o;
    597    if (o == GOF(EBP) && is124) return o;
    598    if (o == GOF(ESI) && is124) return o;
    599    if (o == GOF(EDI) && is124) return o;
    600 
    601    if (o == GOF(CC_DEP1) && sz == 4) return o;
    602    if (o == GOF(CC_DEP2) && sz == 4) return o;
    603 
    604    if (o == GOF(CC_OP)   && sz == 4) return -1; /* slot used for %AH */
    605    if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot used for %BH */
    606    if (o == GOF(DFLAG)   && sz == 4) return -1; /* slot used for %CH */
    607    if (o == GOF(EIP)     && sz == 4) return -1; /* slot unused */
    608    if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
    609    if (o == GOF(IDFLAG)  && sz == 4) return -1; /* slot used for %DH */
    610    if (o == GOF(ACFLAG)  && sz == 4) return -1; /* slot unused */
    611    if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
    612    if (o == GOF(TILEN)   && sz == 4) return -1; /* slot unused */
    613    if (o == GOF(NRADDR)  && sz == 4) return -1; /* slot unused */
    614 
    615    /* Treat %AH, %BH, %CH, %DH as independent registers.  To do this
    616       requires finding 4 unused 32-bit slots in the second-shadow
    617       guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG since none
    618       of those are tracked. */
    619    tl_assert(SZB(CC_OP)   == 4);
    620    tl_assert(SZB(CC_NDEP) == 4);
    621    tl_assert(SZB(DFLAG)   == 4);
    622    tl_assert(SZB(IDFLAG)  == 4);
    623    if (o == 1+ GOF(EAX) && szB == 1) return GOF(CC_OP);
    624    if (o == 1+ GOF(EBX) && szB == 1) return GOF(CC_NDEP);
    625    if (o == 1+ GOF(ECX) && szB == 1) return GOF(DFLAG);
    626    if (o == 1+ GOF(EDX) && szB == 1) return GOF(IDFLAG);
    627 
    628    /* skip XMM and FP admin stuff */
    629    if (o == GOF(SSEROUND) && szB == 4) return -1;
    630    if (o == GOF(FTOP)     && szB == 4) return -1;
    631    if (o == GOF(FPROUND)  && szB == 4) return -1;
    632    if (o == GOF(EMWARN)   && szB == 4) return -1;
    633    if (o == GOF(FC3210)   && szB == 4) return -1;
    634 
    635    /* XMM registers */
    636    if (o >= GOF(XMM0)  && o+sz <= GOF(XMM0)+SZB(XMM0)) return GOF(XMM0);
    637    if (o >= GOF(XMM1)  && o+sz <= GOF(XMM1)+SZB(XMM1)) return GOF(XMM1);
    638    if (o >= GOF(XMM2)  && o+sz <= GOF(XMM2)+SZB(XMM2)) return GOF(XMM2);
    639    if (o >= GOF(XMM3)  && o+sz <= GOF(XMM3)+SZB(XMM3)) return GOF(XMM3);
    640    if (o >= GOF(XMM4)  && o+sz <= GOF(XMM4)+SZB(XMM4)) return GOF(XMM4);
    641    if (o >= GOF(XMM5)  && o+sz <= GOF(XMM5)+SZB(XMM5)) return GOF(XMM5);
    642    if (o >= GOF(XMM6)  && o+sz <= GOF(XMM6)+SZB(XMM6)) return GOF(XMM6);
    643    if (o >= GOF(XMM7)  && o+sz <= GOF(XMM7)+SZB(XMM7)) return GOF(XMM7);
    644 
    645    /* MMX accesses to FP regs.  Need to allow for 32-bit references
    646       due to dirty helpers for frstor etc, which reference the entire
    647       64-byte block in one go. */
    648    if (o >= GOF(FPREG[0])
    649        && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
    650    if (o >= GOF(FPREG[1])
    651        && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
    652    if (o >= GOF(FPREG[2])
    653        && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
    654    if (o >= GOF(FPREG[3])
    655        && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
    656    if (o >= GOF(FPREG[4])
    657        && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
    658    if (o >= GOF(FPREG[5])
    659        && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
    660    if (o >= GOF(FPREG[6])
    661        && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
    662    if (o >= GOF(FPREG[7])
    663        && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
    664 
    665    /* skip %GS and other segment related stuff.  We could shadow
    666       guest_LDT and guest_GDT, although it seems pointless.
    667       guest_CS .. guest_SS are too small to shadow directly and it
    668       also seems pointless to shadow them indirectly (that is, in
    669       the style of %AH .. %DH). */
    670    if (o == GOF(CS) && sz == 2) return -1;
    671    if (o == GOF(DS) && sz == 2) return -1;
    672    if (o == GOF(ES) && sz == 2) return -1;
    673    if (o == GOF(FS) && sz == 2) return -1;
    674    if (o == GOF(GS) && sz == 2) return -1;
    675    if (o == GOF(SS) && sz == 2) return -1;
    676    if (o == GOF(LDT) && sz == 4) return -1;
    677    if (o == GOF(GDT) && sz == 4) return -1;
    678 
    679    VG_(printf)("MC_(get_otrack_shadow_offset)(x86)(off=%d,sz=%d)\n",
    680                offset,szB);
    681    tl_assert(0);
    682 #  undef GOF
    683 #  undef SZB
    684 
    685    /* --------------------- arm --------------------- */
    686 
    687 #  elif defined(VGA_arm)
    688 
    689 #  define GOF(_fieldname) \
    690       (offsetof(VexGuestARMState,guest_##_fieldname))
    691 #  define SZB(_fieldname) \
    692       (sizeof(((VexGuestARMState*)0)->guest_##_fieldname))
    693 
    694    Int  o     = offset;
    695    Int  sz    = szB;
    696    tl_assert(sz > 0);
    697    tl_assert(host_is_little_endian());
    698 
    699    if (o == GOF(R0)  && sz == 4) return o;
    700    if (o == GOF(R1)  && sz == 4) return o;
    701    if (o == GOF(R2)  && sz == 4) return o;
    702    if (o == GOF(R3)  && sz == 4) return o;
    703    if (o == GOF(R4)  && sz == 4) return o;
    704    if (o == GOF(R5)  && sz == 4) return o;
    705    if (o == GOF(R6)  && sz == 4) return o;
    706    if (o == GOF(R7)  && sz == 4) return o;
    707    if (o == GOF(R8)  && sz == 4) return o;
    708    if (o == GOF(R9)  && sz == 4) return o;
    709    if (o == GOF(R10) && sz == 4) return o;
    710    if (o == GOF(R11) && sz == 4) return o;
    711    if (o == GOF(R12) && sz == 4) return o;
    712    if (o == GOF(R13) && sz == 4) return o;
    713    if (o == GOF(R14) && sz == 4) return o;
    714 
    715    /* EAZG: These may be completely wrong. */
    716    if (o == GOF(R15T)  && sz == 4) return -1; /* slot unused */
    717    if (o == GOF(CC_OP) && sz == 4) return -1; /* slot unused */
    718 
    719    if (o == GOF(CC_DEP1) && sz == 4) return o;
    720    if (o == GOF(CC_DEP2) && sz == 4) return o;
    721 
    722    if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot unused */
    723 
    724    if (o == GOF(QFLAG32) && sz == 4) return o;
    725 
    726    if (o == GOF(GEFLAG0) && sz == 4) return o;
    727    if (o == GOF(GEFLAG1) && sz == 4) return o;
    728    if (o == GOF(GEFLAG2) && sz == 4) return o;
    729    if (o == GOF(GEFLAG3) && sz == 4) return o;
    730 
    731    //if (o == GOF(SYSCALLNO)     && sz == 4) return -1; /* slot unused */
    732    //if (o == GOF(CC)     && sz == 4) return -1; /* slot unused */
    733    //if (o == GOF(EMWARN)     && sz == 4) return -1; /* slot unused */
    734    //if (o == GOF(TISTART)     && sz == 4) return -1; /* slot unused */
    735    //if (o == GOF(NRADDR)     && sz == 4) return -1; /* slot unused */
    736 
    737    if (o == GOF(FPSCR)    && sz == 4) return -1;
    738    if (o == GOF(TPIDRURO) && sz == 4) return -1;
    739    if (o == GOF(ITSTATE)  && sz == 4) return -1;
    740 
    741    /* Accesses to F or D registers */
    742    if (sz == 4 || sz == 8) {
    743       if (o >= GOF(D0)  && o+sz <= GOF(D0) +SZB(D0))  return GOF(D0);
    744       if (o >= GOF(D1)  && o+sz <= GOF(D1) +SZB(D1))  return GOF(D1);
    745       if (o >= GOF(D2)  && o+sz <= GOF(D2) +SZB(D2))  return GOF(D2);
    746       if (o >= GOF(D3)  && o+sz <= GOF(D3) +SZB(D3))  return GOF(D3);
    747       if (o >= GOF(D4)  && o+sz <= GOF(D4) +SZB(D4))  return GOF(D4);
    748       if (o >= GOF(D5)  && o+sz <= GOF(D5) +SZB(D5))  return GOF(D5);
    749       if (o >= GOF(D6)  && o+sz <= GOF(D6) +SZB(D6))  return GOF(D6);
    750       if (o >= GOF(D7)  && o+sz <= GOF(D7) +SZB(D7))  return GOF(D7);
    751       if (o >= GOF(D8)  && o+sz <= GOF(D8) +SZB(D8))  return GOF(D8);
    752       if (o >= GOF(D9)  && o+sz <= GOF(D9) +SZB(D9))  return GOF(D9);
    753       if (o >= GOF(D10) && o+sz <= GOF(D10)+SZB(D10)) return GOF(D10);
    754       if (o >= GOF(D11) && o+sz <= GOF(D11)+SZB(D11)) return GOF(D11);
    755       if (o >= GOF(D12) && o+sz <= GOF(D12)+SZB(D12)) return GOF(D12);
    756       if (o >= GOF(D13) && o+sz <= GOF(D13)+SZB(D13)) return GOF(D13);
    757       if (o >= GOF(D14) && o+sz <= GOF(D14)+SZB(D14)) return GOF(D14);
    758       if (o >= GOF(D15) && o+sz <= GOF(D15)+SZB(D15)) return GOF(D15);
    759       if (o >= GOF(D16) && o+sz <= GOF(D16)+SZB(D16)) return GOF(D16);
    760       if (o >= GOF(D17) && o+sz <= GOF(D17)+SZB(D17)) return GOF(D17);
    761       if (o >= GOF(D18) && o+sz <= GOF(D18)+SZB(D18)) return GOF(D18);
    762       if (o >= GOF(D19) && o+sz <= GOF(D19)+SZB(D19)) return GOF(D19);
    763       if (o >= GOF(D20) && o+sz <= GOF(D20)+SZB(D20)) return GOF(D20);
    764       if (o >= GOF(D21) && o+sz <= GOF(D21)+SZB(D21)) return GOF(D21);
    765       if (o >= GOF(D22) && o+sz <= GOF(D22)+SZB(D22)) return GOF(D22);
    766       if (o >= GOF(D23) && o+sz <= GOF(D23)+SZB(D23)) return GOF(D23);
    767       if (o >= GOF(D24) && o+sz <= GOF(D24)+SZB(D24)) return GOF(D24);
    768       if (o >= GOF(D25) && o+sz <= GOF(D25)+SZB(D25)) return GOF(D25);
    769       if (o >= GOF(D26) && o+sz <= GOF(D26)+SZB(D26)) return GOF(D26);
    770       if (o >= GOF(D27) && o+sz <= GOF(D27)+SZB(D27)) return GOF(D27);
    771       if (o >= GOF(D28) && o+sz <= GOF(D28)+SZB(D28)) return GOF(D28);
    772       if (o >= GOF(D29) && o+sz <= GOF(D29)+SZB(D29)) return GOF(D29);
    773       if (o >= GOF(D30) && o+sz <= GOF(D30)+SZB(D30)) return GOF(D30);
    774       if (o >= GOF(D31) && o+sz <= GOF(D31)+SZB(D31)) return GOF(D31);
    775    }
    776 
    777    /* Accesses to Q registers */
    778    if (sz == 16) {
    779       if (o >= GOF(D0)  && o+sz <= GOF(D0) +2*SZB(D0))  return GOF(D0);  // Q0
    780       if (o >= GOF(D2)  && o+sz <= GOF(D2) +2*SZB(D2))  return GOF(D2);  // Q1
    781       if (o >= GOF(D4)  && o+sz <= GOF(D4) +2*SZB(D4))  return GOF(D4);  // Q2
    782       if (o >= GOF(D6)  && o+sz <= GOF(D6) +2*SZB(D6))  return GOF(D6);  // Q3
    783       if (o >= GOF(D8)  && o+sz <= GOF(D8) +2*SZB(D8))  return GOF(D8);  // Q4
    784       if (o >= GOF(D10) && o+sz <= GOF(D10)+2*SZB(D10)) return GOF(D10); // Q5
    785       if (o >= GOF(D12) && o+sz <= GOF(D12)+2*SZB(D12)) return GOF(D12); // Q6
    786       if (o >= GOF(D14) && o+sz <= GOF(D14)+2*SZB(D14)) return GOF(D14); // Q7
    787       if (o >= GOF(D16) && o+sz <= GOF(D16)+2*SZB(D16)) return GOF(D16); // Q8
    788       if (o >= GOF(D18) && o+sz <= GOF(D18)+2*SZB(D18)) return GOF(D18); // Q9
    789       if (o >= GOF(D20) && o+sz <= GOF(D20)+2*SZB(D20)) return GOF(D20); // Q10
    790       if (o >= GOF(D22) && o+sz <= GOF(D22)+2*SZB(D22)) return GOF(D22); // Q11
    791       if (o >= GOF(D24) && o+sz <= GOF(D24)+2*SZB(D24)) return GOF(D24); // Q12
    792       if (o >= GOF(D26) && o+sz <= GOF(D26)+2*SZB(D26)) return GOF(D26); // Q13
    793       if (o >= GOF(D28) && o+sz <= GOF(D28)+2*SZB(D28)) return GOF(D28); // Q14
    794       if (o >= GOF(D30) && o+sz <= GOF(D30)+2*SZB(D30)) return GOF(D30); // Q15
    795    }
    796 
    797    VG_(printf)("MC_(get_otrack_shadow_offset)(arm)(off=%d,sz=%d)\n",
    798                offset,szB);
    799    tl_assert(0);
    800 #  undef GOF
    801 #  undef SZB
    802 
    803 #  else
    804 #    error "FIXME: not implemented for this architecture"
    805 #  endif
    806 }
    807 
    808 
    809 /* Let 'arr' describe an indexed reference to a guest state section
    810    (guest state array).
    811 
    812    This function returns the corresponding guest state type to be used
    813    when indexing the corresponding array in the second shadow (origin
    814    tracking) area.  If the array is not to be origin-tracked, return
    815    Ity_INVALID.
    816 
    817    This function must agree with MC_(get_otrack_shadow_offset) above.
    818    See comments at the start of MC_(get_otrack_shadow_offset).
    819 */
    820 IRType MC_(get_otrack_reg_array_equiv_int_type) ( IRRegArray* arr )
    821 {
    822    /* -------------------- ppc64 -------------------- */
    823 #  if defined(VGA_ppc64)
    824    /* The redir stack. */
    825    if (arr->base == offsetof(VexGuestPPC64State,guest_REDIR_STACK[0])
    826        && arr->elemTy == Ity_I64
    827        && arr->nElems == VEX_GUEST_PPC64_REDIR_STACK_SIZE)
    828       return Ity_I64;
    829 
    830    VG_(printf)("get_reg_array_equiv_int_type(ppc64): unhandled: ");
    831    ppIRRegArray(arr);
    832    VG_(printf)("\n");
    833    tl_assert(0);
    834 
    835    /* -------------------- ppc32 -------------------- */
    836 #  elif defined(VGA_ppc32)
    837    /* The redir stack. */
    838    if (arr->base == offsetof(VexGuestPPC32State,guest_REDIR_STACK[0])
    839        && arr->elemTy == Ity_I32
    840        && arr->nElems == VEX_GUEST_PPC32_REDIR_STACK_SIZE)
    841       return Ity_I32;
    842 
    843    VG_(printf)("get_reg_array_equiv_int_type(ppc32): unhandled: ");
    844    ppIRRegArray(arr);
    845    VG_(printf)("\n");
    846    tl_assert(0);
    847 
    848    /* -------------------- amd64 -------------------- */
    849 #  elif defined(VGA_amd64)
    850    /* Ignore the FP tag array - pointless to shadow, and in any case
    851       the elements are too small */
    852    if (arr->base == offsetof(VexGuestAMD64State,guest_FPTAG)
    853        && arr->elemTy == Ity_I8 && arr->nElems == 8)
    854       return Ity_INVALID;
    855 
    856    /* The FP register array */
    857    if (arr->base == offsetof(VexGuestAMD64State,guest_FPREG[0])
    858        && arr->elemTy == Ity_F64 && arr->nElems == 8)
    859       return Ity_I64;
    860 
    861    VG_(printf)("get_reg_array_equiv_int_type(amd64): unhandled: ");
    862    ppIRRegArray(arr);
    863    VG_(printf)("\n");
    864    tl_assert(0);
    865 
    866    /* --------------------- x86 --------------------- */
    867 #  elif defined(VGA_x86)
    868    /* Ignore the FP tag array - pointless to shadow, and in any case
    869       the elements are too small */
    870    if (arr->base == offsetof(VexGuestX86State,guest_FPTAG)
    871        && arr->elemTy == Ity_I8 && arr->nElems == 8)
    872       return Ity_INVALID;
    873 
    874    /* The FP register array */
    875    if (arr->base == offsetof(VexGuestX86State,guest_FPREG[0])
    876        && arr->elemTy == Ity_F64 && arr->nElems == 8)
    877       return Ity_I64;
    878 
    879    VG_(printf)("get_reg_array_equiv_int_type(x86): unhandled: ");
    880    ppIRRegArray(arr);
    881    VG_(printf)("\n");
    882    tl_assert(0);
    883 
    884    /* --------------------- arm --------------------- */
    885 #  elif defined(VGA_arm)
    886 
    887    VG_(printf)("get_reg_array_equiv_int_type(arm): unhandled: ");
    888    ppIRRegArray(arr);
    889    VG_(printf)("\n");
    890    tl_assert(0);
    891 
    892 #  else
    893 #    error "FIXME: not implemented for this architecture"
    894 #  endif
    895 }
    896 
    897 
    898 /*--------------------------------------------------------------------*/
    899 /*--- end                                             mc_machine.c ---*/
    900 /*--------------------------------------------------------------------*/
    901