blob: 4072b8ada00dd85bbb23451aee5ba949854c0ee1 [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
njn9f207462009-03-10 22:02:09 +000012 Copyright (C) 2008-2009 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
68static inline Bool host_is_big_endian ( void ) {
69 UInt x = 0x11223344;
70 return 0x1122 == *(UShort*)(&x);
71}
72static inline Bool host_is_little_endian ( void ) {
73 UInt x = 0x11223344;
74 return 0x3344 == *(UShort*)(&x);
75}
76
77
78/* Let (offset,szB) describe a reference to the guest state section
79 [offset, offset+szB).
80
81 This function returns the corresponding guest state reference to be
82 used for the origin tag (which of course will be in the second
83 shadow area), or -1 if this piece of guest state is not to be
84 tracked.
85
86 Since origin tags are 32-bits long, we expect any returned value
87 (except -1) to be a multiple of 4, between 0 and
88 sizeof(guest-state)-4 inclusive.
89
90 This is inherently (guest-)architecture specific. For x86 and
91 amd64 we do some somewhat tricky things to give %AH .. %DH their
92 own tags. On ppc32/64 we do some marginally tricky things to give
93 all 16 %CR components their own tags.
94
95 This function only deals with references to the guest state whose
96 offsets are known at translation time (that is, references arising
97 from Put and Get). References whose offset is not known until run
98 time (that is, arise from PutI and GetI) are handled by
99 MC_(get_otrack_reg_array_equiv_int_type) below.
100
101 Note that since some guest state arrays (eg, the x86 FP reg stack)
102 are accessed both as arrays (eg, x87 insns) and directly (eg, MMX
103 insns), the two functions must be consistent for those sections of
104 guest state -- that is, they must both say the area is shadowed, or
105 both say it is not.
106
107 This function is dependent on the host's endianness, hence we
108 assert that the use case is supported.
109*/
110static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ); /*fwds*/
111
112Int MC_(get_otrack_shadow_offset) ( Int offset, Int szB )
113{
114 Int cand = get_otrack_shadow_offset_wrk( offset, szB );
115 if (cand == -1)
116 return cand;
117 tl_assert(0 == (cand & 3));
118 tl_assert(cand <= MC_SIZEOF_GUEST_STATE-4);
119 return cand;
120}
121
122
123static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
124{
125 /* -------------------- ppc64 -------------------- */
126
127# if defined(VGA_ppc64)
128
129# define GOF(_fieldname) \
130 (offsetof(VexGuestPPC64State,guest_##_fieldname))
131# define SZB(_fieldname) \
132 (sizeof(((VexGuestPPC64State*)0)->guest_##_fieldname))
133
134 Int sz = szB;
135 Int o = offset;
136 tl_assert(sz > 0);
137 tl_assert(host_is_big_endian());
138
139 if (sz == 8 || sz == 4) {
140 /* The point of this is to achieve
141 if ((o == GOF(GPRn) && sz == 8) || (o == 4+GOF(GPRn) && sz == 4))
142 return GOF(GPRn);
143 by testing ox instead of o, and setting ox back 4 bytes when sz == 4.
144 */
sewardj85857ab2008-05-06 15:40:32 +0000145 Int ox = sz == 8 ? o : (o - 4);
sewardj7cf4e6b2008-05-01 20:24:26 +0000146 if (ox == GOF(GPR0)) return ox;
147 if (ox == GOF(GPR1)) return ox;
148 if (ox == GOF(GPR2)) return ox;
149 if (ox == GOF(GPR3)) return ox;
150 if (ox == GOF(GPR4)) return ox;
151 if (ox == GOF(GPR5)) return ox;
152 if (ox == GOF(GPR6)) return ox;
153 if (ox == GOF(GPR7)) return ox;
154 if (ox == GOF(GPR8)) return ox;
155 if (ox == GOF(GPR9)) return ox;
156 if (ox == GOF(GPR10)) return ox;
157 if (ox == GOF(GPR11)) return ox;
158 if (ox == GOF(GPR12)) return ox;
159 if (ox == GOF(GPR13)) return ox;
160 if (ox == GOF(GPR14)) return ox;
161 if (ox == GOF(GPR15)) return ox;
162 if (ox == GOF(GPR16)) return ox;
163 if (ox == GOF(GPR17)) return ox;
164 if (ox == GOF(GPR18)) return ox;
165 if (ox == GOF(GPR19)) return ox;
166 if (ox == GOF(GPR20)) return ox;
167 if (ox == GOF(GPR21)) return ox;
168 if (ox == GOF(GPR22)) return ox;
169 if (ox == GOF(GPR23)) return ox;
170 if (ox == GOF(GPR24)) return ox;
171 if (ox == GOF(GPR25)) return ox;
172 if (ox == GOF(GPR26)) return ox;
173 if (ox == GOF(GPR27)) return ox;
174 if (ox == GOF(GPR28)) return ox;
175 if (ox == GOF(GPR29)) return ox;
176 if (ox == GOF(GPR30)) return ox;
177 if (ox == GOF(GPR31)) return ox;
178 }
179
180 if (o == GOF(LR) && sz == 8) return o;
181 if (o == GOF(CTR) && sz == 8) return o;
182
183 if (o == GOF(CIA) && sz == 8) return -1;
sewardj71633b12009-03-30 02:27:29 +0000184 if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000185 if (o == GOF(RESVN) && sz == 8) return -1;
186 if (o == GOF(FPROUND) && sz == 4) return -1;
187 if (o == GOF(EMWARN) && sz == 4) return -1;
188 if (o == GOF(TISTART) && sz == 8) return -1;
189 if (o == GOF(TILEN) && sz == 8) return -1;
190 if (o == GOF(VSCR) && sz == 4) return -1;
191 if (o == GOF(VRSAVE) && sz == 4) return -1;
192 if (o == GOF(REDIR_SP) && sz == 8) return -1;
193
194 tl_assert(SZB(FPR0) == 8);
195 if (o == GOF(FPR0) && sz == 8) return o;
196 if (o == GOF(FPR1) && sz == 8) return o;
197 if (o == GOF(FPR2) && sz == 8) return o;
198 if (o == GOF(FPR3) && sz == 8) return o;
199 if (o == GOF(FPR4) && sz == 8) return o;
200 if (o == GOF(FPR5) && sz == 8) return o;
201 if (o == GOF(FPR6) && sz == 8) return o;
202 if (o == GOF(FPR7) && sz == 8) return o;
203 if (o == GOF(FPR8) && sz == 8) return o;
204 if (o == GOF(FPR9) && sz == 8) return o;
205 if (o == GOF(FPR10) && sz == 8) return o;
206 if (o == GOF(FPR11) && sz == 8) return o;
207 if (o == GOF(FPR12) && sz == 8) return o;
208 if (o == GOF(FPR13) && sz == 8) return o;
209 if (o == GOF(FPR14) && sz == 8) return o;
210 if (o == GOF(FPR15) && sz == 8) return o;
211 if (o == GOF(FPR16) && sz == 8) return o;
212 if (o == GOF(FPR17) && sz == 8) return o;
213 if (o == GOF(FPR18) && sz == 8) return o;
214 if (o == GOF(FPR19) && sz == 8) return o;
215 if (o == GOF(FPR20) && sz == 8) return o;
216 if (o == GOF(FPR21) && sz == 8) return o;
217 if (o == GOF(FPR22) && sz == 8) return o;
218 if (o == GOF(FPR23) && sz == 8) return o;
219 if (o == GOF(FPR24) && sz == 8) return o;
220 if (o == GOF(FPR25) && sz == 8) return o;
221 if (o == GOF(FPR26) && sz == 8) return o;
222 if (o == GOF(FPR27) && sz == 8) return o;
223 if (o == GOF(FPR28) && sz == 8) return o;
224 if (o == GOF(FPR29) && sz == 8) return o;
225 if (o == GOF(FPR30) && sz == 8) return o;
226 if (o == GOF(FPR31) && sz == 8) return o;
227
228 /* For the various byte sized XER/CR pieces, use offset 8
229 in VR0 .. VR31. */
230 tl_assert(SZB(VR0) == 16);
231 if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VR0);
232 if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VR1);
233 if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VR2);
234 if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VR3);
235
236 if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VR4);
237 if (o == GOF(CR0_0) && sz == 1) return 8 +GOF(VR5);
238 if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VR6);
239 if (o == GOF(CR1_0) && sz == 1) return 8 +GOF(VR7);
240 if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VR8);
241 if (o == GOF(CR2_0) && sz == 1) return 8 +GOF(VR9);
242 if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VR10);
243 if (o == GOF(CR3_0) && sz == 1) return 8 +GOF(VR11);
244 if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VR12);
245 if (o == GOF(CR4_0) && sz == 1) return 8 +GOF(VR13);
246 if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VR14);
247 if (o == GOF(CR5_0) && sz == 1) return 8 +GOF(VR15);
248 if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VR16);
249 if (o == GOF(CR6_0) && sz == 1) return 8 +GOF(VR17);
250 if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VR18);
251 if (o == GOF(CR7_0) && sz == 1) return 8 +GOF(VR19);
252
253 /* Vector registers .. use offset 0 in VR0 .. VR31. */
254 if (o >= GOF(VR0) && o+sz <= GOF(VR0) +SZB(VR0)) return 0+ GOF(VR0);
255 if (o >= GOF(VR1) && o+sz <= GOF(VR1) +SZB(VR1)) return 0+ GOF(VR1);
256 if (o >= GOF(VR2) && o+sz <= GOF(VR2) +SZB(VR2)) return 0+ GOF(VR2);
257 if (o >= GOF(VR3) && o+sz <= GOF(VR3) +SZB(VR3)) return 0+ GOF(VR3);
258 if (o >= GOF(VR4) && o+sz <= GOF(VR4) +SZB(VR4)) return 0+ GOF(VR4);
259 if (o >= GOF(VR5) && o+sz <= GOF(VR5) +SZB(VR5)) return 0+ GOF(VR5);
260 if (o >= GOF(VR6) && o+sz <= GOF(VR6) +SZB(VR6)) return 0+ GOF(VR6);
261 if (o >= GOF(VR7) && o+sz <= GOF(VR7) +SZB(VR7)) return 0+ GOF(VR7);
262 if (o >= GOF(VR8) && o+sz <= GOF(VR8) +SZB(VR8)) return 0+ GOF(VR8);
263 if (o >= GOF(VR9) && o+sz <= GOF(VR9) +SZB(VR9)) return 0+ GOF(VR9);
264 if (o >= GOF(VR10) && o+sz <= GOF(VR10)+SZB(VR10)) return 0+ GOF(VR10);
265 if (o >= GOF(VR11) && o+sz <= GOF(VR11)+SZB(VR11)) return 0+ GOF(VR11);
266 if (o >= GOF(VR12) && o+sz <= GOF(VR12)+SZB(VR12)) return 0+ GOF(VR12);
267 if (o >= GOF(VR13) && o+sz <= GOF(VR13)+SZB(VR13)) return 0+ GOF(VR13);
268 if (o >= GOF(VR14) && o+sz <= GOF(VR14)+SZB(VR14)) return 0+ GOF(VR14);
269 if (o >= GOF(VR15) && o+sz <= GOF(VR15)+SZB(VR15)) return 0+ GOF(VR15);
270 if (o >= GOF(VR16) && o+sz <= GOF(VR16)+SZB(VR16)) return 0+ GOF(VR16);
271 if (o >= GOF(VR17) && o+sz <= GOF(VR17)+SZB(VR17)) return 0+ GOF(VR17);
272 if (o >= GOF(VR18) && o+sz <= GOF(VR18)+SZB(VR18)) return 0+ GOF(VR18);
273 if (o >= GOF(VR19) && o+sz <= GOF(VR19)+SZB(VR19)) return 0+ GOF(VR19);
274 if (o >= GOF(VR20) && o+sz <= GOF(VR20)+SZB(VR20)) return 0+ GOF(VR20);
275 if (o >= GOF(VR21) && o+sz <= GOF(VR21)+SZB(VR21)) return 0+ GOF(VR21);
276 if (o >= GOF(VR22) && o+sz <= GOF(VR22)+SZB(VR22)) return 0+ GOF(VR22);
277 if (o >= GOF(VR23) && o+sz <= GOF(VR23)+SZB(VR23)) return 0+ GOF(VR23);
278 if (o >= GOF(VR24) && o+sz <= GOF(VR24)+SZB(VR24)) return 0+ GOF(VR24);
279 if (o >= GOF(VR25) && o+sz <= GOF(VR25)+SZB(VR25)) return 0+ GOF(VR25);
280 if (o >= GOF(VR26) && o+sz <= GOF(VR26)+SZB(VR26)) return 0+ GOF(VR26);
281 if (o >= GOF(VR27) && o+sz <= GOF(VR27)+SZB(VR27)) return 0+ GOF(VR27);
282 if (o >= GOF(VR28) && o+sz <= GOF(VR28)+SZB(VR28)) return 0+ GOF(VR28);
283 if (o >= GOF(VR29) && o+sz <= GOF(VR29)+SZB(VR29)) return 0+ GOF(VR29);
284 if (o >= GOF(VR30) && o+sz <= GOF(VR30)+SZB(VR30)) return 0+ GOF(VR30);
285 if (o >= GOF(VR31) && o+sz <= GOF(VR31)+SZB(VR31)) return 0+ GOF(VR31);
286
287 VG_(printf)("MC_(get_otrack_shadow_offset)(ppc64)(off=%d,sz=%d)\n",
288 offset,szB);
289 tl_assert(0);
290# undef GOF
291# undef SZB
292
293 /* -------------------- ppc32 -------------------- */
294
295# elif defined(VGA_ppc32)
296
297# define GOF(_fieldname) \
298 (offsetof(VexGuestPPC32State,guest_##_fieldname))
299# define SZB(_fieldname) \
300 (sizeof(((VexGuestPPC32State*)0)->guest_##_fieldname))
301 Int o = offset;
302 Int sz = szB;
303 tl_assert(sz > 0);
304 tl_assert(host_is_big_endian());
305
306 if (o == GOF(GPR0) && sz == 4) return o;
307 if (o == GOF(GPR1) && sz == 4) return o;
308 if (o == GOF(GPR2) && sz == 4) return o;
309 if (o == GOF(GPR3) && sz == 4) return o;
310 if (o == GOF(GPR4) && sz == 4) return o;
311 if (o == GOF(GPR5) && sz == 4) return o;
312 if (o == GOF(GPR6) && sz == 4) return o;
313 if (o == GOF(GPR7) && sz == 4) return o;
314 if (o == GOF(GPR8) && sz == 4) return o;
315 if (o == GOF(GPR9) && sz == 4) return o;
316 if (o == GOF(GPR10) && sz == 4) return o;
317 if (o == GOF(GPR11) && sz == 4) return o;
318 if (o == GOF(GPR12) && sz == 4) return o;
319 if (o == GOF(GPR13) && sz == 4) return o;
320 if (o == GOF(GPR14) && sz == 4) return o;
321 if (o == GOF(GPR15) && sz == 4) return o;
322 if (o == GOF(GPR16) && sz == 4) return o;
323 if (o == GOF(GPR17) && sz == 4) return o;
324 if (o == GOF(GPR18) && sz == 4) return o;
325 if (o == GOF(GPR19) && sz == 4) return o;
326 if (o == GOF(GPR20) && sz == 4) return o;
327 if (o == GOF(GPR21) && sz == 4) return o;
328 if (o == GOF(GPR22) && sz == 4) return o;
329 if (o == GOF(GPR23) && sz == 4) return o;
330 if (o == GOF(GPR24) && sz == 4) return o;
331 if (o == GOF(GPR25) && sz == 4) return o;
332 if (o == GOF(GPR26) && sz == 4) return o;
333 if (o == GOF(GPR27) && sz == 4) return o;
334 if (o == GOF(GPR28) && sz == 4) return o;
335 if (o == GOF(GPR29) && sz == 4) return o;
336 if (o == GOF(GPR30) && sz == 4) return o;
337 if (o == GOF(GPR31) && sz == 4) return o;
338
339 if (o == GOF(LR) && sz == 4) return o;
340 if (o == GOF(CTR) && sz == 4) return o;
341
342 if (o == GOF(CIA) && sz == 4) return -1;
sewardj71633b12009-03-30 02:27:29 +0000343 if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000344 if (o == GOF(RESVN) && sz == 4) return -1;
345 if (o == GOF(FPROUND) && sz == 4) return -1;
sewardj3b507352009-02-14 15:28:46 +0000346 if (o == GOF(VRSAVE) && sz == 4) return -1;
sewardj7cf4e6b2008-05-01 20:24:26 +0000347 if (o == GOF(EMWARN) && sz == 4) return -1;
348 if (o == GOF(TISTART) && sz == 4) return -1;
349 if (o == GOF(TILEN) && sz == 4) return -1;
350 if (o == GOF(VSCR) && sz == 4) return -1;
351 if (o == GOF(REDIR_SP) && sz == 4) return -1;
352 if (o == GOF(SPRG3_RO) && sz == 4) return -1;
353
354 tl_assert(SZB(FPR0) == 8);
355 if (o == GOF(FPR0) && sz == 8) return o;
356 if (o == GOF(FPR1) && sz == 8) return o;
357 if (o == GOF(FPR2) && sz == 8) return o;
358 if (o == GOF(FPR3) && sz == 8) return o;
359 if (o == GOF(FPR4) && sz == 8) return o;
360 if (o == GOF(FPR5) && sz == 8) return o;
361 if (o == GOF(FPR6) && sz == 8) return o;
362 if (o == GOF(FPR7) && sz == 8) return o;
363 if (o == GOF(FPR8) && sz == 8) return o;
364 if (o == GOF(FPR9) && sz == 8) return o;
365 if (o == GOF(FPR10) && sz == 8) return o;
366 if (o == GOF(FPR11) && sz == 8) return o;
367 if (o == GOF(FPR12) && sz == 8) return o;
368 if (o == GOF(FPR13) && sz == 8) return o;
369 if (o == GOF(FPR14) && sz == 8) return o;
370 if (o == GOF(FPR15) && sz == 8) return o;
371 if (o == GOF(FPR16) && sz == 8) return o;
372 if (o == GOF(FPR17) && sz == 8) return o;
373 if (o == GOF(FPR18) && sz == 8) return o;
374 if (o == GOF(FPR19) && sz == 8) return o;
375 if (o == GOF(FPR20) && sz == 8) return o;
376 if (o == GOF(FPR21) && sz == 8) return o;
377 if (o == GOF(FPR22) && sz == 8) return o;
378 if (o == GOF(FPR23) && sz == 8) return o;
379 if (o == GOF(FPR24) && sz == 8) return o;
380 if (o == GOF(FPR25) && sz == 8) return o;
381 if (o == GOF(FPR26) && sz == 8) return o;
382 if (o == GOF(FPR27) && sz == 8) return o;
383 if (o == GOF(FPR28) && sz == 8) return o;
384 if (o == GOF(FPR29) && sz == 8) return o;
385 if (o == GOF(FPR30) && sz == 8) return o;
386 if (o == GOF(FPR31) && sz == 8) return o;
387
388 /* For the various byte sized XER/CR pieces, use offset 8
389 in VR0 .. VR31. */
390 tl_assert(SZB(VR0) == 16);
391 if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VR0);
392 if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VR1);
393 if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VR2);
394 if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VR3);
395
396 if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VR4);
397 if (o == GOF(CR0_0) && sz == 1) return 8 +GOF(VR5);
398 if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VR6);
399 if (o == GOF(CR1_0) && sz == 1) return 8 +GOF(VR7);
400 if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VR8);
401 if (o == GOF(CR2_0) && sz == 1) return 8 +GOF(VR9);
402 if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VR10);
403 if (o == GOF(CR3_0) && sz == 1) return 8 +GOF(VR11);
404 if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VR12);
405 if (o == GOF(CR4_0) && sz == 1) return 8 +GOF(VR13);
406 if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VR14);
407 if (o == GOF(CR5_0) && sz == 1) return 8 +GOF(VR15);
408 if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VR16);
409 if (o == GOF(CR6_0) && sz == 1) return 8 +GOF(VR17);
410 if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VR18);
411 if (o == GOF(CR7_0) && sz == 1) return 8 +GOF(VR19);
412
413 /* Vector registers .. use offset 0 in VR0 .. VR31. */
414 if (o >= GOF(VR0) && o+sz <= GOF(VR0) +SZB(VR0)) return 0+ GOF(VR0);
415 if (o >= GOF(VR1) && o+sz <= GOF(VR1) +SZB(VR1)) return 0+ GOF(VR1);
416 if (o >= GOF(VR2) && o+sz <= GOF(VR2) +SZB(VR2)) return 0+ GOF(VR2);
417 if (o >= GOF(VR3) && o+sz <= GOF(VR3) +SZB(VR3)) return 0+ GOF(VR3);
418 if (o >= GOF(VR4) && o+sz <= GOF(VR4) +SZB(VR4)) return 0+ GOF(VR4);
419 if (o >= GOF(VR5) && o+sz <= GOF(VR5) +SZB(VR5)) return 0+ GOF(VR5);
420 if (o >= GOF(VR6) && o+sz <= GOF(VR6) +SZB(VR6)) return 0+ GOF(VR6);
421 if (o >= GOF(VR7) && o+sz <= GOF(VR7) +SZB(VR7)) return 0+ GOF(VR7);
422 if (o >= GOF(VR8) && o+sz <= GOF(VR8) +SZB(VR8)) return 0+ GOF(VR8);
423 if (o >= GOF(VR9) && o+sz <= GOF(VR9) +SZB(VR9)) return 0+ GOF(VR9);
424 if (o >= GOF(VR10) && o+sz <= GOF(VR10)+SZB(VR10)) return 0+ GOF(VR10);
425 if (o >= GOF(VR11) && o+sz <= GOF(VR11)+SZB(VR11)) return 0+ GOF(VR11);
426 if (o >= GOF(VR12) && o+sz <= GOF(VR12)+SZB(VR12)) return 0+ GOF(VR12);
427 if (o >= GOF(VR13) && o+sz <= GOF(VR13)+SZB(VR13)) return 0+ GOF(VR13);
428 if (o >= GOF(VR14) && o+sz <= GOF(VR14)+SZB(VR14)) return 0+ GOF(VR14);
429 if (o >= GOF(VR15) && o+sz <= GOF(VR15)+SZB(VR15)) return 0+ GOF(VR15);
430 if (o >= GOF(VR16) && o+sz <= GOF(VR16)+SZB(VR16)) return 0+ GOF(VR16);
431 if (o >= GOF(VR17) && o+sz <= GOF(VR17)+SZB(VR17)) return 0+ GOF(VR17);
432 if (o >= GOF(VR18) && o+sz <= GOF(VR18)+SZB(VR18)) return 0+ GOF(VR18);
433 if (o >= GOF(VR19) && o+sz <= GOF(VR19)+SZB(VR19)) return 0+ GOF(VR19);
434 if (o >= GOF(VR20) && o+sz <= GOF(VR20)+SZB(VR20)) return 0+ GOF(VR20);
435 if (o >= GOF(VR21) && o+sz <= GOF(VR21)+SZB(VR21)) return 0+ GOF(VR21);
436 if (o >= GOF(VR22) && o+sz <= GOF(VR22)+SZB(VR22)) return 0+ GOF(VR22);
437 if (o >= GOF(VR23) && o+sz <= GOF(VR23)+SZB(VR23)) return 0+ GOF(VR23);
438 if (o >= GOF(VR24) && o+sz <= GOF(VR24)+SZB(VR24)) return 0+ GOF(VR24);
439 if (o >= GOF(VR25) && o+sz <= GOF(VR25)+SZB(VR25)) return 0+ GOF(VR25);
440 if (o >= GOF(VR26) && o+sz <= GOF(VR26)+SZB(VR26)) return 0+ GOF(VR26);
441 if (o >= GOF(VR27) && o+sz <= GOF(VR27)+SZB(VR27)) return 0+ GOF(VR27);
442 if (o >= GOF(VR28) && o+sz <= GOF(VR28)+SZB(VR28)) return 0+ GOF(VR28);
443 if (o >= GOF(VR29) && o+sz <= GOF(VR29)+SZB(VR29)) return 0+ GOF(VR29);
444 if (o >= GOF(VR30) && o+sz <= GOF(VR30)+SZB(VR30)) return 0+ GOF(VR30);
445 if (o >= GOF(VR31) && o+sz <= GOF(VR31)+SZB(VR31)) return 0+ GOF(VR31);
446
447 VG_(printf)("MC_(get_otrack_shadow_offset)(ppc32)(off=%d,sz=%d)\n",
448 offset,szB);
449 tl_assert(0);
450# undef GOF
451# undef SZB
452
453 /* -------------------- amd64 -------------------- */
454
455# elif defined(VGA_amd64)
456
457# define GOF(_fieldname) \
458 (offsetof(VexGuestAMD64State,guest_##_fieldname))
459# define SZB(_fieldname) \
460 (sizeof(((VexGuestAMD64State*)0)->guest_##_fieldname))
461 Int o = offset;
462 Int sz = szB;
463 Bool is1248 = sz == 8 || sz == 4 || sz == 2 || sz == 1;
464 tl_assert(sz > 0);
465 tl_assert(host_is_little_endian());
466
467 if (o == GOF(RAX) && is1248) return o;
468 if (o == GOF(RCX) && is1248) return o;
469 if (o == GOF(RDX) && is1248) return o;
470 if (o == GOF(RBX) && is1248) return o;
471 if (o == GOF(RSP) && is1248) return o;
472 if (o == GOF(RBP) && is1248) return o;
473 if (o == GOF(RSI) && is1248) return o;
474 if (o == GOF(RDI) && is1248) return o;
475 if (o == GOF(R8) && is1248) return o;
476 if (o == GOF(R9) && is1248) return o;
477 if (o == GOF(R10) && is1248) return o;
478 if (o == GOF(R11) && is1248) return o;
479 if (o == GOF(R12) && is1248) return o;
480 if (o == GOF(R13) && is1248) return o;
481 if (o == GOF(R14) && is1248) return o;
482 if (o == GOF(R15) && is1248) return o;
483
484 if (o == GOF(CC_DEP1) && sz == 8) return o;
485 if (o == GOF(CC_DEP2) && sz == 8) return o;
486
487 if (o == GOF(CC_OP) && sz == 8) return -1; /* slot used for %AH */
488 if (o == GOF(CC_NDEP) && sz == 8) return -1; /* slot used for %BH */
489 if (o == GOF(DFLAG) && sz == 8) return -1; /* slot used for %CH */
490 if (o == GOF(RIP) && sz == 8) return -1; /* slot unused */
sewardj71633b12009-03-30 02:27:29 +0000491 if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000492 if (o == GOF(IDFLAG) && sz == 8) return -1; /* slot used for %DH */
493 if (o == GOF(FS_ZERO) && sz == 8) return -1; /* slot unused */
sewardj105e69c2008-05-09 23:26:19 +0000494 if (o == GOF(TISTART) && sz == 8) return -1; /* slot unused */
495 if (o == GOF(TILEN) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000496
497 /* Treat %AH, %BH, %CH, %DH as independent registers. To do this
498 requires finding 4 unused 32-bit slots in the second-shadow
499 guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG, since
500 none of those are tracked. */
501 tl_assert(SZB(CC_OP) == 8);
502 tl_assert(SZB(CC_NDEP) == 8);
503 tl_assert(SZB(IDFLAG) == 8);
504 tl_assert(SZB(DFLAG) == 8);
505
506 if (o == 1+ GOF(RAX) && szB == 1) return GOF(CC_OP);
507 if (o == 1+ GOF(RBX) && szB == 1) return GOF(CC_NDEP);
508 if (o == 1+ GOF(RCX) && szB == 1) return GOF(DFLAG);
509 if (o == 1+ GOF(RDX) && szB == 1) return GOF(IDFLAG);
510
511 /* skip XMM and FP admin stuff */
512 if (o == GOF(SSEROUND) && szB == 8) return -1;
513 if (o == GOF(FTOP) && szB == 4) return -1;
514 if (o == GOF(FPROUND) && szB == 8) return -1;
515 if (o == GOF(EMWARN) && szB == 4) return -1;
sewardj89ea7ab2008-05-27 16:08:24 +0000516 if (o == GOF(FC3210) && szB == 8) return -1;
sewardj7cf4e6b2008-05-01 20:24:26 +0000517
518 /* XMM registers */
519 if (o >= GOF(XMM0) && o+sz <= GOF(XMM0) +SZB(XMM0)) return GOF(XMM0);
520 if (o >= GOF(XMM1) && o+sz <= GOF(XMM1) +SZB(XMM1)) return GOF(XMM1);
521 if (o >= GOF(XMM2) && o+sz <= GOF(XMM2) +SZB(XMM2)) return GOF(XMM2);
522 if (o >= GOF(XMM3) && o+sz <= GOF(XMM3) +SZB(XMM3)) return GOF(XMM3);
523 if (o >= GOF(XMM4) && o+sz <= GOF(XMM4) +SZB(XMM4)) return GOF(XMM4);
524 if (o >= GOF(XMM5) && o+sz <= GOF(XMM5) +SZB(XMM5)) return GOF(XMM5);
525 if (o >= GOF(XMM6) && o+sz <= GOF(XMM6) +SZB(XMM6)) return GOF(XMM6);
526 if (o >= GOF(XMM7) && o+sz <= GOF(XMM7) +SZB(XMM7)) return GOF(XMM7);
527 if (o >= GOF(XMM8) && o+sz <= GOF(XMM8) +SZB(XMM8)) return GOF(XMM8);
528 if (o >= GOF(XMM9) && o+sz <= GOF(XMM9) +SZB(XMM9)) return GOF(XMM9);
529 if (o >= GOF(XMM10) && o+sz <= GOF(XMM10)+SZB(XMM10)) return GOF(XMM10);
530 if (o >= GOF(XMM11) && o+sz <= GOF(XMM11)+SZB(XMM11)) return GOF(XMM11);
531 if (o >= GOF(XMM12) && o+sz <= GOF(XMM12)+SZB(XMM12)) return GOF(XMM12);
532 if (o >= GOF(XMM13) && o+sz <= GOF(XMM13)+SZB(XMM13)) return GOF(XMM13);
533 if (o >= GOF(XMM14) && o+sz <= GOF(XMM14)+SZB(XMM14)) return GOF(XMM14);
534 if (o >= GOF(XMM15) && o+sz <= GOF(XMM15)+SZB(XMM15)) return GOF(XMM15);
535
sewardjf1a483a2008-06-13 07:44:02 +0000536 /* MMX accesses to FP regs. Need to allow for 32-bit references
537 due to dirty helpers for frstor etc, which reference the entire
538 64-byte block in one go. */
539 if (o >= GOF(FPREG[0])
540 && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
541 if (o >= GOF(FPREG[1])
542 && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
543 if (o >= GOF(FPREG[2])
544 && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
545 if (o >= GOF(FPREG[3])
546 && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
547 if (o >= GOF(FPREG[4])
548 && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
549 if (o >= GOF(FPREG[5])
550 && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
551 if (o >= GOF(FPREG[6])
552 && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
553 if (o >= GOF(FPREG[7])
554 && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
sewardj7cf4e6b2008-05-01 20:24:26 +0000555
556 /* Map high halves of %RAX,%RCX,%RDX,%RBX to the whole register.
557 This is needed because the general handling of dirty helper
558 calls is done in 4 byte chunks. Hence we will see these.
559 Currently we only expect to see artefacts from CPUID. */
560 if (o == 4+ GOF(RAX) && sz == 4) return GOF(RAX);
561 if (o == 4+ GOF(RCX) && sz == 4) return GOF(RCX);
562 if (o == 4+ GOF(RDX) && sz == 4) return GOF(RDX);
563 if (o == 4+ GOF(RBX) && sz == 4) return GOF(RBX);
564
565 VG_(printf)("MC_(get_otrack_shadow_offset)(amd64)(off=%d,sz=%d)\n",
566 offset,szB);
567 tl_assert(0);
568# undef GOF
569# undef SZB
570
571 /* --------------------- x86 --------------------- */
572
573# elif defined(VGA_x86)
574
575# define GOF(_fieldname) \
576 (offsetof(VexGuestX86State,guest_##_fieldname))
577# define SZB(_fieldname) \
578 (sizeof(((VexGuestX86State*)0)->guest_##_fieldname))
579
580 Int o = offset;
581 Int sz = szB;
582 Bool is124 = sz == 4 || sz == 2 || sz == 1;
583 tl_assert(sz > 0);
584 tl_assert(host_is_little_endian());
585
586 if (o == GOF(EAX) && is124) return o;
587 if (o == GOF(ECX) && is124) return o;
588 if (o == GOF(EDX) && is124) return o;
589 if (o == GOF(EBX) && is124) return o;
590 if (o == GOF(ESP) && is124) return o;
591 if (o == GOF(EBP) && is124) return o;
592 if (o == GOF(ESI) && is124) return o;
593 if (o == GOF(EDI) && is124) return o;
594
595 if (o == GOF(CC_DEP1) && sz == 4) return o;
596 if (o == GOF(CC_DEP2) && sz == 4) return o;
597
598 if (o == GOF(CC_OP) && sz == 4) return -1; /* slot used for %AH */
599 if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot used for %BH */
600 if (o == GOF(DFLAG) && sz == 4) return -1; /* slot used for %CH */
601 if (o == GOF(EIP) && sz == 4) return -1; /* slot unused */
sewardj71633b12009-03-30 02:27:29 +0000602 if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000603 if (o == GOF(IDFLAG) && sz == 4) return -1; /* slot used for %DH */
604 if (o == GOF(ACFLAG) && sz == 4) return -1; /* slot unused */
sewardj105e69c2008-05-09 23:26:19 +0000605 if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
606 if (o == GOF(TILEN) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000607
608 /* Treat %AH, %BH, %CH, %DH as independent registers. To do this
609 requires finding 4 unused 32-bit slots in the second-shadow
610 guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG since none
611 of those are tracked. */
612 tl_assert(SZB(CC_OP) == 4);
613 tl_assert(SZB(CC_NDEP) == 4);
614 tl_assert(SZB(DFLAG) == 4);
615 tl_assert(SZB(IDFLAG) == 4);
616 if (o == 1+ GOF(EAX) && szB == 1) return GOF(CC_OP);
617 if (o == 1+ GOF(EBX) && szB == 1) return GOF(CC_NDEP);
618 if (o == 1+ GOF(ECX) && szB == 1) return GOF(DFLAG);
619 if (o == 1+ GOF(EDX) && szB == 1) return GOF(IDFLAG);
620
621 /* skip XMM and FP admin stuff */
622 if (o == GOF(SSEROUND) && szB == 4) return -1;
623 if (o == GOF(FTOP) && szB == 4) return -1;
624 if (o == GOF(FPROUND) && szB == 4) return -1;
625 if (o == GOF(EMWARN) && szB == 4) return -1;
626 if (o == GOF(FC3210) && szB == 4) return -1;
627
628 /* XMM registers */
629 if (o >= GOF(XMM0) && o+sz <= GOF(XMM0)+SZB(XMM0)) return GOF(XMM0);
630 if (o >= GOF(XMM1) && o+sz <= GOF(XMM1)+SZB(XMM1)) return GOF(XMM1);
631 if (o >= GOF(XMM2) && o+sz <= GOF(XMM2)+SZB(XMM2)) return GOF(XMM2);
632 if (o >= GOF(XMM3) && o+sz <= GOF(XMM3)+SZB(XMM3)) return GOF(XMM3);
633 if (o >= GOF(XMM4) && o+sz <= GOF(XMM4)+SZB(XMM4)) return GOF(XMM4);
634 if (o >= GOF(XMM5) && o+sz <= GOF(XMM5)+SZB(XMM5)) return GOF(XMM5);
635 if (o >= GOF(XMM6) && o+sz <= GOF(XMM6)+SZB(XMM6)) return GOF(XMM6);
636 if (o >= GOF(XMM7) && o+sz <= GOF(XMM7)+SZB(XMM7)) return GOF(XMM7);
637
638 /* MMX accesses to FP regs. Need to allow for 32-bit references
639 due to dirty helpers for frstor etc, which reference the entire
640 64-byte block in one go. */
641 if (o >= GOF(FPREG[0])
642 && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
643 if (o >= GOF(FPREG[1])
644 && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
645 if (o >= GOF(FPREG[2])
646 && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
647 if (o >= GOF(FPREG[3])
648 && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
649 if (o >= GOF(FPREG[4])
650 && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
651 if (o >= GOF(FPREG[5])
652 && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
653 if (o >= GOF(FPREG[6])
654 && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
655 if (o >= GOF(FPREG[7])
656 && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
657
658 /* skip %GS and other segment related stuff. We could shadow
659 guest_LDT and guest_GDT, although it seems pointless.
660 guest_CS .. guest_SS are too small to shadow directly and it
661 also seems pointless to shadow them indirectly (that is, in
662 the style of %AH .. %DH). */
663 if (o == GOF(CS) && sz == 2) return -1;
664 if (o == GOF(DS) && sz == 2) return -1;
665 if (o == GOF(ES) && sz == 2) return -1;
666 if (o == GOF(FS) && sz == 2) return -1;
667 if (o == GOF(GS) && sz == 2) return -1;
668 if (o == GOF(SS) && sz == 2) return -1;
669 if (o == GOF(LDT) && sz == 4) return -1;
670 if (o == GOF(GDT) && sz == 4) return -1;
671
672 VG_(printf)("MC_(get_otrack_shadow_offset)(x86)(off=%d,sz=%d)\n",
673 offset,szB);
674 tl_assert(0);
675# undef GOF
676# undef SZB
677
678# else
679# error "FIXME: not implemented for this architecture"
680# endif
681}
682
683
684/* Let 'arr' describe an indexed reference to a guest state section
685 (guest state array).
686
687 This function returns the corresponding guest state type to be used
688 when indexing the corresponding array in the second shadow (origin
689 tracking) area. If the array is not to be origin-tracked, return
690 Ity_INVALID.
691
692 This function must agree with MC_(get_otrack_shadow_offset) above.
693 See comments at the start of MC_(get_otrack_shadow_offset).
694*/
695IRType MC_(get_otrack_reg_array_equiv_int_type) ( IRRegArray* arr )
696{
697 /* -------------------- ppc64 -------------------- */
698# if defined(VGA_ppc64)
699 /* The redir stack. */
700 if (arr->base == offsetof(VexGuestPPC64State,guest_REDIR_STACK[0])
701 && arr->elemTy == Ity_I64
702 && arr->nElems == VEX_GUEST_PPC64_REDIR_STACK_SIZE)
703 return Ity_I64;
704
705 VG_(printf)("get_reg_array_equiv_int_type(ppc64): unhandled: ");
706 ppIRRegArray(arr);
707 VG_(printf)("\n");
708 tl_assert(0);
709
710 /* -------------------- ppc32 -------------------- */
711# elif defined(VGA_ppc32)
712 /* The redir stack. */
713 if (arr->base == offsetof(VexGuestPPC32State,guest_REDIR_STACK[0])
714 && arr->elemTy == Ity_I32
715 && arr->nElems == VEX_GUEST_PPC32_REDIR_STACK_SIZE)
716 return Ity_I32;
717
718 VG_(printf)("get_reg_array_equiv_int_type(ppc32): unhandled: ");
719 ppIRRegArray(arr);
720 VG_(printf)("\n");
721 tl_assert(0);
722
723 /* -------------------- amd64 -------------------- */
724# elif defined(VGA_amd64)
725 /* Ignore the FP tag array - pointless to shadow, and in any case
726 the elements are too small */
727 if (arr->base == offsetof(VexGuestAMD64State,guest_FPTAG)
728 && arr->elemTy == Ity_I8 && arr->nElems == 8)
729 return Ity_INVALID;
730
731 /* The FP register array */
732 if (arr->base == offsetof(VexGuestAMD64State,guest_FPREG[0])
733 && arr->elemTy == Ity_F64 && arr->nElems == 8)
734 return Ity_I64;
735
736 VG_(printf)("get_reg_array_equiv_int_type(amd64): unhandled: ");
737 ppIRRegArray(arr);
738 VG_(printf)("\n");
739 tl_assert(0);
740
741 /* --------------------- x86 --------------------- */
742# elif defined(VGA_x86)
743 /* Ignore the FP tag array - pointless to shadow, and in any case
744 the elements are too small */
745 if (arr->base == offsetof(VexGuestX86State,guest_FPTAG)
746 && arr->elemTy == Ity_I8 && arr->nElems == 8)
747 return Ity_INVALID;
748
749 /* The FP register array */
750 if (arr->base == offsetof(VexGuestX86State,guest_FPREG[0])
751 && arr->elemTy == Ity_F64 && arr->nElems == 8)
752 return Ity_I64;
753
754 VG_(printf)("get_reg_array_equiv_int_type(x86): unhandled: ");
755 ppIRRegArray(arr);
756 VG_(printf)("\n");
757 tl_assert(0);
758
759# else
760# error "FIXME: not implemented for this architecture"
761# endif
762}
763
764
765/*--------------------------------------------------------------------*/
766/*--- end mc_machine.c ---*/
767/*--------------------------------------------------------------------*/