• 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-2010 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_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 
host_is_big_endian(void)73 static inline Bool host_is_big_endian ( void ) {
74    UInt x = 0x11223344;
75    return 0x1122 == *(UShort*)(&x);
76 }
host_is_little_endian(void)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 
MC_(get_otrack_shadow_offset)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 
get_otrack_shadow_offset_wrk(Int offset,Int szB)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 */
MC_(get_otrack_reg_array_equiv_int_type)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