blob: 030c845482c6b4d86819987ba54c9ccdd5850bdb [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
sewardj9eecbbb2010-05-03 21:37:12 +000012 Copyright (C) 2008-2010 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"
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
sewardj59570ff2010-01-01 11:59:33 +000068#if defined(VGA_arm)
69# include "libvex_guest_arm.h"
70# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestARMState)
71#endif
72
sewardj7cf4e6b2008-05-01 20:24:26 +000073static inline Bool host_is_big_endian ( void ) {
74 UInt x = 0x11223344;
75 return 0x1122 == *(UShort*)(&x);
76}
77static inline Bool host_is_little_endian ( void ) {
78 UInt x = 0x11223344;
79 return 0x3344 == *(UShort*)(&x);
80}
81
82
83/* Let (offset,szB) describe a reference to the guest state section
84 [offset, offset+szB).
85
86 This function returns the corresponding guest state reference to be
87 used for the origin tag (which of course will be in the second
88 shadow area), or -1 if this piece of guest state is not to be
89 tracked.
90
91 Since origin tags are 32-bits long, we expect any returned value
92 (except -1) to be a multiple of 4, between 0 and
93 sizeof(guest-state)-4 inclusive.
94
95 This is inherently (guest-)architecture specific. For x86 and
96 amd64 we do some somewhat tricky things to give %AH .. %DH their
97 own tags. On ppc32/64 we do some marginally tricky things to give
98 all 16 %CR components their own tags.
99
100 This function only deals with references to the guest state whose
101 offsets are known at translation time (that is, references arising
102 from Put and Get). References whose offset is not known until run
103 time (that is, arise from PutI and GetI) are handled by
104 MC_(get_otrack_reg_array_equiv_int_type) below.
105
106 Note that since some guest state arrays (eg, the x86 FP reg stack)
107 are accessed both as arrays (eg, x87 insns) and directly (eg, MMX
108 insns), the two functions must be consistent for those sections of
109 guest state -- that is, they must both say the area is shadowed, or
110 both say it is not.
111
112 This function is dependent on the host's endianness, hence we
113 assert that the use case is supported.
114*/
115static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ); /*fwds*/
116
117Int MC_(get_otrack_shadow_offset) ( Int offset, Int szB )
118{
119 Int cand = get_otrack_shadow_offset_wrk( offset, szB );
120 if (cand == -1)
121 return cand;
122 tl_assert(0 == (cand & 3));
123 tl_assert(cand <= MC_SIZEOF_GUEST_STATE-4);
124 return cand;
125}
126
127
128static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
129{
130 /* -------------------- ppc64 -------------------- */
131
132# if defined(VGA_ppc64)
133
134# define GOF(_fieldname) \
135 (offsetof(VexGuestPPC64State,guest_##_fieldname))
136# define SZB(_fieldname) \
137 (sizeof(((VexGuestPPC64State*)0)->guest_##_fieldname))
138
139 Int sz = szB;
140 Int o = offset;
141 tl_assert(sz > 0);
142 tl_assert(host_is_big_endian());
143
144 if (sz == 8 || sz == 4) {
145 /* The point of this is to achieve
146 if ((o == GOF(GPRn) && sz == 8) || (o == 4+GOF(GPRn) && sz == 4))
147 return GOF(GPRn);
148 by testing ox instead of o, and setting ox back 4 bytes when sz == 4.
149 */
sewardj85857ab2008-05-06 15:40:32 +0000150 Int ox = sz == 8 ? o : (o - 4);
sewardj7cf4e6b2008-05-01 20:24:26 +0000151 if (ox == GOF(GPR0)) return ox;
152 if (ox == GOF(GPR1)) return ox;
153 if (ox == GOF(GPR2)) return ox;
154 if (ox == GOF(GPR3)) return ox;
155 if (ox == GOF(GPR4)) return ox;
156 if (ox == GOF(GPR5)) return ox;
157 if (ox == GOF(GPR6)) return ox;
158 if (ox == GOF(GPR7)) return ox;
159 if (ox == GOF(GPR8)) return ox;
160 if (ox == GOF(GPR9)) return ox;
161 if (ox == GOF(GPR10)) return ox;
162 if (ox == GOF(GPR11)) return ox;
163 if (ox == GOF(GPR12)) return ox;
164 if (ox == GOF(GPR13)) return ox;
165 if (ox == GOF(GPR14)) return ox;
166 if (ox == GOF(GPR15)) return ox;
167 if (ox == GOF(GPR16)) return ox;
168 if (ox == GOF(GPR17)) return ox;
169 if (ox == GOF(GPR18)) return ox;
170 if (ox == GOF(GPR19)) return ox;
171 if (ox == GOF(GPR20)) return ox;
172 if (ox == GOF(GPR21)) return ox;
173 if (ox == GOF(GPR22)) return ox;
174 if (ox == GOF(GPR23)) return ox;
175 if (ox == GOF(GPR24)) return ox;
176 if (ox == GOF(GPR25)) return ox;
177 if (ox == GOF(GPR26)) return ox;
178 if (ox == GOF(GPR27)) return ox;
179 if (ox == GOF(GPR28)) return ox;
180 if (ox == GOF(GPR29)) return ox;
181 if (ox == GOF(GPR30)) return ox;
182 if (ox == GOF(GPR31)) return ox;
183 }
184
185 if (o == GOF(LR) && sz == 8) return o;
186 if (o == GOF(CTR) && sz == 8) return o;
187
188 if (o == GOF(CIA) && sz == 8) return -1;
sewardj71633b12009-03-30 02:27:29 +0000189 if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000190 if (o == GOF(FPROUND) && sz == 4) return -1;
191 if (o == GOF(EMWARN) && sz == 4) return -1;
192 if (o == GOF(TISTART) && sz == 8) return -1;
193 if (o == GOF(TILEN) && sz == 8) return -1;
194 if (o == GOF(VSCR) && sz == 4) return -1;
195 if (o == GOF(VRSAVE) && sz == 4) return -1;
196 if (o == GOF(REDIR_SP) && sz == 8) return -1;
197
198 tl_assert(SZB(FPR0) == 8);
199 if (o == GOF(FPR0) && sz == 8) return o;
200 if (o == GOF(FPR1) && sz == 8) return o;
201 if (o == GOF(FPR2) && sz == 8) return o;
202 if (o == GOF(FPR3) && sz == 8) return o;
203 if (o == GOF(FPR4) && sz == 8) return o;
204 if (o == GOF(FPR5) && sz == 8) return o;
205 if (o == GOF(FPR6) && sz == 8) return o;
206 if (o == GOF(FPR7) && sz == 8) return o;
207 if (o == GOF(FPR8) && sz == 8) return o;
208 if (o == GOF(FPR9) && sz == 8) return o;
209 if (o == GOF(FPR10) && sz == 8) return o;
210 if (o == GOF(FPR11) && sz == 8) return o;
211 if (o == GOF(FPR12) && sz == 8) return o;
212 if (o == GOF(FPR13) && sz == 8) return o;
213 if (o == GOF(FPR14) && sz == 8) return o;
214 if (o == GOF(FPR15) && sz == 8) return o;
215 if (o == GOF(FPR16) && sz == 8) return o;
216 if (o == GOF(FPR17) && sz == 8) return o;
217 if (o == GOF(FPR18) && sz == 8) return o;
218 if (o == GOF(FPR19) && sz == 8) return o;
219 if (o == GOF(FPR20) && sz == 8) return o;
220 if (o == GOF(FPR21) && sz == 8) return o;
221 if (o == GOF(FPR22) && sz == 8) return o;
222 if (o == GOF(FPR23) && sz == 8) return o;
223 if (o == GOF(FPR24) && sz == 8) return o;
224 if (o == GOF(FPR25) && sz == 8) return o;
225 if (o == GOF(FPR26) && sz == 8) return o;
226 if (o == GOF(FPR27) && sz == 8) return o;
227 if (o == GOF(FPR28) && sz == 8) return o;
228 if (o == GOF(FPR29) && sz == 8) return o;
229 if (o == GOF(FPR30) && sz == 8) return o;
230 if (o == GOF(FPR31) && sz == 8) return o;
231
232 /* For the various byte sized XER/CR pieces, use offset 8
233 in VR0 .. VR31. */
234 tl_assert(SZB(VR0) == 16);
235 if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VR0);
236 if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VR1);
237 if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VR2);
238 if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VR3);
239
240 if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VR4);
241 if (o == GOF(CR0_0) && sz == 1) return 8 +GOF(VR5);
242 if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VR6);
243 if (o == GOF(CR1_0) && sz == 1) return 8 +GOF(VR7);
244 if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VR8);
245 if (o == GOF(CR2_0) && sz == 1) return 8 +GOF(VR9);
246 if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VR10);
247 if (o == GOF(CR3_0) && sz == 1) return 8 +GOF(VR11);
248 if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VR12);
249 if (o == GOF(CR4_0) && sz == 1) return 8 +GOF(VR13);
250 if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VR14);
251 if (o == GOF(CR5_0) && sz == 1) return 8 +GOF(VR15);
252 if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VR16);
253 if (o == GOF(CR6_0) && sz == 1) return 8 +GOF(VR17);
254 if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VR18);
255 if (o == GOF(CR7_0) && sz == 1) return 8 +GOF(VR19);
256
257 /* Vector registers .. use offset 0 in VR0 .. VR31. */
258 if (o >= GOF(VR0) && o+sz <= GOF(VR0) +SZB(VR0)) return 0+ GOF(VR0);
259 if (o >= GOF(VR1) && o+sz <= GOF(VR1) +SZB(VR1)) return 0+ GOF(VR1);
260 if (o >= GOF(VR2) && o+sz <= GOF(VR2) +SZB(VR2)) return 0+ GOF(VR2);
261 if (o >= GOF(VR3) && o+sz <= GOF(VR3) +SZB(VR3)) return 0+ GOF(VR3);
262 if (o >= GOF(VR4) && o+sz <= GOF(VR4) +SZB(VR4)) return 0+ GOF(VR4);
263 if (o >= GOF(VR5) && o+sz <= GOF(VR5) +SZB(VR5)) return 0+ GOF(VR5);
264 if (o >= GOF(VR6) && o+sz <= GOF(VR6) +SZB(VR6)) return 0+ GOF(VR6);
265 if (o >= GOF(VR7) && o+sz <= GOF(VR7) +SZB(VR7)) return 0+ GOF(VR7);
266 if (o >= GOF(VR8) && o+sz <= GOF(VR8) +SZB(VR8)) return 0+ GOF(VR8);
267 if (o >= GOF(VR9) && o+sz <= GOF(VR9) +SZB(VR9)) return 0+ GOF(VR9);
268 if (o >= GOF(VR10) && o+sz <= GOF(VR10)+SZB(VR10)) return 0+ GOF(VR10);
269 if (o >= GOF(VR11) && o+sz <= GOF(VR11)+SZB(VR11)) return 0+ GOF(VR11);
270 if (o >= GOF(VR12) && o+sz <= GOF(VR12)+SZB(VR12)) return 0+ GOF(VR12);
271 if (o >= GOF(VR13) && o+sz <= GOF(VR13)+SZB(VR13)) return 0+ GOF(VR13);
272 if (o >= GOF(VR14) && o+sz <= GOF(VR14)+SZB(VR14)) return 0+ GOF(VR14);
273 if (o >= GOF(VR15) && o+sz <= GOF(VR15)+SZB(VR15)) return 0+ GOF(VR15);
274 if (o >= GOF(VR16) && o+sz <= GOF(VR16)+SZB(VR16)) return 0+ GOF(VR16);
275 if (o >= GOF(VR17) && o+sz <= GOF(VR17)+SZB(VR17)) return 0+ GOF(VR17);
276 if (o >= GOF(VR18) && o+sz <= GOF(VR18)+SZB(VR18)) return 0+ GOF(VR18);
277 if (o >= GOF(VR19) && o+sz <= GOF(VR19)+SZB(VR19)) return 0+ GOF(VR19);
278 if (o >= GOF(VR20) && o+sz <= GOF(VR20)+SZB(VR20)) return 0+ GOF(VR20);
279 if (o >= GOF(VR21) && o+sz <= GOF(VR21)+SZB(VR21)) return 0+ GOF(VR21);
280 if (o >= GOF(VR22) && o+sz <= GOF(VR22)+SZB(VR22)) return 0+ GOF(VR22);
281 if (o >= GOF(VR23) && o+sz <= GOF(VR23)+SZB(VR23)) return 0+ GOF(VR23);
282 if (o >= GOF(VR24) && o+sz <= GOF(VR24)+SZB(VR24)) return 0+ GOF(VR24);
283 if (o >= GOF(VR25) && o+sz <= GOF(VR25)+SZB(VR25)) return 0+ GOF(VR25);
284 if (o >= GOF(VR26) && o+sz <= GOF(VR26)+SZB(VR26)) return 0+ GOF(VR26);
285 if (o >= GOF(VR27) && o+sz <= GOF(VR27)+SZB(VR27)) return 0+ GOF(VR27);
286 if (o >= GOF(VR28) && o+sz <= GOF(VR28)+SZB(VR28)) return 0+ GOF(VR28);
287 if (o >= GOF(VR29) && o+sz <= GOF(VR29)+SZB(VR29)) return 0+ GOF(VR29);
288 if (o >= GOF(VR30) && o+sz <= GOF(VR30)+SZB(VR30)) return 0+ GOF(VR30);
289 if (o >= GOF(VR31) && o+sz <= GOF(VR31)+SZB(VR31)) return 0+ GOF(VR31);
290
291 VG_(printf)("MC_(get_otrack_shadow_offset)(ppc64)(off=%d,sz=%d)\n",
292 offset,szB);
293 tl_assert(0);
294# undef GOF
295# undef SZB
296
297 /* -------------------- ppc32 -------------------- */
298
299# elif defined(VGA_ppc32)
300
301# define GOF(_fieldname) \
302 (offsetof(VexGuestPPC32State,guest_##_fieldname))
303# define SZB(_fieldname) \
304 (sizeof(((VexGuestPPC32State*)0)->guest_##_fieldname))
305 Int o = offset;
306 Int sz = szB;
307 tl_assert(sz > 0);
308 tl_assert(host_is_big_endian());
309
310 if (o == GOF(GPR0) && sz == 4) return o;
311 if (o == GOF(GPR1) && sz == 4) return o;
312 if (o == GOF(GPR2) && sz == 4) return o;
313 if (o == GOF(GPR3) && sz == 4) return o;
314 if (o == GOF(GPR4) && sz == 4) return o;
315 if (o == GOF(GPR5) && sz == 4) return o;
316 if (o == GOF(GPR6) && sz == 4) return o;
317 if (o == GOF(GPR7) && sz == 4) return o;
318 if (o == GOF(GPR8) && sz == 4) return o;
319 if (o == GOF(GPR9) && sz == 4) return o;
320 if (o == GOF(GPR10) && sz == 4) return o;
321 if (o == GOF(GPR11) && sz == 4) return o;
322 if (o == GOF(GPR12) && sz == 4) return o;
323 if (o == GOF(GPR13) && sz == 4) return o;
324 if (o == GOF(GPR14) && sz == 4) return o;
325 if (o == GOF(GPR15) && sz == 4) return o;
326 if (o == GOF(GPR16) && sz == 4) return o;
327 if (o == GOF(GPR17) && sz == 4) return o;
328 if (o == GOF(GPR18) && sz == 4) return o;
329 if (o == GOF(GPR19) && sz == 4) return o;
330 if (o == GOF(GPR20) && sz == 4) return o;
331 if (o == GOF(GPR21) && sz == 4) return o;
332 if (o == GOF(GPR22) && sz == 4) return o;
333 if (o == GOF(GPR23) && sz == 4) return o;
334 if (o == GOF(GPR24) && sz == 4) return o;
335 if (o == GOF(GPR25) && sz == 4) return o;
336 if (o == GOF(GPR26) && sz == 4) return o;
337 if (o == GOF(GPR27) && sz == 4) return o;
338 if (o == GOF(GPR28) && sz == 4) return o;
339 if (o == GOF(GPR29) && sz == 4) return o;
340 if (o == GOF(GPR30) && sz == 4) return o;
341 if (o == GOF(GPR31) && sz == 4) return o;
342
343 if (o == GOF(LR) && sz == 4) return o;
344 if (o == GOF(CTR) && sz == 4) return o;
345
346 if (o == GOF(CIA) && sz == 4) return -1;
sewardj71633b12009-03-30 02:27:29 +0000347 if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000348 if (o == GOF(FPROUND) && sz == 4) return -1;
sewardj3b507352009-02-14 15:28:46 +0000349 if (o == GOF(VRSAVE) && sz == 4) return -1;
sewardj7cf4e6b2008-05-01 20:24:26 +0000350 if (o == GOF(EMWARN) && sz == 4) return -1;
351 if (o == GOF(TISTART) && sz == 4) return -1;
352 if (o == GOF(TILEN) && sz == 4) return -1;
353 if (o == GOF(VSCR) && sz == 4) return -1;
354 if (o == GOF(REDIR_SP) && sz == 4) return -1;
355 if (o == GOF(SPRG3_RO) && sz == 4) return -1;
356
357 tl_assert(SZB(FPR0) == 8);
358 if (o == GOF(FPR0) && sz == 8) return o;
359 if (o == GOF(FPR1) && sz == 8) return o;
360 if (o == GOF(FPR2) && sz == 8) return o;
361 if (o == GOF(FPR3) && sz == 8) return o;
362 if (o == GOF(FPR4) && sz == 8) return o;
363 if (o == GOF(FPR5) && sz == 8) return o;
364 if (o == GOF(FPR6) && sz == 8) return o;
365 if (o == GOF(FPR7) && sz == 8) return o;
366 if (o == GOF(FPR8) && sz == 8) return o;
367 if (o == GOF(FPR9) && sz == 8) return o;
368 if (o == GOF(FPR10) && sz == 8) return o;
369 if (o == GOF(FPR11) && sz == 8) return o;
370 if (o == GOF(FPR12) && sz == 8) return o;
371 if (o == GOF(FPR13) && sz == 8) return o;
372 if (o == GOF(FPR14) && sz == 8) return o;
373 if (o == GOF(FPR15) && sz == 8) return o;
374 if (o == GOF(FPR16) && sz == 8) return o;
375 if (o == GOF(FPR17) && sz == 8) return o;
376 if (o == GOF(FPR18) && sz == 8) return o;
377 if (o == GOF(FPR19) && sz == 8) return o;
378 if (o == GOF(FPR20) && sz == 8) return o;
379 if (o == GOF(FPR21) && sz == 8) return o;
380 if (o == GOF(FPR22) && sz == 8) return o;
381 if (o == GOF(FPR23) && sz == 8) return o;
382 if (o == GOF(FPR24) && sz == 8) return o;
383 if (o == GOF(FPR25) && sz == 8) return o;
384 if (o == GOF(FPR26) && sz == 8) return o;
385 if (o == GOF(FPR27) && sz == 8) return o;
386 if (o == GOF(FPR28) && sz == 8) return o;
387 if (o == GOF(FPR29) && sz == 8) return o;
388 if (o == GOF(FPR30) && sz == 8) return o;
389 if (o == GOF(FPR31) && sz == 8) return o;
390
391 /* For the various byte sized XER/CR pieces, use offset 8
392 in VR0 .. VR31. */
393 tl_assert(SZB(VR0) == 16);
394 if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VR0);
395 if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VR1);
396 if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VR2);
397 if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VR3);
398
399 if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VR4);
400 if (o == GOF(CR0_0) && sz == 1) return 8 +GOF(VR5);
401 if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VR6);
402 if (o == GOF(CR1_0) && sz == 1) return 8 +GOF(VR7);
403 if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VR8);
404 if (o == GOF(CR2_0) && sz == 1) return 8 +GOF(VR9);
405 if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VR10);
406 if (o == GOF(CR3_0) && sz == 1) return 8 +GOF(VR11);
407 if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VR12);
408 if (o == GOF(CR4_0) && sz == 1) return 8 +GOF(VR13);
409 if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VR14);
410 if (o == GOF(CR5_0) && sz == 1) return 8 +GOF(VR15);
411 if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VR16);
412 if (o == GOF(CR6_0) && sz == 1) return 8 +GOF(VR17);
413 if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VR18);
414 if (o == GOF(CR7_0) && sz == 1) return 8 +GOF(VR19);
415
416 /* Vector registers .. use offset 0 in VR0 .. VR31. */
417 if (o >= GOF(VR0) && o+sz <= GOF(VR0) +SZB(VR0)) return 0+ GOF(VR0);
418 if (o >= GOF(VR1) && o+sz <= GOF(VR1) +SZB(VR1)) return 0+ GOF(VR1);
419 if (o >= GOF(VR2) && o+sz <= GOF(VR2) +SZB(VR2)) return 0+ GOF(VR2);
420 if (o >= GOF(VR3) && o+sz <= GOF(VR3) +SZB(VR3)) return 0+ GOF(VR3);
421 if (o >= GOF(VR4) && o+sz <= GOF(VR4) +SZB(VR4)) return 0+ GOF(VR4);
422 if (o >= GOF(VR5) && o+sz <= GOF(VR5) +SZB(VR5)) return 0+ GOF(VR5);
423 if (o >= GOF(VR6) && o+sz <= GOF(VR6) +SZB(VR6)) return 0+ GOF(VR6);
424 if (o >= GOF(VR7) && o+sz <= GOF(VR7) +SZB(VR7)) return 0+ GOF(VR7);
425 if (o >= GOF(VR8) && o+sz <= GOF(VR8) +SZB(VR8)) return 0+ GOF(VR8);
426 if (o >= GOF(VR9) && o+sz <= GOF(VR9) +SZB(VR9)) return 0+ GOF(VR9);
427 if (o >= GOF(VR10) && o+sz <= GOF(VR10)+SZB(VR10)) return 0+ GOF(VR10);
428 if (o >= GOF(VR11) && o+sz <= GOF(VR11)+SZB(VR11)) return 0+ GOF(VR11);
429 if (o >= GOF(VR12) && o+sz <= GOF(VR12)+SZB(VR12)) return 0+ GOF(VR12);
430 if (o >= GOF(VR13) && o+sz <= GOF(VR13)+SZB(VR13)) return 0+ GOF(VR13);
431 if (o >= GOF(VR14) && o+sz <= GOF(VR14)+SZB(VR14)) return 0+ GOF(VR14);
432 if (o >= GOF(VR15) && o+sz <= GOF(VR15)+SZB(VR15)) return 0+ GOF(VR15);
433 if (o >= GOF(VR16) && o+sz <= GOF(VR16)+SZB(VR16)) return 0+ GOF(VR16);
434 if (o >= GOF(VR17) && o+sz <= GOF(VR17)+SZB(VR17)) return 0+ GOF(VR17);
435 if (o >= GOF(VR18) && o+sz <= GOF(VR18)+SZB(VR18)) return 0+ GOF(VR18);
436 if (o >= GOF(VR19) && o+sz <= GOF(VR19)+SZB(VR19)) return 0+ GOF(VR19);
437 if (o >= GOF(VR20) && o+sz <= GOF(VR20)+SZB(VR20)) return 0+ GOF(VR20);
438 if (o >= GOF(VR21) && o+sz <= GOF(VR21)+SZB(VR21)) return 0+ GOF(VR21);
439 if (o >= GOF(VR22) && o+sz <= GOF(VR22)+SZB(VR22)) return 0+ GOF(VR22);
440 if (o >= GOF(VR23) && o+sz <= GOF(VR23)+SZB(VR23)) return 0+ GOF(VR23);
441 if (o >= GOF(VR24) && o+sz <= GOF(VR24)+SZB(VR24)) return 0+ GOF(VR24);
442 if (o >= GOF(VR25) && o+sz <= GOF(VR25)+SZB(VR25)) return 0+ GOF(VR25);
443 if (o >= GOF(VR26) && o+sz <= GOF(VR26)+SZB(VR26)) return 0+ GOF(VR26);
444 if (o >= GOF(VR27) && o+sz <= GOF(VR27)+SZB(VR27)) return 0+ GOF(VR27);
445 if (o >= GOF(VR28) && o+sz <= GOF(VR28)+SZB(VR28)) return 0+ GOF(VR28);
446 if (o >= GOF(VR29) && o+sz <= GOF(VR29)+SZB(VR29)) return 0+ GOF(VR29);
447 if (o >= GOF(VR30) && o+sz <= GOF(VR30)+SZB(VR30)) return 0+ GOF(VR30);
448 if (o >= GOF(VR31) && o+sz <= GOF(VR31)+SZB(VR31)) return 0+ GOF(VR31);
449
450 VG_(printf)("MC_(get_otrack_shadow_offset)(ppc32)(off=%d,sz=%d)\n",
451 offset,szB);
452 tl_assert(0);
453# undef GOF
454# undef SZB
455
456 /* -------------------- amd64 -------------------- */
457
458# elif defined(VGA_amd64)
459
460# define GOF(_fieldname) \
461 (offsetof(VexGuestAMD64State,guest_##_fieldname))
462# define SZB(_fieldname) \
463 (sizeof(((VexGuestAMD64State*)0)->guest_##_fieldname))
464 Int o = offset;
465 Int sz = szB;
466 Bool is1248 = sz == 8 || sz == 4 || sz == 2 || sz == 1;
467 tl_assert(sz > 0);
468 tl_assert(host_is_little_endian());
469
470 if (o == GOF(RAX) && is1248) return o;
471 if (o == GOF(RCX) && is1248) return o;
472 if (o == GOF(RDX) && is1248) return o;
473 if (o == GOF(RBX) && is1248) return o;
474 if (o == GOF(RSP) && is1248) return o;
475 if (o == GOF(RBP) && is1248) return o;
476 if (o == GOF(RSI) && is1248) return o;
477 if (o == GOF(RDI) && is1248) return o;
478 if (o == GOF(R8) && is1248) return o;
479 if (o == GOF(R9) && is1248) return o;
480 if (o == GOF(R10) && is1248) return o;
481 if (o == GOF(R11) && is1248) return o;
482 if (o == GOF(R12) && is1248) return o;
483 if (o == GOF(R13) && is1248) return o;
484 if (o == GOF(R14) && is1248) return o;
485 if (o == GOF(R15) && is1248) return o;
486
487 if (o == GOF(CC_DEP1) && sz == 8) return o;
488 if (o == GOF(CC_DEP2) && sz == 8) return o;
489
490 if (o == GOF(CC_OP) && sz == 8) return -1; /* slot used for %AH */
491 if (o == GOF(CC_NDEP) && sz == 8) return -1; /* slot used for %BH */
492 if (o == GOF(DFLAG) && sz == 8) return -1; /* slot used for %CH */
493 if (o == GOF(RIP) && sz == 8) return -1; /* slot unused */
sewardj71633b12009-03-30 02:27:29 +0000494 if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000495 if (o == GOF(IDFLAG) && sz == 8) return -1; /* slot used for %DH */
sewardj65864932010-09-28 16:00:11 +0000496 if (o == GOF(ACFLAG) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000497 if (o == GOF(FS_ZERO) && sz == 8) return -1; /* slot unused */
njnf76d27a2009-05-28 01:53:07 +0000498 if (o == GOF(GS_0x60) && sz == 8) return -1; /* slot unused */
sewardj105e69c2008-05-09 23:26:19 +0000499 if (o == GOF(TISTART) && sz == 8) return -1; /* slot unused */
500 if (o == GOF(TILEN) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000501
502 /* Treat %AH, %BH, %CH, %DH as independent registers. To do this
503 requires finding 4 unused 32-bit slots in the second-shadow
504 guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG, since
505 none of those are tracked. */
506 tl_assert(SZB(CC_OP) == 8);
507 tl_assert(SZB(CC_NDEP) == 8);
508 tl_assert(SZB(IDFLAG) == 8);
509 tl_assert(SZB(DFLAG) == 8);
510
511 if (o == 1+ GOF(RAX) && szB == 1) return GOF(CC_OP);
512 if (o == 1+ GOF(RBX) && szB == 1) return GOF(CC_NDEP);
513 if (o == 1+ GOF(RCX) && szB == 1) return GOF(DFLAG);
514 if (o == 1+ GOF(RDX) && szB == 1) return GOF(IDFLAG);
515
516 /* skip XMM and FP admin stuff */
517 if (o == GOF(SSEROUND) && szB == 8) return -1;
518 if (o == GOF(FTOP) && szB == 4) return -1;
519 if (o == GOF(FPROUND) && szB == 8) return -1;
520 if (o == GOF(EMWARN) && szB == 4) return -1;
sewardj89ea7ab2008-05-27 16:08:24 +0000521 if (o == GOF(FC3210) && szB == 8) return -1;
sewardj7cf4e6b2008-05-01 20:24:26 +0000522
523 /* XMM registers */
524 if (o >= GOF(XMM0) && o+sz <= GOF(XMM0) +SZB(XMM0)) return GOF(XMM0);
525 if (o >= GOF(XMM1) && o+sz <= GOF(XMM1) +SZB(XMM1)) return GOF(XMM1);
526 if (o >= GOF(XMM2) && o+sz <= GOF(XMM2) +SZB(XMM2)) return GOF(XMM2);
527 if (o >= GOF(XMM3) && o+sz <= GOF(XMM3) +SZB(XMM3)) return GOF(XMM3);
528 if (o >= GOF(XMM4) && o+sz <= GOF(XMM4) +SZB(XMM4)) return GOF(XMM4);
529 if (o >= GOF(XMM5) && o+sz <= GOF(XMM5) +SZB(XMM5)) return GOF(XMM5);
530 if (o >= GOF(XMM6) && o+sz <= GOF(XMM6) +SZB(XMM6)) return GOF(XMM6);
531 if (o >= GOF(XMM7) && o+sz <= GOF(XMM7) +SZB(XMM7)) return GOF(XMM7);
532 if (o >= GOF(XMM8) && o+sz <= GOF(XMM8) +SZB(XMM8)) return GOF(XMM8);
533 if (o >= GOF(XMM9) && o+sz <= GOF(XMM9) +SZB(XMM9)) return GOF(XMM9);
534 if (o >= GOF(XMM10) && o+sz <= GOF(XMM10)+SZB(XMM10)) return GOF(XMM10);
535 if (o >= GOF(XMM11) && o+sz <= GOF(XMM11)+SZB(XMM11)) return GOF(XMM11);
536 if (o >= GOF(XMM12) && o+sz <= GOF(XMM12)+SZB(XMM12)) return GOF(XMM12);
537 if (o >= GOF(XMM13) && o+sz <= GOF(XMM13)+SZB(XMM13)) return GOF(XMM13);
538 if (o >= GOF(XMM14) && o+sz <= GOF(XMM14)+SZB(XMM14)) return GOF(XMM14);
539 if (o >= GOF(XMM15) && o+sz <= GOF(XMM15)+SZB(XMM15)) return GOF(XMM15);
sewardj565dc132010-08-06 08:01:47 +0000540 if (o >= GOF(XMM16) && o+sz <= GOF(XMM16)+SZB(XMM16)) return GOF(XMM16);
sewardj7cf4e6b2008-05-01 20:24:26 +0000541
sewardjf1a483a2008-06-13 07:44:02 +0000542 /* MMX accesses to FP regs. Need to allow for 32-bit references
543 due to dirty helpers for frstor etc, which reference the entire
544 64-byte block in one go. */
545 if (o >= GOF(FPREG[0])
546 && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
547 if (o >= GOF(FPREG[1])
548 && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
549 if (o >= GOF(FPREG[2])
550 && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
551 if (o >= GOF(FPREG[3])
552 && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
553 if (o >= GOF(FPREG[4])
554 && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
555 if (o >= GOF(FPREG[5])
556 && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
557 if (o >= GOF(FPREG[6])
558 && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
559 if (o >= GOF(FPREG[7])
560 && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
sewardj7cf4e6b2008-05-01 20:24:26 +0000561
562 /* Map high halves of %RAX,%RCX,%RDX,%RBX to the whole register.
563 This is needed because the general handling of dirty helper
564 calls is done in 4 byte chunks. Hence we will see these.
565 Currently we only expect to see artefacts from CPUID. */
566 if (o == 4+ GOF(RAX) && sz == 4) return GOF(RAX);
567 if (o == 4+ GOF(RCX) && sz == 4) return GOF(RCX);
568 if (o == 4+ GOF(RDX) && sz == 4) return GOF(RDX);
569 if (o == 4+ GOF(RBX) && sz == 4) return GOF(RBX);
570
571 VG_(printf)("MC_(get_otrack_shadow_offset)(amd64)(off=%d,sz=%d)\n",
572 offset,szB);
573 tl_assert(0);
574# undef GOF
575# undef SZB
576
577 /* --------------------- x86 --------------------- */
578
579# elif defined(VGA_x86)
580
581# define GOF(_fieldname) \
582 (offsetof(VexGuestX86State,guest_##_fieldname))
583# define SZB(_fieldname) \
584 (sizeof(((VexGuestX86State*)0)->guest_##_fieldname))
585
586 Int o = offset;
587 Int sz = szB;
588 Bool is124 = sz == 4 || sz == 2 || sz == 1;
589 tl_assert(sz > 0);
590 tl_assert(host_is_little_endian());
591
592 if (o == GOF(EAX) && is124) return o;
593 if (o == GOF(ECX) && is124) return o;
594 if (o == GOF(EDX) && is124) return o;
595 if (o == GOF(EBX) && is124) return o;
596 if (o == GOF(ESP) && is124) return o;
597 if (o == GOF(EBP) && is124) return o;
598 if (o == GOF(ESI) && is124) return o;
599 if (o == GOF(EDI) && is124) return o;
600
601 if (o == GOF(CC_DEP1) && sz == 4) return o;
602 if (o == GOF(CC_DEP2) && sz == 4) return o;
603
604 if (o == GOF(CC_OP) && sz == 4) return -1; /* slot used for %AH */
605 if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot used for %BH */
606 if (o == GOF(DFLAG) && sz == 4) return -1; /* slot used for %CH */
607 if (o == GOF(EIP) && sz == 4) return -1; /* slot unused */
sewardj71633b12009-03-30 02:27:29 +0000608 if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000609 if (o == GOF(IDFLAG) && sz == 4) return -1; /* slot used for %DH */
610 if (o == GOF(ACFLAG) && sz == 4) return -1; /* slot unused */
sewardj105e69c2008-05-09 23:26:19 +0000611 if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
612 if (o == GOF(TILEN) && sz == 4) return -1; /* slot unused */
sewardj5575f052011-01-28 00:53:37 +0000613 if (o == GOF(NRADDR) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000614
615 /* Treat %AH, %BH, %CH, %DH as independent registers. To do this
616 requires finding 4 unused 32-bit slots in the second-shadow
617 guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG since none
618 of those are tracked. */
619 tl_assert(SZB(CC_OP) == 4);
620 tl_assert(SZB(CC_NDEP) == 4);
621 tl_assert(SZB(DFLAG) == 4);
622 tl_assert(SZB(IDFLAG) == 4);
623 if (o == 1+ GOF(EAX) && szB == 1) return GOF(CC_OP);
624 if (o == 1+ GOF(EBX) && szB == 1) return GOF(CC_NDEP);
625 if (o == 1+ GOF(ECX) && szB == 1) return GOF(DFLAG);
626 if (o == 1+ GOF(EDX) && szB == 1) return GOF(IDFLAG);
627
628 /* skip XMM and FP admin stuff */
629 if (o == GOF(SSEROUND) && szB == 4) return -1;
630 if (o == GOF(FTOP) && szB == 4) return -1;
631 if (o == GOF(FPROUND) && szB == 4) return -1;
632 if (o == GOF(EMWARN) && szB == 4) return -1;
633 if (o == GOF(FC3210) && szB == 4) return -1;
634
635 /* XMM registers */
636 if (o >= GOF(XMM0) && o+sz <= GOF(XMM0)+SZB(XMM0)) return GOF(XMM0);
637 if (o >= GOF(XMM1) && o+sz <= GOF(XMM1)+SZB(XMM1)) return GOF(XMM1);
638 if (o >= GOF(XMM2) && o+sz <= GOF(XMM2)+SZB(XMM2)) return GOF(XMM2);
639 if (o >= GOF(XMM3) && o+sz <= GOF(XMM3)+SZB(XMM3)) return GOF(XMM3);
640 if (o >= GOF(XMM4) && o+sz <= GOF(XMM4)+SZB(XMM4)) return GOF(XMM4);
641 if (o >= GOF(XMM5) && o+sz <= GOF(XMM5)+SZB(XMM5)) return GOF(XMM5);
642 if (o >= GOF(XMM6) && o+sz <= GOF(XMM6)+SZB(XMM6)) return GOF(XMM6);
643 if (o >= GOF(XMM7) && o+sz <= GOF(XMM7)+SZB(XMM7)) return GOF(XMM7);
644
645 /* MMX accesses to FP regs. Need to allow for 32-bit references
646 due to dirty helpers for frstor etc, which reference the entire
647 64-byte block in one go. */
648 if (o >= GOF(FPREG[0])
649 && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
650 if (o >= GOF(FPREG[1])
651 && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
652 if (o >= GOF(FPREG[2])
653 && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
654 if (o >= GOF(FPREG[3])
655 && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
656 if (o >= GOF(FPREG[4])
657 && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
658 if (o >= GOF(FPREG[5])
659 && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
660 if (o >= GOF(FPREG[6])
661 && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
662 if (o >= GOF(FPREG[7])
663 && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
664
665 /* skip %GS and other segment related stuff. We could shadow
666 guest_LDT and guest_GDT, although it seems pointless.
667 guest_CS .. guest_SS are too small to shadow directly and it
668 also seems pointless to shadow them indirectly (that is, in
669 the style of %AH .. %DH). */
670 if (o == GOF(CS) && sz == 2) return -1;
671 if (o == GOF(DS) && sz == 2) return -1;
672 if (o == GOF(ES) && sz == 2) return -1;
673 if (o == GOF(FS) && sz == 2) return -1;
674 if (o == GOF(GS) && sz == 2) return -1;
675 if (o == GOF(SS) && sz == 2) return -1;
676 if (o == GOF(LDT) && sz == 4) return -1;
677 if (o == GOF(GDT) && sz == 4) return -1;
678
679 VG_(printf)("MC_(get_otrack_shadow_offset)(x86)(off=%d,sz=%d)\n",
680 offset,szB);
681 tl_assert(0);
682# undef GOF
683# undef SZB
684
sewardj59570ff2010-01-01 11:59:33 +0000685 /* --------------------- arm --------------------- */
686
687# elif defined(VGA_arm)
688
689# define GOF(_fieldname) \
690 (offsetof(VexGuestARMState,guest_##_fieldname))
691# define SZB(_fieldname) \
692 (sizeof(((VexGuestARMState*)0)->guest_##_fieldname))
693
694 Int o = offset;
695 Int sz = szB;
696 tl_assert(sz > 0);
697 tl_assert(host_is_little_endian());
698
699 if (o == GOF(R0) && sz == 4) return o;
700 if (o == GOF(R1) && sz == 4) return o;
701 if (o == GOF(R2) && sz == 4) return o;
702 if (o == GOF(R3) && sz == 4) return o;
703 if (o == GOF(R4) && sz == 4) return o;
704 if (o == GOF(R5) && sz == 4) return o;
705 if (o == GOF(R6) && sz == 4) return o;
706 if (o == GOF(R7) && sz == 4) return o;
707 if (o == GOF(R8) && sz == 4) return o;
708 if (o == GOF(R9) && sz == 4) return o;
709 if (o == GOF(R10) && sz == 4) return o;
710 if (o == GOF(R11) && sz == 4) return o;
711 if (o == GOF(R12) && sz == 4) return o;
712 if (o == GOF(R13) && sz == 4) return o;
713 if (o == GOF(R14) && sz == 4) return o;
714
715 /* EAZG: These may be completely wrong. */
sewardjca9054a2010-08-22 12:16:25 +0000716 if (o == GOF(R15T) && sz == 4) return -1; /* slot unused */
sewardj59570ff2010-01-01 11:59:33 +0000717 if (o == GOF(CC_OP) && sz == 4) return -1; /* slot unused */
718
719 if (o == GOF(CC_DEP1) && sz == 4) return o;
720 if (o == GOF(CC_DEP2) && sz == 4) return o;
721
722 if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot unused */
723
sewardjca9054a2010-08-22 12:16:25 +0000724 if (o == GOF(QFLAG32) && sz == 4) return o;
725
sewardj6fede422010-09-22 22:27:41 +0000726 if (o == GOF(GEFLAG0) && sz == 4) return o;
727 if (o == GOF(GEFLAG1) && sz == 4) return o;
728 if (o == GOF(GEFLAG2) && sz == 4) return o;
729 if (o == GOF(GEFLAG3) && sz == 4) return o;
730
sewardj59570ff2010-01-01 11:59:33 +0000731 //if (o == GOF(SYSCALLNO) && sz == 4) return -1; /* slot unused */
732 //if (o == GOF(CC) && sz == 4) return -1; /* slot unused */
733 //if (o == GOF(EMWARN) && sz == 4) return -1; /* slot unused */
734 //if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
735 //if (o == GOF(NRADDR) && sz == 4) return -1; /* slot unused */
736
737 if (o == GOF(FPSCR) && sz == 4) return -1;
738 if (o == GOF(TPIDRURO) && sz == 4) return -1;
sewardjca9054a2010-08-22 12:16:25 +0000739 if (o == GOF(ITSTATE) && sz == 4) return -1;
sewardj59570ff2010-01-01 11:59:33 +0000740
sewardj8f6ec702010-09-29 21:40:44 +0000741 /* Accesses to F or D registers */
742 if (sz == 4 || sz == 8) {
743 if (o >= GOF(D0) && o+sz <= GOF(D0) +SZB(D0)) return GOF(D0);
744 if (o >= GOF(D1) && o+sz <= GOF(D1) +SZB(D1)) return GOF(D1);
745 if (o >= GOF(D2) && o+sz <= GOF(D2) +SZB(D2)) return GOF(D2);
746 if (o >= GOF(D3) && o+sz <= GOF(D3) +SZB(D3)) return GOF(D3);
747 if (o >= GOF(D4) && o+sz <= GOF(D4) +SZB(D4)) return GOF(D4);
748 if (o >= GOF(D5) && o+sz <= GOF(D5) +SZB(D5)) return GOF(D5);
749 if (o >= GOF(D6) && o+sz <= GOF(D6) +SZB(D6)) return GOF(D6);
750 if (o >= GOF(D7) && o+sz <= GOF(D7) +SZB(D7)) return GOF(D7);
751 if (o >= GOF(D8) && o+sz <= GOF(D8) +SZB(D8)) return GOF(D8);
752 if (o >= GOF(D9) && o+sz <= GOF(D9) +SZB(D9)) return GOF(D9);
753 if (o >= GOF(D10) && o+sz <= GOF(D10)+SZB(D10)) return GOF(D10);
754 if (o >= GOF(D11) && o+sz <= GOF(D11)+SZB(D11)) return GOF(D11);
755 if (o >= GOF(D12) && o+sz <= GOF(D12)+SZB(D12)) return GOF(D12);
756 if (o >= GOF(D13) && o+sz <= GOF(D13)+SZB(D13)) return GOF(D13);
757 if (o >= GOF(D14) && o+sz <= GOF(D14)+SZB(D14)) return GOF(D14);
758 if (o >= GOF(D15) && o+sz <= GOF(D15)+SZB(D15)) return GOF(D15);
759 if (o >= GOF(D16) && o+sz <= GOF(D16)+SZB(D16)) return GOF(D16);
760 if (o >= GOF(D17) && o+sz <= GOF(D17)+SZB(D17)) return GOF(D17);
761 if (o >= GOF(D18) && o+sz <= GOF(D18)+SZB(D18)) return GOF(D18);
762 if (o >= GOF(D19) && o+sz <= GOF(D19)+SZB(D19)) return GOF(D19);
763 if (o >= GOF(D20) && o+sz <= GOF(D20)+SZB(D20)) return GOF(D20);
764 if (o >= GOF(D21) && o+sz <= GOF(D21)+SZB(D21)) return GOF(D21);
765 if (o >= GOF(D22) && o+sz <= GOF(D22)+SZB(D22)) return GOF(D22);
766 if (o >= GOF(D23) && o+sz <= GOF(D23)+SZB(D23)) return GOF(D23);
767 if (o >= GOF(D24) && o+sz <= GOF(D24)+SZB(D24)) return GOF(D24);
768 if (o >= GOF(D25) && o+sz <= GOF(D25)+SZB(D25)) return GOF(D25);
769 if (o >= GOF(D26) && o+sz <= GOF(D26)+SZB(D26)) return GOF(D26);
770 if (o >= GOF(D27) && o+sz <= GOF(D27)+SZB(D27)) return GOF(D27);
771 if (o >= GOF(D28) && o+sz <= GOF(D28)+SZB(D28)) return GOF(D28);
772 if (o >= GOF(D29) && o+sz <= GOF(D29)+SZB(D29)) return GOF(D29);
773 if (o >= GOF(D30) && o+sz <= GOF(D30)+SZB(D30)) return GOF(D30);
774 if (o >= GOF(D31) && o+sz <= GOF(D31)+SZB(D31)) return GOF(D31);
775 }
776
777 /* Accesses to Q registers */
778 if (sz == 16) {
779 if (o >= GOF(D0) && o+sz <= GOF(D0) +2*SZB(D0)) return GOF(D0); // Q0
780 if (o >= GOF(D2) && o+sz <= GOF(D2) +2*SZB(D2)) return GOF(D2); // Q1
781 if (o >= GOF(D4) && o+sz <= GOF(D4) +2*SZB(D4)) return GOF(D4); // Q2
782 if (o >= GOF(D6) && o+sz <= GOF(D6) +2*SZB(D6)) return GOF(D6); // Q3
783 if (o >= GOF(D8) && o+sz <= GOF(D8) +2*SZB(D8)) return GOF(D8); // Q4
784 if (o >= GOF(D10) && o+sz <= GOF(D10)+2*SZB(D10)) return GOF(D10); // Q5
785 if (o >= GOF(D12) && o+sz <= GOF(D12)+2*SZB(D12)) return GOF(D12); // Q6
786 if (o >= GOF(D14) && o+sz <= GOF(D14)+2*SZB(D14)) return GOF(D14); // Q7
787 if (o >= GOF(D16) && o+sz <= GOF(D16)+2*SZB(D16)) return GOF(D16); // Q8
788 if (o >= GOF(D18) && o+sz <= GOF(D18)+2*SZB(D18)) return GOF(D18); // Q9
789 if (o >= GOF(D20) && o+sz <= GOF(D20)+2*SZB(D20)) return GOF(D20); // Q10
790 if (o >= GOF(D22) && o+sz <= GOF(D22)+2*SZB(D22)) return GOF(D22); // Q11
791 if (o >= GOF(D24) && o+sz <= GOF(D24)+2*SZB(D24)) return GOF(D24); // Q12
792 if (o >= GOF(D26) && o+sz <= GOF(D26)+2*SZB(D26)) return GOF(D26); // Q13
793 if (o >= GOF(D28) && o+sz <= GOF(D28)+2*SZB(D28)) return GOF(D28); // Q14
794 if (o >= GOF(D30) && o+sz <= GOF(D30)+2*SZB(D30)) return GOF(D30); // Q15
795 }
sewardj59570ff2010-01-01 11:59:33 +0000796
797 VG_(printf)("MC_(get_otrack_shadow_offset)(arm)(off=%d,sz=%d)\n",
798 offset,szB);
799 tl_assert(0);
800# undef GOF
801# undef SZB
802
sewardj7cf4e6b2008-05-01 20:24:26 +0000803# else
804# error "FIXME: not implemented for this architecture"
805# endif
806}
807
808
809/* Let 'arr' describe an indexed reference to a guest state section
810 (guest state array).
811
812 This function returns the corresponding guest state type to be used
813 when indexing the corresponding array in the second shadow (origin
814 tracking) area. If the array is not to be origin-tracked, return
815 Ity_INVALID.
816
817 This function must agree with MC_(get_otrack_shadow_offset) above.
818 See comments at the start of MC_(get_otrack_shadow_offset).
819*/
820IRType MC_(get_otrack_reg_array_equiv_int_type) ( IRRegArray* arr )
821{
822 /* -------------------- ppc64 -------------------- */
823# if defined(VGA_ppc64)
824 /* The redir stack. */
825 if (arr->base == offsetof(VexGuestPPC64State,guest_REDIR_STACK[0])
826 && arr->elemTy == Ity_I64
827 && arr->nElems == VEX_GUEST_PPC64_REDIR_STACK_SIZE)
828 return Ity_I64;
829
830 VG_(printf)("get_reg_array_equiv_int_type(ppc64): unhandled: ");
831 ppIRRegArray(arr);
832 VG_(printf)("\n");
833 tl_assert(0);
834
835 /* -------------------- ppc32 -------------------- */
836# elif defined(VGA_ppc32)
837 /* The redir stack. */
838 if (arr->base == offsetof(VexGuestPPC32State,guest_REDIR_STACK[0])
839 && arr->elemTy == Ity_I32
840 && arr->nElems == VEX_GUEST_PPC32_REDIR_STACK_SIZE)
841 return Ity_I32;
842
843 VG_(printf)("get_reg_array_equiv_int_type(ppc32): unhandled: ");
844 ppIRRegArray(arr);
845 VG_(printf)("\n");
846 tl_assert(0);
847
848 /* -------------------- amd64 -------------------- */
849# elif defined(VGA_amd64)
850 /* Ignore the FP tag array - pointless to shadow, and in any case
851 the elements are too small */
852 if (arr->base == offsetof(VexGuestAMD64State,guest_FPTAG)
853 && arr->elemTy == Ity_I8 && arr->nElems == 8)
854 return Ity_INVALID;
855
856 /* The FP register array */
857 if (arr->base == offsetof(VexGuestAMD64State,guest_FPREG[0])
858 && arr->elemTy == Ity_F64 && arr->nElems == 8)
859 return Ity_I64;
860
861 VG_(printf)("get_reg_array_equiv_int_type(amd64): unhandled: ");
862 ppIRRegArray(arr);
863 VG_(printf)("\n");
864 tl_assert(0);
865
866 /* --------------------- x86 --------------------- */
867# elif defined(VGA_x86)
868 /* Ignore the FP tag array - pointless to shadow, and in any case
869 the elements are too small */
870 if (arr->base == offsetof(VexGuestX86State,guest_FPTAG)
871 && arr->elemTy == Ity_I8 && arr->nElems == 8)
872 return Ity_INVALID;
873
874 /* The FP register array */
875 if (arr->base == offsetof(VexGuestX86State,guest_FPREG[0])
876 && arr->elemTy == Ity_F64 && arr->nElems == 8)
877 return Ity_I64;
878
879 VG_(printf)("get_reg_array_equiv_int_type(x86): unhandled: ");
880 ppIRRegArray(arr);
881 VG_(printf)("\n");
882 tl_assert(0);
883
sewardj59570ff2010-01-01 11:59:33 +0000884 /* --------------------- arm --------------------- */
885# elif defined(VGA_arm)
886
887 VG_(printf)("get_reg_array_equiv_int_type(arm): unhandled: ");
888 ppIRRegArray(arr);
889 VG_(printf)("\n");
890 tl_assert(0);
891
sewardj7cf4e6b2008-05-01 20:24:26 +0000892# else
893# error "FIXME: not implemented for this architecture"
894# endif
895}
896
897
898/*--------------------------------------------------------------------*/
899/*--- end mc_machine.c ---*/
900/*--------------------------------------------------------------------*/