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