blob: 0c72b2dd903ff00103ac1eb67823a54078393cef [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
sewardjf34eb492011-04-15 11:57:05 +0000203 // With ISA 2.06, the "Vector-Scalar Floating-point" category
204 // provides facilities to support vector and scalar binary floating-
205 // point operations. A unified register file is an integral part
206 // of this new facility, combining floating point and vector registers
207 // using a 64x128-bit vector. These are referred to as VSR[0..63].
208 // The floating point registers are now mapped into double word element 0
209 // of VSR[0..31]. The 32x128-bit vector registers defined by the "Vector
210 // Facility [Category: Vector]" are now mapped to VSR[32..63].
211
212 // Floating point registers . . .
213 if (o == GOF(VSR0) && sz == 8) return o;
214 if (o == GOF(VSR1) && sz == 8) return o;
215 if (o == GOF(VSR2) && sz == 8) return o;
216 if (o == GOF(VSR3) && sz == 8) return o;
217 if (o == GOF(VSR4) && sz == 8) return o;
218 if (o == GOF(VSR5) && sz == 8) return o;
219 if (o == GOF(VSR6) && sz == 8) return o;
220 if (o == GOF(VSR7) && sz == 8) return o;
221 if (o == GOF(VSR8) && sz == 8) return o;
222 if (o == GOF(VSR9) && sz == 8) return o;
223 if (o == GOF(VSR10) && sz == 8) return o;
224 if (o == GOF(VSR11) && sz == 8) return o;
225 if (o == GOF(VSR12) && sz == 8) return o;
226 if (o == GOF(VSR13) && sz == 8) return o;
227 if (o == GOF(VSR14) && sz == 8) return o;
228 if (o == GOF(VSR15) && sz == 8) return o;
229 if (o == GOF(VSR16) && sz == 8) return o;
230 if (o == GOF(VSR17) && sz == 8) return o;
231 if (o == GOF(VSR18) && sz == 8) return o;
232 if (o == GOF(VSR19) && sz == 8) return o;
233 if (o == GOF(VSR20) && sz == 8) return o;
234 if (o == GOF(VSR21) && sz == 8) return o;
235 if (o == GOF(VSR22) && sz == 8) return o;
236 if (o == GOF(VSR23) && sz == 8) return o;
237 if (o == GOF(VSR24) && sz == 8) return o;
238 if (o == GOF(VSR25) && sz == 8) return o;
239 if (o == GOF(VSR26) && sz == 8) return o;
240 if (o == GOF(VSR27) && sz == 8) return o;
241 if (o == GOF(VSR28) && sz == 8) return o;
242 if (o == GOF(VSR29) && sz == 8) return o;
243 if (o == GOF(VSR30) && sz == 8) return o;
244 if (o == GOF(VSR31) && sz == 8) return o;
sewardj7cf4e6b2008-05-01 20:24:26 +0000245
246 /* For the various byte sized XER/CR pieces, use offset 8
sewardjf34eb492011-04-15 11:57:05 +0000247 in VSR0 .. VSR19. */
248 tl_assert(SZB(VSR0) == 16);
249 if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VSR0);
250 if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VSR1);
251 if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VSR2);
252 if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VSR3);
sewardj7cf4e6b2008-05-01 20:24:26 +0000253
sewardjf34eb492011-04-15 11:57:05 +0000254 if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VSR4);
255 if (o == GOF(CR0_0) && sz == 1) return 8 +GOF(VSR5);
256 if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VSR6);
257 if (o == GOF(CR1_0) && sz == 1) return 8 +GOF(VSR7);
258 if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VSR8);
259 if (o == GOF(CR2_0) && sz == 1) return 8 +GOF(VSR9);
260 if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VSR10);
261 if (o == GOF(CR3_0) && sz == 1) return 8 +GOF(VSR11);
262 if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VSR12);
263 if (o == GOF(CR4_0) && sz == 1) return 8 +GOF(VSR13);
264 if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VSR14);
265 if (o == GOF(CR5_0) && sz == 1) return 8 +GOF(VSR15);
266 if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VSR16);
267 if (o == GOF(CR6_0) && sz == 1) return 8 +GOF(VSR17);
268 if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VSR18);
269 if (o == GOF(CR7_0) && sz == 1) return 8 +GOF(VSR19);
sewardj7cf4e6b2008-05-01 20:24:26 +0000270
sewardjf34eb492011-04-15 11:57:05 +0000271 /* Vector registers .. use offset 0 in VSR0 .. VSR63. */
272 if (o >= GOF(VSR0) && o+sz <= GOF(VSR0) +SZB(VSR0)) return 0+ GOF(VSR0);
273 if (o >= GOF(VSR1) && o+sz <= GOF(VSR1) +SZB(VSR1)) return 0+ GOF(VSR1);
274 if (o >= GOF(VSR2) && o+sz <= GOF(VSR2) +SZB(VSR2)) return 0+ GOF(VSR2);
275 if (o >= GOF(VSR3) && o+sz <= GOF(VSR3) +SZB(VSR3)) return 0+ GOF(VSR3);
276 if (o >= GOF(VSR4) && o+sz <= GOF(VSR4) +SZB(VSR4)) return 0+ GOF(VSR4);
277 if (o >= GOF(VSR5) && o+sz <= GOF(VSR5) +SZB(VSR5)) return 0+ GOF(VSR5);
278 if (o >= GOF(VSR6) && o+sz <= GOF(VSR6) +SZB(VSR6)) return 0+ GOF(VSR6);
279 if (o >= GOF(VSR7) && o+sz <= GOF(VSR7) +SZB(VSR7)) return 0+ GOF(VSR7);
280 if (o >= GOF(VSR8) && o+sz <= GOF(VSR8) +SZB(VSR8)) return 0+ GOF(VSR8);
281 if (o >= GOF(VSR9) && o+sz <= GOF(VSR9) +SZB(VSR9)) return 0+ GOF(VSR9);
282 if (o >= GOF(VSR10) && o+sz <= GOF(VSR10)+SZB(VSR10)) return 0+ GOF(VSR10);
283 if (o >= GOF(VSR11) && o+sz <= GOF(VSR11)+SZB(VSR11)) return 0+ GOF(VSR11);
284 if (o >= GOF(VSR12) && o+sz <= GOF(VSR12)+SZB(VSR12)) return 0+ GOF(VSR12);
285 if (o >= GOF(VSR13) && o+sz <= GOF(VSR13)+SZB(VSR13)) return 0+ GOF(VSR13);
286 if (o >= GOF(VSR14) && o+sz <= GOF(VSR14)+SZB(VSR14)) return 0+ GOF(VSR14);
287 if (o >= GOF(VSR15) && o+sz <= GOF(VSR15)+SZB(VSR15)) return 0+ GOF(VSR15);
288 if (o >= GOF(VSR16) && o+sz <= GOF(VSR16)+SZB(VSR16)) return 0+ GOF(VSR16);
289 if (o >= GOF(VSR17) && o+sz <= GOF(VSR17)+SZB(VSR17)) return 0+ GOF(VSR17);
290 if (o >= GOF(VSR18) && o+sz <= GOF(VSR18)+SZB(VSR18)) return 0+ GOF(VSR18);
291 if (o >= GOF(VSR19) && o+sz <= GOF(VSR19)+SZB(VSR19)) return 0+ GOF(VSR19);
292 if (o >= GOF(VSR20) && o+sz <= GOF(VSR20)+SZB(VSR20)) return 0+ GOF(VSR20);
293 if (o >= GOF(VSR21) && o+sz <= GOF(VSR21)+SZB(VSR21)) return 0+ GOF(VSR21);
294 if (o >= GOF(VSR22) && o+sz <= GOF(VSR22)+SZB(VSR22)) return 0+ GOF(VSR22);
295 if (o >= GOF(VSR23) && o+sz <= GOF(VSR23)+SZB(VSR23)) return 0+ GOF(VSR23);
296 if (o >= GOF(VSR24) && o+sz <= GOF(VSR24)+SZB(VSR24)) return 0+ GOF(VSR24);
297 if (o >= GOF(VSR25) && o+sz <= GOF(VSR25)+SZB(VSR25)) return 0+ GOF(VSR25);
298 if (o >= GOF(VSR26) && o+sz <= GOF(VSR26)+SZB(VSR26)) return 0+ GOF(VSR26);
299 if (o >= GOF(VSR27) && o+sz <= GOF(VSR27)+SZB(VSR27)) return 0+ GOF(VSR27);
300 if (o >= GOF(VSR28) && o+sz <= GOF(VSR28)+SZB(VSR28)) return 0+ GOF(VSR28);
301 if (o >= GOF(VSR29) && o+sz <= GOF(VSR29)+SZB(VSR29)) return 0+ GOF(VSR29);
302 if (o >= GOF(VSR30) && o+sz <= GOF(VSR30)+SZB(VSR30)) return 0+ GOF(VSR30);
303 if (o >= GOF(VSR31) && o+sz <= GOF(VSR31)+SZB(VSR31)) return 0+ GOF(VSR31);
304 if (o >= GOF(VSR32) && o+sz <= GOF(VSR32)+SZB(VSR32)) return 0+ GOF(VSR32);
305 if (o >= GOF(VSR33) && o+sz <= GOF(VSR33)+SZB(VSR33)) return 0+ GOF(VSR33);
306 if (o >= GOF(VSR34) && o+sz <= GOF(VSR34)+SZB(VSR34)) return 0+ GOF(VSR34);
307 if (o >= GOF(VSR35) && o+sz <= GOF(VSR35)+SZB(VSR35)) return 0+ GOF(VSR35);
308 if (o >= GOF(VSR36) && o+sz <= GOF(VSR36)+SZB(VSR36)) return 0+ GOF(VSR36);
309 if (o >= GOF(VSR37) && o+sz <= GOF(VSR37)+SZB(VSR37)) return 0+ GOF(VSR37);
310 if (o >= GOF(VSR38) && o+sz <= GOF(VSR38)+SZB(VSR38)) return 0+ GOF(VSR38);
311 if (o >= GOF(VSR39) && o+sz <= GOF(VSR39)+SZB(VSR39)) return 0+ GOF(VSR39);
312 if (o >= GOF(VSR40) && o+sz <= GOF(VSR40)+SZB(VSR40)) return 0+ GOF(VSR40);
313 if (o >= GOF(VSR41) && o+sz <= GOF(VSR41)+SZB(VSR41)) return 0+ GOF(VSR41);
314 if (o >= GOF(VSR42) && o+sz <= GOF(VSR42)+SZB(VSR42)) return 0+ GOF(VSR42);
315 if (o >= GOF(VSR43) && o+sz <= GOF(VSR43)+SZB(VSR43)) return 0+ GOF(VSR43);
316 if (o >= GOF(VSR44) && o+sz <= GOF(VSR44)+SZB(VSR44)) return 0+ GOF(VSR44);
317 if (o >= GOF(VSR45) && o+sz <= GOF(VSR45)+SZB(VSR45)) return 0+ GOF(VSR45);
318 if (o >= GOF(VSR46) && o+sz <= GOF(VSR46)+SZB(VSR46)) return 0+ GOF(VSR46);
319 if (o >= GOF(VSR47) && o+sz <= GOF(VSR47)+SZB(VSR47)) return 0+ GOF(VSR47);
320 if (o >= GOF(VSR48) && o+sz <= GOF(VSR48)+SZB(VSR48)) return 0+ GOF(VSR48);
321 if (o >= GOF(VSR49) && o+sz <= GOF(VSR49)+SZB(VSR49)) return 0+ GOF(VSR49);
322 if (o >= GOF(VSR50) && o+sz <= GOF(VSR50)+SZB(VSR50)) return 0+ GOF(VSR50);
323 if (o >= GOF(VSR51) && o+sz <= GOF(VSR51)+SZB(VSR51)) return 0+ GOF(VSR51);
324 if (o >= GOF(VSR52) && o+sz <= GOF(VSR52)+SZB(VSR52)) return 0+ GOF(VSR52);
325 if (o >= GOF(VSR53) && o+sz <= GOF(VSR53)+SZB(VSR53)) return 0+ GOF(VSR53);
326 if (o >= GOF(VSR54) && o+sz <= GOF(VSR54)+SZB(VSR54)) return 0+ GOF(VSR54);
327 if (o >= GOF(VSR55) && o+sz <= GOF(VSR55)+SZB(VSR55)) return 0+ GOF(VSR55);
328 if (o >= GOF(VSR56) && o+sz <= GOF(VSR56)+SZB(VSR56)) return 0+ GOF(VSR56);
329 if (o >= GOF(VSR57) && o+sz <= GOF(VSR57)+SZB(VSR57)) return 0+ GOF(VSR57);
330 if (o >= GOF(VSR58) && o+sz <= GOF(VSR58)+SZB(VSR58)) return 0+ GOF(VSR58);
331 if (o >= GOF(VSR59) && o+sz <= GOF(VSR59)+SZB(VSR59)) return 0+ GOF(VSR59);
332 if (o >= GOF(VSR60) && o+sz <= GOF(VSR60)+SZB(VSR60)) return 0+ GOF(VSR60);
333 if (o >= GOF(VSR61) && o+sz <= GOF(VSR61)+SZB(VSR61)) return 0+ GOF(VSR61);
334 if (o >= GOF(VSR62) && o+sz <= GOF(VSR62)+SZB(VSR62)) return 0+ GOF(VSR62);
335 if (o >= GOF(VSR63) && o+sz <= GOF(VSR63)+SZB(VSR63)) return 0+ GOF(VSR63);
sewardj7cf4e6b2008-05-01 20:24:26 +0000336
337 VG_(printf)("MC_(get_otrack_shadow_offset)(ppc64)(off=%d,sz=%d)\n",
338 offset,szB);
339 tl_assert(0);
340# undef GOF
341# undef SZB
342
343 /* -------------------- ppc32 -------------------- */
344
345# elif defined(VGA_ppc32)
346
347# define GOF(_fieldname) \
348 (offsetof(VexGuestPPC32State,guest_##_fieldname))
349# define SZB(_fieldname) \
350 (sizeof(((VexGuestPPC32State*)0)->guest_##_fieldname))
351 Int o = offset;
352 Int sz = szB;
353 tl_assert(sz > 0);
354 tl_assert(host_is_big_endian());
355
356 if (o == GOF(GPR0) && sz == 4) return o;
357 if (o == GOF(GPR1) && sz == 4) return o;
358 if (o == GOF(GPR2) && sz == 4) return o;
359 if (o == GOF(GPR3) && sz == 4) return o;
360 if (o == GOF(GPR4) && sz == 4) return o;
361 if (o == GOF(GPR5) && sz == 4) return o;
362 if (o == GOF(GPR6) && sz == 4) return o;
363 if (o == GOF(GPR7) && sz == 4) return o;
364 if (o == GOF(GPR8) && sz == 4) return o;
365 if (o == GOF(GPR9) && sz == 4) return o;
366 if (o == GOF(GPR10) && sz == 4) return o;
367 if (o == GOF(GPR11) && sz == 4) return o;
368 if (o == GOF(GPR12) && sz == 4) return o;
369 if (o == GOF(GPR13) && sz == 4) return o;
370 if (o == GOF(GPR14) && sz == 4) return o;
371 if (o == GOF(GPR15) && sz == 4) return o;
372 if (o == GOF(GPR16) && sz == 4) return o;
373 if (o == GOF(GPR17) && sz == 4) return o;
374 if (o == GOF(GPR18) && sz == 4) return o;
375 if (o == GOF(GPR19) && sz == 4) return o;
376 if (o == GOF(GPR20) && sz == 4) return o;
377 if (o == GOF(GPR21) && sz == 4) return o;
378 if (o == GOF(GPR22) && sz == 4) return o;
379 if (o == GOF(GPR23) && sz == 4) return o;
380 if (o == GOF(GPR24) && sz == 4) return o;
381 if (o == GOF(GPR25) && sz == 4) return o;
382 if (o == GOF(GPR26) && sz == 4) return o;
383 if (o == GOF(GPR27) && sz == 4) return o;
384 if (o == GOF(GPR28) && sz == 4) return o;
385 if (o == GOF(GPR29) && sz == 4) return o;
386 if (o == GOF(GPR30) && sz == 4) return o;
387 if (o == GOF(GPR31) && sz == 4) return o;
388
389 if (o == GOF(LR) && sz == 4) return o;
390 if (o == GOF(CTR) && sz == 4) return o;
391
392 if (o == GOF(CIA) && sz == 4) return -1;
sewardj71633b12009-03-30 02:27:29 +0000393 if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000394 if (o == GOF(FPROUND) && sz == 4) return -1;
sewardj3b507352009-02-14 15:28:46 +0000395 if (o == GOF(VRSAVE) && sz == 4) return -1;
sewardj7cf4e6b2008-05-01 20:24:26 +0000396 if (o == GOF(EMWARN) && sz == 4) return -1;
397 if (o == GOF(TISTART) && sz == 4) return -1;
398 if (o == GOF(TILEN) && sz == 4) return -1;
399 if (o == GOF(VSCR) && sz == 4) return -1;
400 if (o == GOF(REDIR_SP) && sz == 4) return -1;
401 if (o == GOF(SPRG3_RO) && sz == 4) return -1;
402
sewardjf34eb492011-04-15 11:57:05 +0000403 // With ISA 2.06, the "Vector-Scalar Floating-point" category
404 // provides facilities to support vector and scalar binary floating-
405 // point operations. A unified register file is an integral part
406 // of this new facility, combining floating point and vector registers
407 // using a 64x128-bit vector. These are referred to as VSR[0..63].
408 // The floating point registers are now mapped into double word element 0
409 // of VSR[0..31]. The 32x128-bit vector registers defined by the "Vector
410 // Facility [Category: Vector]" are now mapped to VSR[32..63].
411
412 // Floating point registers . . .
413 if (o == GOF(VSR0) && sz == 8) return o;
414 if (o == GOF(VSR1) && sz == 8) return o;
415 if (o == GOF(VSR2) && sz == 8) return o;
416 if (o == GOF(VSR3) && sz == 8) return o;
417 if (o == GOF(VSR4) && sz == 8) return o;
418 if (o == GOF(VSR5) && sz == 8) return o;
419 if (o == GOF(VSR6) && sz == 8) return o;
420 if (o == GOF(VSR7) && sz == 8) return o;
421 if (o == GOF(VSR8) && sz == 8) return o;
422 if (o == GOF(VSR9) && sz == 8) return o;
423 if (o == GOF(VSR10) && sz == 8) return o;
424 if (o == GOF(VSR11) && sz == 8) return o;
425 if (o == GOF(VSR12) && sz == 8) return o;
426 if (o == GOF(VSR13) && sz == 8) return o;
427 if (o == GOF(VSR14) && sz == 8) return o;
428 if (o == GOF(VSR15) && sz == 8) return o;
429 if (o == GOF(VSR16) && sz == 8) return o;
430 if (o == GOF(VSR17) && sz == 8) return o;
431 if (o == GOF(VSR18) && sz == 8) return o;
432 if (o == GOF(VSR19) && sz == 8) return o;
433 if (o == GOF(VSR20) && sz == 8) return o;
434 if (o == GOF(VSR21) && sz == 8) return o;
435 if (o == GOF(VSR22) && sz == 8) return o;
436 if (o == GOF(VSR23) && sz == 8) return o;
437 if (o == GOF(VSR24) && sz == 8) return o;
438 if (o == GOF(VSR25) && sz == 8) return o;
439 if (o == GOF(VSR26) && sz == 8) return o;
440 if (o == GOF(VSR27) && sz == 8) return o;
441 if (o == GOF(VSR28) && sz == 8) return o;
442 if (o == GOF(VSR29) && sz == 8) return o;
443 if (o == GOF(VSR30) && sz == 8) return o;
444 if (o == GOF(VSR31) && sz == 8) return o;
sewardj7cf4e6b2008-05-01 20:24:26 +0000445
446 /* For the various byte sized XER/CR pieces, use offset 8
sewardjf34eb492011-04-15 11:57:05 +0000447 in VSR0 .. VSR19. */
448 tl_assert(SZB(VSR0) == 16);
449 if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VSR0);
450 if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VSR1);
451 if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VSR2);
452 if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VSR3);
sewardj7cf4e6b2008-05-01 20:24:26 +0000453
sewardjf34eb492011-04-15 11:57:05 +0000454 if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VSR4);
455 if (o == GOF(CR0_0) && sz == 1) return 8 +GOF(VSR5);
456 if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VSR6);
457 if (o == GOF(CR1_0) && sz == 1) return 8 +GOF(VSR7);
458 if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VSR8);
459 if (o == GOF(CR2_0) && sz == 1) return 8 +GOF(VSR9);
460 if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VSR10);
461 if (o == GOF(CR3_0) && sz == 1) return 8 +GOF(VSR11);
462 if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VSR12);
463 if (o == GOF(CR4_0) && sz == 1) return 8 +GOF(VSR13);
464 if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VSR14);
465 if (o == GOF(CR5_0) && sz == 1) return 8 +GOF(VSR15);
466 if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VSR16);
467 if (o == GOF(CR6_0) && sz == 1) return 8 +GOF(VSR17);
468 if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VSR18);
469 if (o == GOF(CR7_0) && sz == 1) return 8 +GOF(VSR19);
sewardj7cf4e6b2008-05-01 20:24:26 +0000470
sewardjf34eb492011-04-15 11:57:05 +0000471 /* Vector registers .. use offset 0 in VSR0 .. VSR63. */
472 if (o >= GOF(VSR0) && o+sz <= GOF(VSR0) +SZB(VSR0)) return 0+ GOF(VSR0);
473 if (o >= GOF(VSR1) && o+sz <= GOF(VSR1) +SZB(VSR1)) return 0+ GOF(VSR1);
474 if (o >= GOF(VSR2) && o+sz <= GOF(VSR2) +SZB(VSR2)) return 0+ GOF(VSR2);
475 if (o >= GOF(VSR3) && o+sz <= GOF(VSR3) +SZB(VSR3)) return 0+ GOF(VSR3);
476 if (o >= GOF(VSR4) && o+sz <= GOF(VSR4) +SZB(VSR4)) return 0+ GOF(VSR4);
477 if (o >= GOF(VSR5) && o+sz <= GOF(VSR5) +SZB(VSR5)) return 0+ GOF(VSR5);
478 if (o >= GOF(VSR6) && o+sz <= GOF(VSR6) +SZB(VSR6)) return 0+ GOF(VSR6);
479 if (o >= GOF(VSR7) && o+sz <= GOF(VSR7) +SZB(VSR7)) return 0+ GOF(VSR7);
480 if (o >= GOF(VSR8) && o+sz <= GOF(VSR8) +SZB(VSR8)) return 0+ GOF(VSR8);
481 if (o >= GOF(VSR9) && o+sz <= GOF(VSR9) +SZB(VSR9)) return 0+ GOF(VSR9);
482 if (o >= GOF(VSR10) && o+sz <= GOF(VSR10)+SZB(VSR10)) return 0+ GOF(VSR10);
483 if (o >= GOF(VSR11) && o+sz <= GOF(VSR11)+SZB(VSR11)) return 0+ GOF(VSR11);
484 if (o >= GOF(VSR12) && o+sz <= GOF(VSR12)+SZB(VSR12)) return 0+ GOF(VSR12);
485 if (o >= GOF(VSR13) && o+sz <= GOF(VSR13)+SZB(VSR13)) return 0+ GOF(VSR13);
486 if (o >= GOF(VSR14) && o+sz <= GOF(VSR14)+SZB(VSR14)) return 0+ GOF(VSR14);
487 if (o >= GOF(VSR15) && o+sz <= GOF(VSR15)+SZB(VSR15)) return 0+ GOF(VSR15);
488 if (o >= GOF(VSR16) && o+sz <= GOF(VSR16)+SZB(VSR16)) return 0+ GOF(VSR16);
489 if (o >= GOF(VSR17) && o+sz <= GOF(VSR17)+SZB(VSR17)) return 0+ GOF(VSR17);
490 if (o >= GOF(VSR18) && o+sz <= GOF(VSR18)+SZB(VSR18)) return 0+ GOF(VSR18);
491 if (o >= GOF(VSR19) && o+sz <= GOF(VSR19)+SZB(VSR19)) return 0+ GOF(VSR19);
492 if (o >= GOF(VSR20) && o+sz <= GOF(VSR20)+SZB(VSR20)) return 0+ GOF(VSR20);
493 if (o >= GOF(VSR21) && o+sz <= GOF(VSR21)+SZB(VSR21)) return 0+ GOF(VSR21);
494 if (o >= GOF(VSR22) && o+sz <= GOF(VSR22)+SZB(VSR22)) return 0+ GOF(VSR22);
495 if (o >= GOF(VSR23) && o+sz <= GOF(VSR23)+SZB(VSR23)) return 0+ GOF(VSR23);
496 if (o >= GOF(VSR24) && o+sz <= GOF(VSR24)+SZB(VSR24)) return 0+ GOF(VSR24);
497 if (o >= GOF(VSR25) && o+sz <= GOF(VSR25)+SZB(VSR25)) return 0+ GOF(VSR25);
498 if (o >= GOF(VSR26) && o+sz <= GOF(VSR26)+SZB(VSR26)) return 0+ GOF(VSR26);
499 if (o >= GOF(VSR27) && o+sz <= GOF(VSR27)+SZB(VSR27)) return 0+ GOF(VSR27);
500 if (o >= GOF(VSR28) && o+sz <= GOF(VSR28)+SZB(VSR28)) return 0+ GOF(VSR28);
501 if (o >= GOF(VSR29) && o+sz <= GOF(VSR29)+SZB(VSR29)) return 0+ GOF(VSR29);
502 if (o >= GOF(VSR30) && o+sz <= GOF(VSR30)+SZB(VSR30)) return 0+ GOF(VSR30);
503 if (o >= GOF(VSR31) && o+sz <= GOF(VSR31)+SZB(VSR31)) return 0+ GOF(VSR31);
504 if (o >= GOF(VSR32) && o+sz <= GOF(VSR32)+SZB(VSR32)) return 0+ GOF(VSR32);
505 if (o >= GOF(VSR33) && o+sz <= GOF(VSR33)+SZB(VSR33)) return 0+ GOF(VSR33);
506 if (o >= GOF(VSR34) && o+sz <= GOF(VSR34)+SZB(VSR34)) return 0+ GOF(VSR34);
507 if (o >= GOF(VSR35) && o+sz <= GOF(VSR35)+SZB(VSR35)) return 0+ GOF(VSR35);
508 if (o >= GOF(VSR36) && o+sz <= GOF(VSR36)+SZB(VSR36)) return 0+ GOF(VSR36);
509 if (o >= GOF(VSR37) && o+sz <= GOF(VSR37)+SZB(VSR37)) return 0+ GOF(VSR37);
510 if (o >= GOF(VSR38) && o+sz <= GOF(VSR38)+SZB(VSR38)) return 0+ GOF(VSR38);
511 if (o >= GOF(VSR39) && o+sz <= GOF(VSR39)+SZB(VSR39)) return 0+ GOF(VSR39);
512 if (o >= GOF(VSR40) && o+sz <= GOF(VSR40)+SZB(VSR40)) return 0+ GOF(VSR40);
513 if (o >= GOF(VSR41) && o+sz <= GOF(VSR41)+SZB(VSR41)) return 0+ GOF(VSR41);
514 if (o >= GOF(VSR42) && o+sz <= GOF(VSR42)+SZB(VSR42)) return 0+ GOF(VSR42);
515 if (o >= GOF(VSR43) && o+sz <= GOF(VSR43)+SZB(VSR43)) return 0+ GOF(VSR43);
516 if (o >= GOF(VSR44) && o+sz <= GOF(VSR44)+SZB(VSR44)) return 0+ GOF(VSR44);
517 if (o >= GOF(VSR45) && o+sz <= GOF(VSR45)+SZB(VSR45)) return 0+ GOF(VSR45);
518 if (o >= GOF(VSR46) && o+sz <= GOF(VSR46)+SZB(VSR46)) return 0+ GOF(VSR46);
519 if (o >= GOF(VSR47) && o+sz <= GOF(VSR47)+SZB(VSR47)) return 0+ GOF(VSR47);
520 if (o >= GOF(VSR48) && o+sz <= GOF(VSR48)+SZB(VSR48)) return 0+ GOF(VSR48);
521 if (o >= GOF(VSR49) && o+sz <= GOF(VSR49)+SZB(VSR49)) return 0+ GOF(VSR49);
522 if (o >= GOF(VSR50) && o+sz <= GOF(VSR50)+SZB(VSR50)) return 0+ GOF(VSR50);
523 if (o >= GOF(VSR51) && o+sz <= GOF(VSR51)+SZB(VSR51)) return 0+ GOF(VSR51);
524 if (o >= GOF(VSR52) && o+sz <= GOF(VSR52)+SZB(VSR52)) return 0+ GOF(VSR52);
525 if (o >= GOF(VSR53) && o+sz <= GOF(VSR53)+SZB(VSR53)) return 0+ GOF(VSR53);
526 if (o >= GOF(VSR54) && o+sz <= GOF(VSR54)+SZB(VSR54)) return 0+ GOF(VSR54);
527 if (o >= GOF(VSR55) && o+sz <= GOF(VSR55)+SZB(VSR55)) return 0+ GOF(VSR55);
528 if (o >= GOF(VSR56) && o+sz <= GOF(VSR56)+SZB(VSR56)) return 0+ GOF(VSR56);
529 if (o >= GOF(VSR57) && o+sz <= GOF(VSR57)+SZB(VSR57)) return 0+ GOF(VSR57);
530 if (o >= GOF(VSR58) && o+sz <= GOF(VSR58)+SZB(VSR58)) return 0+ GOF(VSR58);
531 if (o >= GOF(VSR59) && o+sz <= GOF(VSR59)+SZB(VSR59)) return 0+ GOF(VSR59);
532 if (o >= GOF(VSR60) && o+sz <= GOF(VSR60)+SZB(VSR60)) return 0+ GOF(VSR60);
533 if (o >= GOF(VSR61) && o+sz <= GOF(VSR61)+SZB(VSR61)) return 0+ GOF(VSR61);
534 if (o >= GOF(VSR62) && o+sz <= GOF(VSR62)+SZB(VSR62)) return 0+ GOF(VSR62);
535 if (o >= GOF(VSR63) && o+sz <= GOF(VSR63)+SZB(VSR63)) return 0+ GOF(VSR63);
sewardj7cf4e6b2008-05-01 20:24:26 +0000536
537 VG_(printf)("MC_(get_otrack_shadow_offset)(ppc32)(off=%d,sz=%d)\n",
538 offset,szB);
539 tl_assert(0);
540# undef GOF
541# undef SZB
542
543 /* -------------------- amd64 -------------------- */
544
545# elif defined(VGA_amd64)
546
547# define GOF(_fieldname) \
548 (offsetof(VexGuestAMD64State,guest_##_fieldname))
549# define SZB(_fieldname) \
550 (sizeof(((VexGuestAMD64State*)0)->guest_##_fieldname))
551 Int o = offset;
552 Int sz = szB;
553 Bool is1248 = sz == 8 || sz == 4 || sz == 2 || sz == 1;
554 tl_assert(sz > 0);
555 tl_assert(host_is_little_endian());
556
557 if (o == GOF(RAX) && is1248) return o;
558 if (o == GOF(RCX) && is1248) return o;
559 if (o == GOF(RDX) && is1248) return o;
560 if (o == GOF(RBX) && is1248) return o;
561 if (o == GOF(RSP) && is1248) return o;
562 if (o == GOF(RBP) && is1248) return o;
563 if (o == GOF(RSI) && is1248) return o;
564 if (o == GOF(RDI) && is1248) return o;
565 if (o == GOF(R8) && is1248) return o;
566 if (o == GOF(R9) && is1248) return o;
567 if (o == GOF(R10) && is1248) return o;
568 if (o == GOF(R11) && is1248) return o;
569 if (o == GOF(R12) && is1248) return o;
570 if (o == GOF(R13) && is1248) return o;
571 if (o == GOF(R14) && is1248) return o;
572 if (o == GOF(R15) && is1248) return o;
573
574 if (o == GOF(CC_DEP1) && sz == 8) return o;
575 if (o == GOF(CC_DEP2) && sz == 8) return o;
576
577 if (o == GOF(CC_OP) && sz == 8) return -1; /* slot used for %AH */
578 if (o == GOF(CC_NDEP) && sz == 8) return -1; /* slot used for %BH */
579 if (o == GOF(DFLAG) && sz == 8) return -1; /* slot used for %CH */
580 if (o == GOF(RIP) && sz == 8) return -1; /* slot unused */
sewardj71633b12009-03-30 02:27:29 +0000581 if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000582 if (o == GOF(IDFLAG) && sz == 8) return -1; /* slot used for %DH */
sewardj65864932010-09-28 16:00:11 +0000583 if (o == GOF(ACFLAG) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000584 if (o == GOF(FS_ZERO) && sz == 8) return -1; /* slot unused */
njnf76d27a2009-05-28 01:53:07 +0000585 if (o == GOF(GS_0x60) && sz == 8) return -1; /* slot unused */
sewardj105e69c2008-05-09 23:26:19 +0000586 if (o == GOF(TISTART) && sz == 8) return -1; /* slot unused */
587 if (o == GOF(TILEN) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000588
589 /* Treat %AH, %BH, %CH, %DH as independent registers. To do this
590 requires finding 4 unused 32-bit slots in the second-shadow
591 guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG, since
592 none of those are tracked. */
593 tl_assert(SZB(CC_OP) == 8);
594 tl_assert(SZB(CC_NDEP) == 8);
595 tl_assert(SZB(IDFLAG) == 8);
596 tl_assert(SZB(DFLAG) == 8);
597
598 if (o == 1+ GOF(RAX) && szB == 1) return GOF(CC_OP);
599 if (o == 1+ GOF(RBX) && szB == 1) return GOF(CC_NDEP);
600 if (o == 1+ GOF(RCX) && szB == 1) return GOF(DFLAG);
601 if (o == 1+ GOF(RDX) && szB == 1) return GOF(IDFLAG);
602
603 /* skip XMM and FP admin stuff */
604 if (o == GOF(SSEROUND) && szB == 8) return -1;
605 if (o == GOF(FTOP) && szB == 4) return -1;
606 if (o == GOF(FPROUND) && szB == 8) return -1;
607 if (o == GOF(EMWARN) && szB == 4) return -1;
sewardj89ea7ab2008-05-27 16:08:24 +0000608 if (o == GOF(FC3210) && szB == 8) return -1;
sewardj7cf4e6b2008-05-01 20:24:26 +0000609
610 /* XMM registers */
611 if (o >= GOF(XMM0) && o+sz <= GOF(XMM0) +SZB(XMM0)) return GOF(XMM0);
612 if (o >= GOF(XMM1) && o+sz <= GOF(XMM1) +SZB(XMM1)) return GOF(XMM1);
613 if (o >= GOF(XMM2) && o+sz <= GOF(XMM2) +SZB(XMM2)) return GOF(XMM2);
614 if (o >= GOF(XMM3) && o+sz <= GOF(XMM3) +SZB(XMM3)) return GOF(XMM3);
615 if (o >= GOF(XMM4) && o+sz <= GOF(XMM4) +SZB(XMM4)) return GOF(XMM4);
616 if (o >= GOF(XMM5) && o+sz <= GOF(XMM5) +SZB(XMM5)) return GOF(XMM5);
617 if (o >= GOF(XMM6) && o+sz <= GOF(XMM6) +SZB(XMM6)) return GOF(XMM6);
618 if (o >= GOF(XMM7) && o+sz <= GOF(XMM7) +SZB(XMM7)) return GOF(XMM7);
619 if (o >= GOF(XMM8) && o+sz <= GOF(XMM8) +SZB(XMM8)) return GOF(XMM8);
620 if (o >= GOF(XMM9) && o+sz <= GOF(XMM9) +SZB(XMM9)) return GOF(XMM9);
621 if (o >= GOF(XMM10) && o+sz <= GOF(XMM10)+SZB(XMM10)) return GOF(XMM10);
622 if (o >= GOF(XMM11) && o+sz <= GOF(XMM11)+SZB(XMM11)) return GOF(XMM11);
623 if (o >= GOF(XMM12) && o+sz <= GOF(XMM12)+SZB(XMM12)) return GOF(XMM12);
624 if (o >= GOF(XMM13) && o+sz <= GOF(XMM13)+SZB(XMM13)) return GOF(XMM13);
625 if (o >= GOF(XMM14) && o+sz <= GOF(XMM14)+SZB(XMM14)) return GOF(XMM14);
626 if (o >= GOF(XMM15) && o+sz <= GOF(XMM15)+SZB(XMM15)) return GOF(XMM15);
sewardj565dc132010-08-06 08:01:47 +0000627 if (o >= GOF(XMM16) && o+sz <= GOF(XMM16)+SZB(XMM16)) return GOF(XMM16);
sewardj7cf4e6b2008-05-01 20:24:26 +0000628
sewardjf1a483a2008-06-13 07:44:02 +0000629 /* MMX accesses to FP regs. Need to allow for 32-bit references
630 due to dirty helpers for frstor etc, which reference the entire
631 64-byte block in one go. */
632 if (o >= GOF(FPREG[0])
633 && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
634 if (o >= GOF(FPREG[1])
635 && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
636 if (o >= GOF(FPREG[2])
637 && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
638 if (o >= GOF(FPREG[3])
639 && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
640 if (o >= GOF(FPREG[4])
641 && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
642 if (o >= GOF(FPREG[5])
643 && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
644 if (o >= GOF(FPREG[6])
645 && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
646 if (o >= GOF(FPREG[7])
647 && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
sewardj7cf4e6b2008-05-01 20:24:26 +0000648
649 /* Map high halves of %RAX,%RCX,%RDX,%RBX to the whole register.
650 This is needed because the general handling of dirty helper
651 calls is done in 4 byte chunks. Hence we will see these.
652 Currently we only expect to see artefacts from CPUID. */
653 if (o == 4+ GOF(RAX) && sz == 4) return GOF(RAX);
654 if (o == 4+ GOF(RCX) && sz == 4) return GOF(RCX);
655 if (o == 4+ GOF(RDX) && sz == 4) return GOF(RDX);
656 if (o == 4+ GOF(RBX) && sz == 4) return GOF(RBX);
657
658 VG_(printf)("MC_(get_otrack_shadow_offset)(amd64)(off=%d,sz=%d)\n",
659 offset,szB);
660 tl_assert(0);
661# undef GOF
662# undef SZB
663
664 /* --------------------- x86 --------------------- */
665
666# elif defined(VGA_x86)
667
668# define GOF(_fieldname) \
669 (offsetof(VexGuestX86State,guest_##_fieldname))
670# define SZB(_fieldname) \
671 (sizeof(((VexGuestX86State*)0)->guest_##_fieldname))
672
673 Int o = offset;
674 Int sz = szB;
675 Bool is124 = sz == 4 || sz == 2 || sz == 1;
676 tl_assert(sz > 0);
677 tl_assert(host_is_little_endian());
678
679 if (o == GOF(EAX) && is124) return o;
680 if (o == GOF(ECX) && is124) return o;
681 if (o == GOF(EDX) && is124) return o;
682 if (o == GOF(EBX) && is124) return o;
683 if (o == GOF(ESP) && is124) return o;
684 if (o == GOF(EBP) && is124) return o;
685 if (o == GOF(ESI) && is124) return o;
686 if (o == GOF(EDI) && is124) return o;
687
688 if (o == GOF(CC_DEP1) && sz == 4) return o;
689 if (o == GOF(CC_DEP2) && sz == 4) return o;
690
691 if (o == GOF(CC_OP) && sz == 4) return -1; /* slot used for %AH */
692 if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot used for %BH */
693 if (o == GOF(DFLAG) && sz == 4) return -1; /* slot used for %CH */
694 if (o == GOF(EIP) && sz == 4) return -1; /* slot unused */
sewardj71633b12009-03-30 02:27:29 +0000695 if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000696 if (o == GOF(IDFLAG) && sz == 4) return -1; /* slot used for %DH */
697 if (o == GOF(ACFLAG) && sz == 4) return -1; /* slot unused */
sewardj105e69c2008-05-09 23:26:19 +0000698 if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
699 if (o == GOF(TILEN) && sz == 4) return -1; /* slot unused */
sewardj5575f052011-01-28 00:53:37 +0000700 if (o == GOF(NRADDR) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000701
702 /* Treat %AH, %BH, %CH, %DH as independent registers. To do this
703 requires finding 4 unused 32-bit slots in the second-shadow
704 guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG since none
705 of those are tracked. */
706 tl_assert(SZB(CC_OP) == 4);
707 tl_assert(SZB(CC_NDEP) == 4);
708 tl_assert(SZB(DFLAG) == 4);
709 tl_assert(SZB(IDFLAG) == 4);
710 if (o == 1+ GOF(EAX) && szB == 1) return GOF(CC_OP);
711 if (o == 1+ GOF(EBX) && szB == 1) return GOF(CC_NDEP);
712 if (o == 1+ GOF(ECX) && szB == 1) return GOF(DFLAG);
713 if (o == 1+ GOF(EDX) && szB == 1) return GOF(IDFLAG);
714
715 /* skip XMM and FP admin stuff */
716 if (o == GOF(SSEROUND) && szB == 4) return -1;
717 if (o == GOF(FTOP) && szB == 4) return -1;
718 if (o == GOF(FPROUND) && szB == 4) return -1;
719 if (o == GOF(EMWARN) && szB == 4) return -1;
720 if (o == GOF(FC3210) && szB == 4) return -1;
721
722 /* XMM registers */
723 if (o >= GOF(XMM0) && o+sz <= GOF(XMM0)+SZB(XMM0)) return GOF(XMM0);
724 if (o >= GOF(XMM1) && o+sz <= GOF(XMM1)+SZB(XMM1)) return GOF(XMM1);
725 if (o >= GOF(XMM2) && o+sz <= GOF(XMM2)+SZB(XMM2)) return GOF(XMM2);
726 if (o >= GOF(XMM3) && o+sz <= GOF(XMM3)+SZB(XMM3)) return GOF(XMM3);
727 if (o >= GOF(XMM4) && o+sz <= GOF(XMM4)+SZB(XMM4)) return GOF(XMM4);
728 if (o >= GOF(XMM5) && o+sz <= GOF(XMM5)+SZB(XMM5)) return GOF(XMM5);
729 if (o >= GOF(XMM6) && o+sz <= GOF(XMM6)+SZB(XMM6)) return GOF(XMM6);
730 if (o >= GOF(XMM7) && o+sz <= GOF(XMM7)+SZB(XMM7)) return GOF(XMM7);
731
732 /* MMX accesses to FP regs. Need to allow for 32-bit references
733 due to dirty helpers for frstor etc, which reference the entire
734 64-byte block in one go. */
735 if (o >= GOF(FPREG[0])
736 && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
737 if (o >= GOF(FPREG[1])
738 && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
739 if (o >= GOF(FPREG[2])
740 && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
741 if (o >= GOF(FPREG[3])
742 && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
743 if (o >= GOF(FPREG[4])
744 && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
745 if (o >= GOF(FPREG[5])
746 && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
747 if (o >= GOF(FPREG[6])
748 && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
749 if (o >= GOF(FPREG[7])
750 && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
751
752 /* skip %GS and other segment related stuff. We could shadow
753 guest_LDT and guest_GDT, although it seems pointless.
754 guest_CS .. guest_SS are too small to shadow directly and it
755 also seems pointless to shadow them indirectly (that is, in
756 the style of %AH .. %DH). */
757 if (o == GOF(CS) && sz == 2) return -1;
758 if (o == GOF(DS) && sz == 2) return -1;
759 if (o == GOF(ES) && sz == 2) return -1;
760 if (o == GOF(FS) && sz == 2) return -1;
761 if (o == GOF(GS) && sz == 2) return -1;
762 if (o == GOF(SS) && sz == 2) return -1;
763 if (o == GOF(LDT) && sz == 4) return -1;
764 if (o == GOF(GDT) && sz == 4) return -1;
765
766 VG_(printf)("MC_(get_otrack_shadow_offset)(x86)(off=%d,sz=%d)\n",
767 offset,szB);
768 tl_assert(0);
769# undef GOF
770# undef SZB
771
sewardjb5b87402011-03-07 16:05:35 +0000772 /* -------------------- s390x -------------------- */
773
774# elif defined(VGA_s390x)
775# define GOF(_fieldname) \
776 (offsetof(VexGuestS390XState,guest_##_fieldname))
777 Int o = offset;
778 Int sz = szB;
779 tl_assert(sz > 0);
780 tl_assert(host_is_big_endian());
781
782 /* no matter what byte(s) we change, we have changed the full 8 byte value
783 and need to track this change for the whole register */
784 if (o >= GOF(r0) && sz <= 8 && o <= (GOF(r15) + 8 - sz))
785 return GOF(r0) + ((o-GOF(r0)) & -8) ;
786
787
788 /* fprs are accessed 4 or 8 byte at once. Again, we track that change for
789 the full register */
790 if ((sz == 8 || sz == 4) && o >= GOF(f0) && o <= GOF(f15)+8-sz)
791 return GOF(f0) + ((o-GOF(f0)) & -8) ;
792
793 /* access registers are accessed 4 bytes at once */
794 if (sz == 4 && o >= GOF(a0) && o <= GOF(a15))
795 return o;
796
797 /* we access the guest counter either fully or one of the 4byte words */
798 if (o == GOF(counter) && (sz == 8 || sz ==4))
799 return o;
800 if (o == GOF(counter) + 4 && sz == 4)
801 return o;
802
803 if (o == GOF(CC_OP)) return -1;
804 if (o == GOF(CC_DEP1)) return o;
805 if (o == GOF(CC_DEP2)) return o;
806 if (o == GOF(CC_NDEP)) return -1;
807 if (o == GOF(TISTART)) return -1;
808 if (o == GOF(TILEN)) return -1;
809 if (o == GOF(NRADDR)) return -1;
810 if (o == GOF(IP_AT_SYSCALL)) return -1;
811 if (o == GOF(fpc)) return -1;
812 if (o == GOF(IA)) return -1;
813 if (o == GOF(SYSNO)) return -1;
814 VG_(printf)("MC_(get_otrack_shadow_offset)(s390x)(off=%d,sz=%d)\n",
815 offset,szB);
816 tl_assert(0);
817# undef GOF
818
819
sewardj59570ff2010-01-01 11:59:33 +0000820 /* --------------------- arm --------------------- */
821
822# elif defined(VGA_arm)
823
824# define GOF(_fieldname) \
825 (offsetof(VexGuestARMState,guest_##_fieldname))
826# define SZB(_fieldname) \
827 (sizeof(((VexGuestARMState*)0)->guest_##_fieldname))
828
829 Int o = offset;
830 Int sz = szB;
831 tl_assert(sz > 0);
832 tl_assert(host_is_little_endian());
833
834 if (o == GOF(R0) && sz == 4) return o;
835 if (o == GOF(R1) && sz == 4) return o;
836 if (o == GOF(R2) && sz == 4) return o;
837 if (o == GOF(R3) && sz == 4) return o;
838 if (o == GOF(R4) && sz == 4) return o;
839 if (o == GOF(R5) && sz == 4) return o;
840 if (o == GOF(R6) && sz == 4) return o;
841 if (o == GOF(R7) && sz == 4) return o;
842 if (o == GOF(R8) && sz == 4) return o;
843 if (o == GOF(R9) && sz == 4) return o;
844 if (o == GOF(R10) && sz == 4) return o;
845 if (o == GOF(R11) && sz == 4) return o;
846 if (o == GOF(R12) && sz == 4) return o;
847 if (o == GOF(R13) && sz == 4) return o;
848 if (o == GOF(R14) && sz == 4) return o;
849
850 /* EAZG: These may be completely wrong. */
sewardjca9054a2010-08-22 12:16:25 +0000851 if (o == GOF(R15T) && sz == 4) return -1; /* slot unused */
sewardj59570ff2010-01-01 11:59:33 +0000852 if (o == GOF(CC_OP) && sz == 4) return -1; /* slot unused */
853
854 if (o == GOF(CC_DEP1) && sz == 4) return o;
855 if (o == GOF(CC_DEP2) && sz == 4) return o;
856
857 if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot unused */
858
sewardjca9054a2010-08-22 12:16:25 +0000859 if (o == GOF(QFLAG32) && sz == 4) return o;
860
sewardj6fede422010-09-22 22:27:41 +0000861 if (o == GOF(GEFLAG0) && sz == 4) return o;
862 if (o == GOF(GEFLAG1) && sz == 4) return o;
863 if (o == GOF(GEFLAG2) && sz == 4) return o;
864 if (o == GOF(GEFLAG3) && sz == 4) return o;
865
sewardj59570ff2010-01-01 11:59:33 +0000866 //if (o == GOF(SYSCALLNO) && sz == 4) return -1; /* slot unused */
867 //if (o == GOF(CC) && sz == 4) return -1; /* slot unused */
868 //if (o == GOF(EMWARN) && sz == 4) return -1; /* slot unused */
869 //if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
870 //if (o == GOF(NRADDR) && sz == 4) return -1; /* slot unused */
871
872 if (o == GOF(FPSCR) && sz == 4) return -1;
873 if (o == GOF(TPIDRURO) && sz == 4) return -1;
sewardjca9054a2010-08-22 12:16:25 +0000874 if (o == GOF(ITSTATE) && sz == 4) return -1;
sewardj59570ff2010-01-01 11:59:33 +0000875
sewardj8f6ec702010-09-29 21:40:44 +0000876 /* Accesses to F or D registers */
877 if (sz == 4 || sz == 8) {
878 if (o >= GOF(D0) && o+sz <= GOF(D0) +SZB(D0)) return GOF(D0);
879 if (o >= GOF(D1) && o+sz <= GOF(D1) +SZB(D1)) return GOF(D1);
880 if (o >= GOF(D2) && o+sz <= GOF(D2) +SZB(D2)) return GOF(D2);
881 if (o >= GOF(D3) && o+sz <= GOF(D3) +SZB(D3)) return GOF(D3);
882 if (o >= GOF(D4) && o+sz <= GOF(D4) +SZB(D4)) return GOF(D4);
883 if (o >= GOF(D5) && o+sz <= GOF(D5) +SZB(D5)) return GOF(D5);
884 if (o >= GOF(D6) && o+sz <= GOF(D6) +SZB(D6)) return GOF(D6);
885 if (o >= GOF(D7) && o+sz <= GOF(D7) +SZB(D7)) return GOF(D7);
886 if (o >= GOF(D8) && o+sz <= GOF(D8) +SZB(D8)) return GOF(D8);
887 if (o >= GOF(D9) && o+sz <= GOF(D9) +SZB(D9)) return GOF(D9);
888 if (o >= GOF(D10) && o+sz <= GOF(D10)+SZB(D10)) return GOF(D10);
889 if (o >= GOF(D11) && o+sz <= GOF(D11)+SZB(D11)) return GOF(D11);
890 if (o >= GOF(D12) && o+sz <= GOF(D12)+SZB(D12)) return GOF(D12);
891 if (o >= GOF(D13) && o+sz <= GOF(D13)+SZB(D13)) return GOF(D13);
892 if (o >= GOF(D14) && o+sz <= GOF(D14)+SZB(D14)) return GOF(D14);
893 if (o >= GOF(D15) && o+sz <= GOF(D15)+SZB(D15)) return GOF(D15);
894 if (o >= GOF(D16) && o+sz <= GOF(D16)+SZB(D16)) return GOF(D16);
895 if (o >= GOF(D17) && o+sz <= GOF(D17)+SZB(D17)) return GOF(D17);
896 if (o >= GOF(D18) && o+sz <= GOF(D18)+SZB(D18)) return GOF(D18);
897 if (o >= GOF(D19) && o+sz <= GOF(D19)+SZB(D19)) return GOF(D19);
898 if (o >= GOF(D20) && o+sz <= GOF(D20)+SZB(D20)) return GOF(D20);
899 if (o >= GOF(D21) && o+sz <= GOF(D21)+SZB(D21)) return GOF(D21);
900 if (o >= GOF(D22) && o+sz <= GOF(D22)+SZB(D22)) return GOF(D22);
901 if (o >= GOF(D23) && o+sz <= GOF(D23)+SZB(D23)) return GOF(D23);
902 if (o >= GOF(D24) && o+sz <= GOF(D24)+SZB(D24)) return GOF(D24);
903 if (o >= GOF(D25) && o+sz <= GOF(D25)+SZB(D25)) return GOF(D25);
904 if (o >= GOF(D26) && o+sz <= GOF(D26)+SZB(D26)) return GOF(D26);
905 if (o >= GOF(D27) && o+sz <= GOF(D27)+SZB(D27)) return GOF(D27);
906 if (o >= GOF(D28) && o+sz <= GOF(D28)+SZB(D28)) return GOF(D28);
907 if (o >= GOF(D29) && o+sz <= GOF(D29)+SZB(D29)) return GOF(D29);
908 if (o >= GOF(D30) && o+sz <= GOF(D30)+SZB(D30)) return GOF(D30);
909 if (o >= GOF(D31) && o+sz <= GOF(D31)+SZB(D31)) return GOF(D31);
910 }
911
912 /* Accesses to Q registers */
913 if (sz == 16) {
914 if (o >= GOF(D0) && o+sz <= GOF(D0) +2*SZB(D0)) return GOF(D0); // Q0
915 if (o >= GOF(D2) && o+sz <= GOF(D2) +2*SZB(D2)) return GOF(D2); // Q1
916 if (o >= GOF(D4) && o+sz <= GOF(D4) +2*SZB(D4)) return GOF(D4); // Q2
917 if (o >= GOF(D6) && o+sz <= GOF(D6) +2*SZB(D6)) return GOF(D6); // Q3
918 if (o >= GOF(D8) && o+sz <= GOF(D8) +2*SZB(D8)) return GOF(D8); // Q4
919 if (o >= GOF(D10) && o+sz <= GOF(D10)+2*SZB(D10)) return GOF(D10); // Q5
920 if (o >= GOF(D12) && o+sz <= GOF(D12)+2*SZB(D12)) return GOF(D12); // Q6
921 if (o >= GOF(D14) && o+sz <= GOF(D14)+2*SZB(D14)) return GOF(D14); // Q7
922 if (o >= GOF(D16) && o+sz <= GOF(D16)+2*SZB(D16)) return GOF(D16); // Q8
923 if (o >= GOF(D18) && o+sz <= GOF(D18)+2*SZB(D18)) return GOF(D18); // Q9
924 if (o >= GOF(D20) && o+sz <= GOF(D20)+2*SZB(D20)) return GOF(D20); // Q10
925 if (o >= GOF(D22) && o+sz <= GOF(D22)+2*SZB(D22)) return GOF(D22); // Q11
926 if (o >= GOF(D24) && o+sz <= GOF(D24)+2*SZB(D24)) return GOF(D24); // Q12
927 if (o >= GOF(D26) && o+sz <= GOF(D26)+2*SZB(D26)) return GOF(D26); // Q13
928 if (o >= GOF(D28) && o+sz <= GOF(D28)+2*SZB(D28)) return GOF(D28); // Q14
929 if (o >= GOF(D30) && o+sz <= GOF(D30)+2*SZB(D30)) return GOF(D30); // Q15
930 }
sewardj59570ff2010-01-01 11:59:33 +0000931
932 VG_(printf)("MC_(get_otrack_shadow_offset)(arm)(off=%d,sz=%d)\n",
933 offset,szB);
934 tl_assert(0);
935# undef GOF
936# undef SZB
937
sewardj7cf4e6b2008-05-01 20:24:26 +0000938# else
939# error "FIXME: not implemented for this architecture"
940# endif
941}
942
943
944/* Let 'arr' describe an indexed reference to a guest state section
945 (guest state array).
946
947 This function returns the corresponding guest state type to be used
948 when indexing the corresponding array in the second shadow (origin
949 tracking) area. If the array is not to be origin-tracked, return
950 Ity_INVALID.
951
952 This function must agree with MC_(get_otrack_shadow_offset) above.
953 See comments at the start of MC_(get_otrack_shadow_offset).
954*/
955IRType MC_(get_otrack_reg_array_equiv_int_type) ( IRRegArray* arr )
956{
957 /* -------------------- ppc64 -------------------- */
958# if defined(VGA_ppc64)
959 /* The redir stack. */
960 if (arr->base == offsetof(VexGuestPPC64State,guest_REDIR_STACK[0])
961 && arr->elemTy == Ity_I64
962 && arr->nElems == VEX_GUEST_PPC64_REDIR_STACK_SIZE)
963 return Ity_I64;
964
965 VG_(printf)("get_reg_array_equiv_int_type(ppc64): unhandled: ");
966 ppIRRegArray(arr);
967 VG_(printf)("\n");
968 tl_assert(0);
969
970 /* -------------------- ppc32 -------------------- */
971# elif defined(VGA_ppc32)
972 /* The redir stack. */
973 if (arr->base == offsetof(VexGuestPPC32State,guest_REDIR_STACK[0])
974 && arr->elemTy == Ity_I32
975 && arr->nElems == VEX_GUEST_PPC32_REDIR_STACK_SIZE)
976 return Ity_I32;
977
978 VG_(printf)("get_reg_array_equiv_int_type(ppc32): unhandled: ");
979 ppIRRegArray(arr);
980 VG_(printf)("\n");
981 tl_assert(0);
982
983 /* -------------------- amd64 -------------------- */
984# elif defined(VGA_amd64)
985 /* Ignore the FP tag array - pointless to shadow, and in any case
986 the elements are too small */
987 if (arr->base == offsetof(VexGuestAMD64State,guest_FPTAG)
988 && arr->elemTy == Ity_I8 && arr->nElems == 8)
989 return Ity_INVALID;
990
991 /* The FP register array */
992 if (arr->base == offsetof(VexGuestAMD64State,guest_FPREG[0])
993 && arr->elemTy == Ity_F64 && arr->nElems == 8)
994 return Ity_I64;
995
996 VG_(printf)("get_reg_array_equiv_int_type(amd64): unhandled: ");
997 ppIRRegArray(arr);
998 VG_(printf)("\n");
999 tl_assert(0);
1000
1001 /* --------------------- x86 --------------------- */
1002# elif defined(VGA_x86)
1003 /* Ignore the FP tag array - pointless to shadow, and in any case
1004 the elements are too small */
1005 if (arr->base == offsetof(VexGuestX86State,guest_FPTAG)
1006 && arr->elemTy == Ity_I8 && arr->nElems == 8)
1007 return Ity_INVALID;
1008
1009 /* The FP register array */
1010 if (arr->base == offsetof(VexGuestX86State,guest_FPREG[0])
1011 && arr->elemTy == Ity_F64 && arr->nElems == 8)
1012 return Ity_I64;
1013
1014 VG_(printf)("get_reg_array_equiv_int_type(x86): unhandled: ");
1015 ppIRRegArray(arr);
1016 VG_(printf)("\n");
1017 tl_assert(0);
1018
sewardj59570ff2010-01-01 11:59:33 +00001019 /* --------------------- arm --------------------- */
1020# elif defined(VGA_arm)
1021
1022 VG_(printf)("get_reg_array_equiv_int_type(arm): unhandled: ");
1023 ppIRRegArray(arr);
1024 VG_(printf)("\n");
1025 tl_assert(0);
1026
sewardjb5b87402011-03-07 16:05:35 +00001027 /* --------------------- s390x --------------------- */
1028# elif defined(VGA_s390x)
1029 /* Should never het here because s390x does not use Ist_PutI
1030 and Iex_GetI. */
1031 tl_assert(0);
sewardj7cf4e6b2008-05-01 20:24:26 +00001032# else
1033# error "FIXME: not implemented for this architecture"
1034# endif
1035}
1036
1037
1038/*--------------------------------------------------------------------*/
1039/*--- end mc_machine.c ---*/
1040/*--------------------------------------------------------------------*/