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