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