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