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