]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/memcheck/mc_machine.c
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / memcheck / mc_machine.c
1
2 /*--------------------------------------------------------------------*/
3 /*--- Contains machine-specific (guest-state-layout-specific)      ---*/
4 /*--- support for origin tracking.                                 ---*/
5 /*---                                                 mc_machine.c ---*/
6 /*--------------------------------------------------------------------*/
7
8 /*
9    This file is part of MemCheck, a heavyweight Valgrind tool for
10    detecting memory errors.
11
12    Copyright (C) 2008-2010 OpenWorks Ltd
13       info@open-works.co.uk
14
15    This program is free software; you can redistribute it and/or
16    modify it under the terms of the GNU General Public License as
17    published by the Free Software Foundation; either version 2 of the
18    License, or (at your option) any later version.
19
20    This program is distributed in the hope that it will be useful, but
21    WITHOUT ANY WARRANTY; without even the implied warranty of
22    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23    General Public License for more details.
24
25    You should have received a copy of the GNU General Public License
26    along with this program; if not, write to the Free Software
27    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28    02111-1307, USA.
29
30    The GNU General Public License is contained in the file COPYING.
31
32    Neither the names of the U.S. Department of Energy nor the
33    University of California nor the names of its contributors may be
34    used to endorse or promote products derived from this software
35    without prior written permission.
36 */
37
38 #include "pub_tool_basics.h"
39 #include "pub_tool_hashtable.h"     // For mc_include.h
40 #include "pub_tool_libcassert.h"
41 #include "pub_tool_libcprint.h"
42 #include "pub_tool_tooliface.h"
43
44 #include "mc_include.h"
45
46 #undef MC_SIZEOF_GUEST_STATE
47
48 #if defined(VGA_x86)
49 # include "libvex_guest_x86.h"
50 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestX86State)
51 #endif
52
53 #if defined(VGA_amd64)
54 # include "libvex_guest_amd64.h"
55 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestAMD64State)
56 #endif
57
58 #if defined(VGA_ppc32)
59 # include "libvex_guest_ppc32.h"
60 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC32State)
61 #endif
62
63 #if defined(VGA_ppc64)
64 # include "libvex_guest_ppc64.h"
65 # define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC64State)
66 #endif
67
68 #if defined(VGA_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
78 static inline Bool host_is_big_endian ( void ) {
79    UInt x = 0x11223344;
80    return 0x1122 == *(UShort*)(&x);
81 }
82 static 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 */
120 static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ); /*fwds*/
121
122 Int 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
133 static 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 */
955 IRType 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 /*--------------------------------------------------------------------*/