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