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