blob: d9865ac431f67a4980dd019aa3d6bdf724458028 [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
sewardj03f8d3f2012-08-05 15:46:46 +000012 Copyright (C) 2008-2012 OpenWorks Ltd
sewardj7cf4e6b2008-05-01 20:24:26 +000013 info@open-works.co.uk
14
15 This program is free software; you can redistribute it and/or
16 modify it under the terms of the GNU General Public License as
17 published by the Free Software Foundation; either version 2 of the
18 License, or (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful, but
21 WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
28 02111-1307, USA.
29
30 The GNU General Public License is contained in the file COPYING.
31
32 Neither the names of the U.S. Department of Energy nor the
33 University of California nor the names of its contributors may be
34 used to endorse or promote products derived from this software
35 without prior written permission.
36*/
37
38#include "pub_tool_basics.h"
philippe6643e962012-01-17 21:16:30 +000039#include "pub_tool_poolalloc.h" // For mc_include.h
sewardj7cf4e6b2008-05-01 20:24:26 +000040#include "pub_tool_hashtable.h" // For mc_include.h
41#include "pub_tool_libcassert.h"
42#include "pub_tool_libcprint.h"
43#include "pub_tool_tooliface.h"
44
45#include "mc_include.h"
46
47#undef MC_SIZEOF_GUEST_STATE
48
49#if defined(VGA_x86)
50# include "libvex_guest_x86.h"
51# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestX86State)
52#endif
53
54#if defined(VGA_amd64)
55# include "libvex_guest_amd64.h"
56# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestAMD64State)
57#endif
58
59#if defined(VGA_ppc32)
60# include "libvex_guest_ppc32.h"
61# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC32State)
62#endif
63
64#if defined(VGA_ppc64)
65# include "libvex_guest_ppc64.h"
66# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestPPC64State)
67#endif
68
sewardjb5b87402011-03-07 16:05:35 +000069#if defined(VGA_s390x)
70# include "libvex_guest_s390x.h"
71# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestS390XState)
72#endif
73
sewardj59570ff2010-01-01 11:59:33 +000074#if defined(VGA_arm)
75# include "libvex_guest_arm.h"
76# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestARMState)
77#endif
78
sewardj5db15402012-06-07 09:13:21 +000079#if defined(VGA_mips32)
80# include "libvex_guest_mips32.h"
81# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestMIPS32State)
82#endif
83
petarj4df0bfc2013-02-27 23:17:33 +000084#if defined(VGA_mips64)
85# include "libvex_guest_mips64.h"
86# define MC_SIZEOF_GUEST_STATE sizeof(VexGuestMIPS64State)
87#endif
88
sewardj7cf4e6b2008-05-01 20:24:26 +000089static inline Bool host_is_big_endian ( void ) {
90 UInt x = 0x11223344;
91 return 0x1122 == *(UShort*)(&x);
92}
93static inline Bool host_is_little_endian ( void ) {
94 UInt x = 0x11223344;
95 return 0x3344 == *(UShort*)(&x);
96}
97
98
99/* Let (offset,szB) describe a reference to the guest state section
100 [offset, offset+szB).
101
102 This function returns the corresponding guest state reference to be
103 used for the origin tag (which of course will be in the second
104 shadow area), or -1 if this piece of guest state is not to be
105 tracked.
106
107 Since origin tags are 32-bits long, we expect any returned value
108 (except -1) to be a multiple of 4, between 0 and
109 sizeof(guest-state)-4 inclusive.
110
111 This is inherently (guest-)architecture specific. For x86 and
112 amd64 we do some somewhat tricky things to give %AH .. %DH their
113 own tags. On ppc32/64 we do some marginally tricky things to give
114 all 16 %CR components their own tags.
115
116 This function only deals with references to the guest state whose
117 offsets are known at translation time (that is, references arising
118 from Put and Get). References whose offset is not known until run
119 time (that is, arise from PutI and GetI) are handled by
120 MC_(get_otrack_reg_array_equiv_int_type) below.
121
122 Note that since some guest state arrays (eg, the x86 FP reg stack)
123 are accessed both as arrays (eg, x87 insns) and directly (eg, MMX
124 insns), the two functions must be consistent for those sections of
125 guest state -- that is, they must both say the area is shadowed, or
126 both say it is not.
127
128 This function is dependent on the host's endianness, hence we
129 assert that the use case is supported.
130*/
131static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB ); /*fwds*/
132
133Int MC_(get_otrack_shadow_offset) ( Int offset, Int szB )
134{
135 Int cand = get_otrack_shadow_offset_wrk( offset, szB );
136 if (cand == -1)
137 return cand;
138 tl_assert(0 == (cand & 3));
139 tl_assert(cand <= MC_SIZEOF_GUEST_STATE-4);
140 return cand;
141}
142
143
144static Int get_otrack_shadow_offset_wrk ( Int offset, Int szB )
145{
146 /* -------------------- ppc64 -------------------- */
147
148# if defined(VGA_ppc64)
149
150# define GOF(_fieldname) \
151 (offsetof(VexGuestPPC64State,guest_##_fieldname))
152# define SZB(_fieldname) \
153 (sizeof(((VexGuestPPC64State*)0)->guest_##_fieldname))
154
155 Int sz = szB;
156 Int o = offset;
157 tl_assert(sz > 0);
158 tl_assert(host_is_big_endian());
159
160 if (sz == 8 || sz == 4) {
161 /* The point of this is to achieve
162 if ((o == GOF(GPRn) && sz == 8) || (o == 4+GOF(GPRn) && sz == 4))
163 return GOF(GPRn);
164 by testing ox instead of o, and setting ox back 4 bytes when sz == 4.
165 */
sewardj85857ab2008-05-06 15:40:32 +0000166 Int ox = sz == 8 ? o : (o - 4);
sewardj7cf4e6b2008-05-01 20:24:26 +0000167 if (ox == GOF(GPR0)) return ox;
168 if (ox == GOF(GPR1)) return ox;
169 if (ox == GOF(GPR2)) return ox;
170 if (ox == GOF(GPR3)) return ox;
171 if (ox == GOF(GPR4)) return ox;
172 if (ox == GOF(GPR5)) return ox;
173 if (ox == GOF(GPR6)) return ox;
174 if (ox == GOF(GPR7)) return ox;
175 if (ox == GOF(GPR8)) return ox;
176 if (ox == GOF(GPR9)) return ox;
177 if (ox == GOF(GPR10)) return ox;
178 if (ox == GOF(GPR11)) return ox;
179 if (ox == GOF(GPR12)) return ox;
180 if (ox == GOF(GPR13)) return ox;
181 if (ox == GOF(GPR14)) return ox;
182 if (ox == GOF(GPR15)) return ox;
183 if (ox == GOF(GPR16)) return ox;
184 if (ox == GOF(GPR17)) return ox;
185 if (ox == GOF(GPR18)) return ox;
186 if (ox == GOF(GPR19)) return ox;
187 if (ox == GOF(GPR20)) return ox;
188 if (ox == GOF(GPR21)) return ox;
189 if (ox == GOF(GPR22)) return ox;
190 if (ox == GOF(GPR23)) return ox;
191 if (ox == GOF(GPR24)) return ox;
192 if (ox == GOF(GPR25)) return ox;
193 if (ox == GOF(GPR26)) return ox;
194 if (ox == GOF(GPR27)) return ox;
195 if (ox == GOF(GPR28)) return ox;
196 if (ox == GOF(GPR29)) return ox;
197 if (ox == GOF(GPR30)) return ox;
198 if (ox == GOF(GPR31)) return ox;
199 }
200
201 if (o == GOF(LR) && sz == 8) return o;
202 if (o == GOF(CTR) && sz == 8) return o;
203
204 if (o == GOF(CIA) && sz == 8) return -1;
sewardj71633b12009-03-30 02:27:29 +0000205 if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
sewardjb0ccb4d2012-04-02 10:22:05 +0000206 if (o == GOF(FPROUND) && sz == 1) return -1;
207 if (o == GOF(DFPROUND) && sz == 1) return -1;
florian2e497412012-08-26 03:22:09 +0000208 if (o == GOF(EMNOTE) && sz == 4) return -1;
sewardj7cf4e6b2008-05-01 20:24:26 +0000209 if (o == GOF(TISTART) && sz == 8) return -1;
210 if (o == GOF(TILEN) && sz == 8) return -1;
211 if (o == GOF(VSCR) && sz == 4) return -1;
212 if (o == GOF(VRSAVE) && sz == 4) return -1;
213 if (o == GOF(REDIR_SP) && sz == 8) return -1;
214
sewardjf34eb492011-04-15 11:57:05 +0000215 // With ISA 2.06, the "Vector-Scalar Floating-point" category
216 // provides facilities to support vector and scalar binary floating-
217 // point operations. A unified register file is an integral part
218 // of this new facility, combining floating point and vector registers
219 // using a 64x128-bit vector. These are referred to as VSR[0..63].
220 // The floating point registers are now mapped into double word element 0
221 // of VSR[0..31]. The 32x128-bit vector registers defined by the "Vector
222 // Facility [Category: Vector]" are now mapped to VSR[32..63].
223
224 // Floating point registers . . .
225 if (o == GOF(VSR0) && sz == 8) return o;
226 if (o == GOF(VSR1) && sz == 8) return o;
227 if (o == GOF(VSR2) && sz == 8) return o;
228 if (o == GOF(VSR3) && sz == 8) return o;
229 if (o == GOF(VSR4) && sz == 8) return o;
230 if (o == GOF(VSR5) && sz == 8) return o;
231 if (o == GOF(VSR6) && sz == 8) return o;
232 if (o == GOF(VSR7) && sz == 8) return o;
233 if (o == GOF(VSR8) && sz == 8) return o;
234 if (o == GOF(VSR9) && sz == 8) return o;
235 if (o == GOF(VSR10) && sz == 8) return o;
236 if (o == GOF(VSR11) && sz == 8) return o;
237 if (o == GOF(VSR12) && sz == 8) return o;
238 if (o == GOF(VSR13) && sz == 8) return o;
239 if (o == GOF(VSR14) && sz == 8) return o;
240 if (o == GOF(VSR15) && sz == 8) return o;
241 if (o == GOF(VSR16) && sz == 8) return o;
242 if (o == GOF(VSR17) && sz == 8) return o;
243 if (o == GOF(VSR18) && sz == 8) return o;
244 if (o == GOF(VSR19) && sz == 8) return o;
245 if (o == GOF(VSR20) && sz == 8) return o;
246 if (o == GOF(VSR21) && sz == 8) return o;
247 if (o == GOF(VSR22) && sz == 8) return o;
248 if (o == GOF(VSR23) && sz == 8) return o;
249 if (o == GOF(VSR24) && sz == 8) return o;
250 if (o == GOF(VSR25) && sz == 8) return o;
251 if (o == GOF(VSR26) && sz == 8) return o;
252 if (o == GOF(VSR27) && sz == 8) return o;
253 if (o == GOF(VSR28) && sz == 8) return o;
254 if (o == GOF(VSR29) && sz == 8) return o;
255 if (o == GOF(VSR30) && sz == 8) return o;
256 if (o == GOF(VSR31) && sz == 8) return o;
sewardj7cf4e6b2008-05-01 20:24:26 +0000257
258 /* For the various byte sized XER/CR pieces, use offset 8
sewardjf34eb492011-04-15 11:57:05 +0000259 in VSR0 .. VSR19. */
260 tl_assert(SZB(VSR0) == 16);
261 if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VSR0);
262 if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VSR1);
263 if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VSR2);
264 if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VSR3);
sewardj7cf4e6b2008-05-01 20:24:26 +0000265
sewardjf34eb492011-04-15 11:57:05 +0000266 if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VSR4);
267 if (o == GOF(CR0_0) && sz == 1) return 8 +GOF(VSR5);
268 if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VSR6);
269 if (o == GOF(CR1_0) && sz == 1) return 8 +GOF(VSR7);
270 if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VSR8);
271 if (o == GOF(CR2_0) && sz == 1) return 8 +GOF(VSR9);
272 if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VSR10);
273 if (o == GOF(CR3_0) && sz == 1) return 8 +GOF(VSR11);
274 if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VSR12);
275 if (o == GOF(CR4_0) && sz == 1) return 8 +GOF(VSR13);
276 if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VSR14);
277 if (o == GOF(CR5_0) && sz == 1) return 8 +GOF(VSR15);
278 if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VSR16);
279 if (o == GOF(CR6_0) && sz == 1) return 8 +GOF(VSR17);
280 if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VSR18);
281 if (o == GOF(CR7_0) && sz == 1) return 8 +GOF(VSR19);
sewardj7cf4e6b2008-05-01 20:24:26 +0000282
sewardjf34eb492011-04-15 11:57:05 +0000283 /* Vector registers .. use offset 0 in VSR0 .. VSR63. */
284 if (o >= GOF(VSR0) && o+sz <= GOF(VSR0) +SZB(VSR0)) return 0+ GOF(VSR0);
285 if (o >= GOF(VSR1) && o+sz <= GOF(VSR1) +SZB(VSR1)) return 0+ GOF(VSR1);
286 if (o >= GOF(VSR2) && o+sz <= GOF(VSR2) +SZB(VSR2)) return 0+ GOF(VSR2);
287 if (o >= GOF(VSR3) && o+sz <= GOF(VSR3) +SZB(VSR3)) return 0+ GOF(VSR3);
288 if (o >= GOF(VSR4) && o+sz <= GOF(VSR4) +SZB(VSR4)) return 0+ GOF(VSR4);
289 if (o >= GOF(VSR5) && o+sz <= GOF(VSR5) +SZB(VSR5)) return 0+ GOF(VSR5);
290 if (o >= GOF(VSR6) && o+sz <= GOF(VSR6) +SZB(VSR6)) return 0+ GOF(VSR6);
291 if (o >= GOF(VSR7) && o+sz <= GOF(VSR7) +SZB(VSR7)) return 0+ GOF(VSR7);
292 if (o >= GOF(VSR8) && o+sz <= GOF(VSR8) +SZB(VSR8)) return 0+ GOF(VSR8);
293 if (o >= GOF(VSR9) && o+sz <= GOF(VSR9) +SZB(VSR9)) return 0+ GOF(VSR9);
294 if (o >= GOF(VSR10) && o+sz <= GOF(VSR10)+SZB(VSR10)) return 0+ GOF(VSR10);
295 if (o >= GOF(VSR11) && o+sz <= GOF(VSR11)+SZB(VSR11)) return 0+ GOF(VSR11);
296 if (o >= GOF(VSR12) && o+sz <= GOF(VSR12)+SZB(VSR12)) return 0+ GOF(VSR12);
297 if (o >= GOF(VSR13) && o+sz <= GOF(VSR13)+SZB(VSR13)) return 0+ GOF(VSR13);
298 if (o >= GOF(VSR14) && o+sz <= GOF(VSR14)+SZB(VSR14)) return 0+ GOF(VSR14);
299 if (o >= GOF(VSR15) && o+sz <= GOF(VSR15)+SZB(VSR15)) return 0+ GOF(VSR15);
300 if (o >= GOF(VSR16) && o+sz <= GOF(VSR16)+SZB(VSR16)) return 0+ GOF(VSR16);
301 if (o >= GOF(VSR17) && o+sz <= GOF(VSR17)+SZB(VSR17)) return 0+ GOF(VSR17);
302 if (o >= GOF(VSR18) && o+sz <= GOF(VSR18)+SZB(VSR18)) return 0+ GOF(VSR18);
303 if (o >= GOF(VSR19) && o+sz <= GOF(VSR19)+SZB(VSR19)) return 0+ GOF(VSR19);
304 if (o >= GOF(VSR20) && o+sz <= GOF(VSR20)+SZB(VSR20)) return 0+ GOF(VSR20);
305 if (o >= GOF(VSR21) && o+sz <= GOF(VSR21)+SZB(VSR21)) return 0+ GOF(VSR21);
306 if (o >= GOF(VSR22) && o+sz <= GOF(VSR22)+SZB(VSR22)) return 0+ GOF(VSR22);
307 if (o >= GOF(VSR23) && o+sz <= GOF(VSR23)+SZB(VSR23)) return 0+ GOF(VSR23);
308 if (o >= GOF(VSR24) && o+sz <= GOF(VSR24)+SZB(VSR24)) return 0+ GOF(VSR24);
309 if (o >= GOF(VSR25) && o+sz <= GOF(VSR25)+SZB(VSR25)) return 0+ GOF(VSR25);
310 if (o >= GOF(VSR26) && o+sz <= GOF(VSR26)+SZB(VSR26)) return 0+ GOF(VSR26);
311 if (o >= GOF(VSR27) && o+sz <= GOF(VSR27)+SZB(VSR27)) return 0+ GOF(VSR27);
312 if (o >= GOF(VSR28) && o+sz <= GOF(VSR28)+SZB(VSR28)) return 0+ GOF(VSR28);
313 if (o >= GOF(VSR29) && o+sz <= GOF(VSR29)+SZB(VSR29)) return 0+ GOF(VSR29);
314 if (o >= GOF(VSR30) && o+sz <= GOF(VSR30)+SZB(VSR30)) return 0+ GOF(VSR30);
315 if (o >= GOF(VSR31) && o+sz <= GOF(VSR31)+SZB(VSR31)) return 0+ GOF(VSR31);
316 if (o >= GOF(VSR32) && o+sz <= GOF(VSR32)+SZB(VSR32)) return 0+ GOF(VSR32);
317 if (o >= GOF(VSR33) && o+sz <= GOF(VSR33)+SZB(VSR33)) return 0+ GOF(VSR33);
318 if (o >= GOF(VSR34) && o+sz <= GOF(VSR34)+SZB(VSR34)) return 0+ GOF(VSR34);
319 if (o >= GOF(VSR35) && o+sz <= GOF(VSR35)+SZB(VSR35)) return 0+ GOF(VSR35);
320 if (o >= GOF(VSR36) && o+sz <= GOF(VSR36)+SZB(VSR36)) return 0+ GOF(VSR36);
321 if (o >= GOF(VSR37) && o+sz <= GOF(VSR37)+SZB(VSR37)) return 0+ GOF(VSR37);
322 if (o >= GOF(VSR38) && o+sz <= GOF(VSR38)+SZB(VSR38)) return 0+ GOF(VSR38);
323 if (o >= GOF(VSR39) && o+sz <= GOF(VSR39)+SZB(VSR39)) return 0+ GOF(VSR39);
324 if (o >= GOF(VSR40) && o+sz <= GOF(VSR40)+SZB(VSR40)) return 0+ GOF(VSR40);
325 if (o >= GOF(VSR41) && o+sz <= GOF(VSR41)+SZB(VSR41)) return 0+ GOF(VSR41);
326 if (o >= GOF(VSR42) && o+sz <= GOF(VSR42)+SZB(VSR42)) return 0+ GOF(VSR42);
327 if (o >= GOF(VSR43) && o+sz <= GOF(VSR43)+SZB(VSR43)) return 0+ GOF(VSR43);
328 if (o >= GOF(VSR44) && o+sz <= GOF(VSR44)+SZB(VSR44)) return 0+ GOF(VSR44);
329 if (o >= GOF(VSR45) && o+sz <= GOF(VSR45)+SZB(VSR45)) return 0+ GOF(VSR45);
330 if (o >= GOF(VSR46) && o+sz <= GOF(VSR46)+SZB(VSR46)) return 0+ GOF(VSR46);
331 if (o >= GOF(VSR47) && o+sz <= GOF(VSR47)+SZB(VSR47)) return 0+ GOF(VSR47);
332 if (o >= GOF(VSR48) && o+sz <= GOF(VSR48)+SZB(VSR48)) return 0+ GOF(VSR48);
333 if (o >= GOF(VSR49) && o+sz <= GOF(VSR49)+SZB(VSR49)) return 0+ GOF(VSR49);
334 if (o >= GOF(VSR50) && o+sz <= GOF(VSR50)+SZB(VSR50)) return 0+ GOF(VSR50);
335 if (o >= GOF(VSR51) && o+sz <= GOF(VSR51)+SZB(VSR51)) return 0+ GOF(VSR51);
336 if (o >= GOF(VSR52) && o+sz <= GOF(VSR52)+SZB(VSR52)) return 0+ GOF(VSR52);
337 if (o >= GOF(VSR53) && o+sz <= GOF(VSR53)+SZB(VSR53)) return 0+ GOF(VSR53);
338 if (o >= GOF(VSR54) && o+sz <= GOF(VSR54)+SZB(VSR54)) return 0+ GOF(VSR54);
339 if (o >= GOF(VSR55) && o+sz <= GOF(VSR55)+SZB(VSR55)) return 0+ GOF(VSR55);
340 if (o >= GOF(VSR56) && o+sz <= GOF(VSR56)+SZB(VSR56)) return 0+ GOF(VSR56);
341 if (o >= GOF(VSR57) && o+sz <= GOF(VSR57)+SZB(VSR57)) return 0+ GOF(VSR57);
342 if (o >= GOF(VSR58) && o+sz <= GOF(VSR58)+SZB(VSR58)) return 0+ GOF(VSR58);
343 if (o >= GOF(VSR59) && o+sz <= GOF(VSR59)+SZB(VSR59)) return 0+ GOF(VSR59);
344 if (o >= GOF(VSR60) && o+sz <= GOF(VSR60)+SZB(VSR60)) return 0+ GOF(VSR60);
345 if (o >= GOF(VSR61) && o+sz <= GOF(VSR61)+SZB(VSR61)) return 0+ GOF(VSR61);
346 if (o >= GOF(VSR62) && o+sz <= GOF(VSR62)+SZB(VSR62)) return 0+ GOF(VSR62);
347 if (o >= GOF(VSR63) && o+sz <= GOF(VSR63)+SZB(VSR63)) return 0+ GOF(VSR63);
sewardj7cf4e6b2008-05-01 20:24:26 +0000348
349 VG_(printf)("MC_(get_otrack_shadow_offset)(ppc64)(off=%d,sz=%d)\n",
350 offset,szB);
351 tl_assert(0);
352# undef GOF
353# undef SZB
354
355 /* -------------------- ppc32 -------------------- */
356
357# elif defined(VGA_ppc32)
358
359# define GOF(_fieldname) \
360 (offsetof(VexGuestPPC32State,guest_##_fieldname))
361# define SZB(_fieldname) \
362 (sizeof(((VexGuestPPC32State*)0)->guest_##_fieldname))
363 Int o = offset;
364 Int sz = szB;
365 tl_assert(sz > 0);
366 tl_assert(host_is_big_endian());
367
368 if (o == GOF(GPR0) && sz == 4) return o;
369 if (o == GOF(GPR1) && sz == 4) return o;
370 if (o == GOF(GPR2) && sz == 4) return o;
371 if (o == GOF(GPR3) && sz == 4) return o;
372 if (o == GOF(GPR4) && sz == 4) return o;
373 if (o == GOF(GPR5) && sz == 4) return o;
374 if (o == GOF(GPR6) && sz == 4) return o;
375 if (o == GOF(GPR7) && sz == 4) return o;
376 if (o == GOF(GPR8) && sz == 4) return o;
377 if (o == GOF(GPR9) && sz == 4) return o;
378 if (o == GOF(GPR10) && sz == 4) return o;
379 if (o == GOF(GPR11) && sz == 4) return o;
380 if (o == GOF(GPR12) && sz == 4) return o;
381 if (o == GOF(GPR13) && sz == 4) return o;
382 if (o == GOF(GPR14) && sz == 4) return o;
383 if (o == GOF(GPR15) && sz == 4) return o;
384 if (o == GOF(GPR16) && sz == 4) return o;
385 if (o == GOF(GPR17) && sz == 4) return o;
386 if (o == GOF(GPR18) && sz == 4) return o;
387 if (o == GOF(GPR19) && sz == 4) return o;
388 if (o == GOF(GPR20) && sz == 4) return o;
389 if (o == GOF(GPR21) && sz == 4) return o;
390 if (o == GOF(GPR22) && sz == 4) return o;
391 if (o == GOF(GPR23) && sz == 4) return o;
392 if (o == GOF(GPR24) && sz == 4) return o;
393 if (o == GOF(GPR25) && sz == 4) return o;
394 if (o == GOF(GPR26) && sz == 4) return o;
395 if (o == GOF(GPR27) && sz == 4) return o;
396 if (o == GOF(GPR28) && sz == 4) return o;
397 if (o == GOF(GPR29) && sz == 4) return o;
398 if (o == GOF(GPR30) && sz == 4) return o;
399 if (o == GOF(GPR31) && sz == 4) return o;
400
401 if (o == GOF(LR) && sz == 4) return o;
402 if (o == GOF(CTR) && sz == 4) return o;
403
404 if (o == GOF(CIA) && sz == 4) return -1;
sewardj71633b12009-03-30 02:27:29 +0000405 if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
sewardjf06eabf2012-04-02 15:10:37 +0000406 if (o == GOF(FPROUND) && sz == 1) return -1;
407 if (o == GOF(DFPROUND) && sz == 1) return -1;
sewardj3b507352009-02-14 15:28:46 +0000408 if (o == GOF(VRSAVE) && sz == 4) return -1;
florian2e497412012-08-26 03:22:09 +0000409 if (o == GOF(EMNOTE) && sz == 4) return -1;
sewardj7cf4e6b2008-05-01 20:24:26 +0000410 if (o == GOF(TISTART) && sz == 4) return -1;
411 if (o == GOF(TILEN) && sz == 4) return -1;
412 if (o == GOF(VSCR) && sz == 4) return -1;
413 if (o == GOF(REDIR_SP) && sz == 4) return -1;
414 if (o == GOF(SPRG3_RO) && sz == 4) return -1;
415
sewardjf34eb492011-04-15 11:57:05 +0000416 // With ISA 2.06, the "Vector-Scalar Floating-point" category
417 // provides facilities to support vector and scalar binary floating-
418 // point operations. A unified register file is an integral part
419 // of this new facility, combining floating point and vector registers
420 // using a 64x128-bit vector. These are referred to as VSR[0..63].
421 // The floating point registers are now mapped into double word element 0
422 // of VSR[0..31]. The 32x128-bit vector registers defined by the "Vector
423 // Facility [Category: Vector]" are now mapped to VSR[32..63].
424
425 // Floating point registers . . .
426 if (o == GOF(VSR0) && sz == 8) return o;
427 if (o == GOF(VSR1) && sz == 8) return o;
428 if (o == GOF(VSR2) && sz == 8) return o;
429 if (o == GOF(VSR3) && sz == 8) return o;
430 if (o == GOF(VSR4) && sz == 8) return o;
431 if (o == GOF(VSR5) && sz == 8) return o;
432 if (o == GOF(VSR6) && sz == 8) return o;
433 if (o == GOF(VSR7) && sz == 8) return o;
434 if (o == GOF(VSR8) && sz == 8) return o;
435 if (o == GOF(VSR9) && sz == 8) return o;
436 if (o == GOF(VSR10) && sz == 8) return o;
437 if (o == GOF(VSR11) && sz == 8) return o;
438 if (o == GOF(VSR12) && sz == 8) return o;
439 if (o == GOF(VSR13) && sz == 8) return o;
440 if (o == GOF(VSR14) && sz == 8) return o;
441 if (o == GOF(VSR15) && sz == 8) return o;
442 if (o == GOF(VSR16) && sz == 8) return o;
443 if (o == GOF(VSR17) && sz == 8) return o;
444 if (o == GOF(VSR18) && sz == 8) return o;
445 if (o == GOF(VSR19) && sz == 8) return o;
446 if (o == GOF(VSR20) && sz == 8) return o;
447 if (o == GOF(VSR21) && sz == 8) return o;
448 if (o == GOF(VSR22) && sz == 8) return o;
449 if (o == GOF(VSR23) && sz == 8) return o;
450 if (o == GOF(VSR24) && sz == 8) return o;
451 if (o == GOF(VSR25) && sz == 8) return o;
452 if (o == GOF(VSR26) && sz == 8) return o;
453 if (o == GOF(VSR27) && sz == 8) return o;
454 if (o == GOF(VSR28) && sz == 8) return o;
455 if (o == GOF(VSR29) && sz == 8) return o;
456 if (o == GOF(VSR30) && sz == 8) return o;
457 if (o == GOF(VSR31) && sz == 8) return o;
sewardj7cf4e6b2008-05-01 20:24:26 +0000458
459 /* For the various byte sized XER/CR pieces, use offset 8
sewardjf34eb492011-04-15 11:57:05 +0000460 in VSR0 .. VSR19. */
461 tl_assert(SZB(VSR0) == 16);
462 if (o == GOF(XER_SO) && sz == 1) return 8 +GOF(VSR0);
463 if (o == GOF(XER_OV) && sz == 1) return 8 +GOF(VSR1);
464 if (o == GOF(XER_CA) && sz == 1) return 8 +GOF(VSR2);
465 if (o == GOF(XER_BC) && sz == 1) return 8 +GOF(VSR3);
sewardj7cf4e6b2008-05-01 20:24:26 +0000466
sewardjf34eb492011-04-15 11:57:05 +0000467 if (o == GOF(CR0_321) && sz == 1) return 8 +GOF(VSR4);
468 if (o == GOF(CR0_0) && sz == 1) return 8 +GOF(VSR5);
469 if (o == GOF(CR1_321) && sz == 1) return 8 +GOF(VSR6);
470 if (o == GOF(CR1_0) && sz == 1) return 8 +GOF(VSR7);
471 if (o == GOF(CR2_321) && sz == 1) return 8 +GOF(VSR8);
472 if (o == GOF(CR2_0) && sz == 1) return 8 +GOF(VSR9);
473 if (o == GOF(CR3_321) && sz == 1) return 8 +GOF(VSR10);
474 if (o == GOF(CR3_0) && sz == 1) return 8 +GOF(VSR11);
475 if (o == GOF(CR4_321) && sz == 1) return 8 +GOF(VSR12);
476 if (o == GOF(CR4_0) && sz == 1) return 8 +GOF(VSR13);
477 if (o == GOF(CR5_321) && sz == 1) return 8 +GOF(VSR14);
478 if (o == GOF(CR5_0) && sz == 1) return 8 +GOF(VSR15);
479 if (o == GOF(CR6_321) && sz == 1) return 8 +GOF(VSR16);
480 if (o == GOF(CR6_0) && sz == 1) return 8 +GOF(VSR17);
481 if (o == GOF(CR7_321) && sz == 1) return 8 +GOF(VSR18);
482 if (o == GOF(CR7_0) && sz == 1) return 8 +GOF(VSR19);
sewardj7cf4e6b2008-05-01 20:24:26 +0000483
sewardjf34eb492011-04-15 11:57:05 +0000484 /* Vector registers .. use offset 0 in VSR0 .. VSR63. */
485 if (o >= GOF(VSR0) && o+sz <= GOF(VSR0) +SZB(VSR0)) return 0+ GOF(VSR0);
486 if (o >= GOF(VSR1) && o+sz <= GOF(VSR1) +SZB(VSR1)) return 0+ GOF(VSR1);
487 if (o >= GOF(VSR2) && o+sz <= GOF(VSR2) +SZB(VSR2)) return 0+ GOF(VSR2);
488 if (o >= GOF(VSR3) && o+sz <= GOF(VSR3) +SZB(VSR3)) return 0+ GOF(VSR3);
489 if (o >= GOF(VSR4) && o+sz <= GOF(VSR4) +SZB(VSR4)) return 0+ GOF(VSR4);
490 if (o >= GOF(VSR5) && o+sz <= GOF(VSR5) +SZB(VSR5)) return 0+ GOF(VSR5);
491 if (o >= GOF(VSR6) && o+sz <= GOF(VSR6) +SZB(VSR6)) return 0+ GOF(VSR6);
492 if (o >= GOF(VSR7) && o+sz <= GOF(VSR7) +SZB(VSR7)) return 0+ GOF(VSR7);
493 if (o >= GOF(VSR8) && o+sz <= GOF(VSR8) +SZB(VSR8)) return 0+ GOF(VSR8);
494 if (o >= GOF(VSR9) && o+sz <= GOF(VSR9) +SZB(VSR9)) return 0+ GOF(VSR9);
495 if (o >= GOF(VSR10) && o+sz <= GOF(VSR10)+SZB(VSR10)) return 0+ GOF(VSR10);
496 if (o >= GOF(VSR11) && o+sz <= GOF(VSR11)+SZB(VSR11)) return 0+ GOF(VSR11);
497 if (o >= GOF(VSR12) && o+sz <= GOF(VSR12)+SZB(VSR12)) return 0+ GOF(VSR12);
498 if (o >= GOF(VSR13) && o+sz <= GOF(VSR13)+SZB(VSR13)) return 0+ GOF(VSR13);
499 if (o >= GOF(VSR14) && o+sz <= GOF(VSR14)+SZB(VSR14)) return 0+ GOF(VSR14);
500 if (o >= GOF(VSR15) && o+sz <= GOF(VSR15)+SZB(VSR15)) return 0+ GOF(VSR15);
501 if (o >= GOF(VSR16) && o+sz <= GOF(VSR16)+SZB(VSR16)) return 0+ GOF(VSR16);
502 if (o >= GOF(VSR17) && o+sz <= GOF(VSR17)+SZB(VSR17)) return 0+ GOF(VSR17);
503 if (o >= GOF(VSR18) && o+sz <= GOF(VSR18)+SZB(VSR18)) return 0+ GOF(VSR18);
504 if (o >= GOF(VSR19) && o+sz <= GOF(VSR19)+SZB(VSR19)) return 0+ GOF(VSR19);
505 if (o >= GOF(VSR20) && o+sz <= GOF(VSR20)+SZB(VSR20)) return 0+ GOF(VSR20);
506 if (o >= GOF(VSR21) && o+sz <= GOF(VSR21)+SZB(VSR21)) return 0+ GOF(VSR21);
507 if (o >= GOF(VSR22) && o+sz <= GOF(VSR22)+SZB(VSR22)) return 0+ GOF(VSR22);
508 if (o >= GOF(VSR23) && o+sz <= GOF(VSR23)+SZB(VSR23)) return 0+ GOF(VSR23);
509 if (o >= GOF(VSR24) && o+sz <= GOF(VSR24)+SZB(VSR24)) return 0+ GOF(VSR24);
510 if (o >= GOF(VSR25) && o+sz <= GOF(VSR25)+SZB(VSR25)) return 0+ GOF(VSR25);
511 if (o >= GOF(VSR26) && o+sz <= GOF(VSR26)+SZB(VSR26)) return 0+ GOF(VSR26);
512 if (o >= GOF(VSR27) && o+sz <= GOF(VSR27)+SZB(VSR27)) return 0+ GOF(VSR27);
513 if (o >= GOF(VSR28) && o+sz <= GOF(VSR28)+SZB(VSR28)) return 0+ GOF(VSR28);
514 if (o >= GOF(VSR29) && o+sz <= GOF(VSR29)+SZB(VSR29)) return 0+ GOF(VSR29);
515 if (o >= GOF(VSR30) && o+sz <= GOF(VSR30)+SZB(VSR30)) return 0+ GOF(VSR30);
516 if (o >= GOF(VSR31) && o+sz <= GOF(VSR31)+SZB(VSR31)) return 0+ GOF(VSR31);
517 if (o >= GOF(VSR32) && o+sz <= GOF(VSR32)+SZB(VSR32)) return 0+ GOF(VSR32);
518 if (o >= GOF(VSR33) && o+sz <= GOF(VSR33)+SZB(VSR33)) return 0+ GOF(VSR33);
519 if (o >= GOF(VSR34) && o+sz <= GOF(VSR34)+SZB(VSR34)) return 0+ GOF(VSR34);
520 if (o >= GOF(VSR35) && o+sz <= GOF(VSR35)+SZB(VSR35)) return 0+ GOF(VSR35);
521 if (o >= GOF(VSR36) && o+sz <= GOF(VSR36)+SZB(VSR36)) return 0+ GOF(VSR36);
522 if (o >= GOF(VSR37) && o+sz <= GOF(VSR37)+SZB(VSR37)) return 0+ GOF(VSR37);
523 if (o >= GOF(VSR38) && o+sz <= GOF(VSR38)+SZB(VSR38)) return 0+ GOF(VSR38);
524 if (o >= GOF(VSR39) && o+sz <= GOF(VSR39)+SZB(VSR39)) return 0+ GOF(VSR39);
525 if (o >= GOF(VSR40) && o+sz <= GOF(VSR40)+SZB(VSR40)) return 0+ GOF(VSR40);
526 if (o >= GOF(VSR41) && o+sz <= GOF(VSR41)+SZB(VSR41)) return 0+ GOF(VSR41);
527 if (o >= GOF(VSR42) && o+sz <= GOF(VSR42)+SZB(VSR42)) return 0+ GOF(VSR42);
528 if (o >= GOF(VSR43) && o+sz <= GOF(VSR43)+SZB(VSR43)) return 0+ GOF(VSR43);
529 if (o >= GOF(VSR44) && o+sz <= GOF(VSR44)+SZB(VSR44)) return 0+ GOF(VSR44);
530 if (o >= GOF(VSR45) && o+sz <= GOF(VSR45)+SZB(VSR45)) return 0+ GOF(VSR45);
531 if (o >= GOF(VSR46) && o+sz <= GOF(VSR46)+SZB(VSR46)) return 0+ GOF(VSR46);
532 if (o >= GOF(VSR47) && o+sz <= GOF(VSR47)+SZB(VSR47)) return 0+ GOF(VSR47);
533 if (o >= GOF(VSR48) && o+sz <= GOF(VSR48)+SZB(VSR48)) return 0+ GOF(VSR48);
534 if (o >= GOF(VSR49) && o+sz <= GOF(VSR49)+SZB(VSR49)) return 0+ GOF(VSR49);
535 if (o >= GOF(VSR50) && o+sz <= GOF(VSR50)+SZB(VSR50)) return 0+ GOF(VSR50);
536 if (o >= GOF(VSR51) && o+sz <= GOF(VSR51)+SZB(VSR51)) return 0+ GOF(VSR51);
537 if (o >= GOF(VSR52) && o+sz <= GOF(VSR52)+SZB(VSR52)) return 0+ GOF(VSR52);
538 if (o >= GOF(VSR53) && o+sz <= GOF(VSR53)+SZB(VSR53)) return 0+ GOF(VSR53);
539 if (o >= GOF(VSR54) && o+sz <= GOF(VSR54)+SZB(VSR54)) return 0+ GOF(VSR54);
540 if (o >= GOF(VSR55) && o+sz <= GOF(VSR55)+SZB(VSR55)) return 0+ GOF(VSR55);
541 if (o >= GOF(VSR56) && o+sz <= GOF(VSR56)+SZB(VSR56)) return 0+ GOF(VSR56);
542 if (o >= GOF(VSR57) && o+sz <= GOF(VSR57)+SZB(VSR57)) return 0+ GOF(VSR57);
543 if (o >= GOF(VSR58) && o+sz <= GOF(VSR58)+SZB(VSR58)) return 0+ GOF(VSR58);
544 if (o >= GOF(VSR59) && o+sz <= GOF(VSR59)+SZB(VSR59)) return 0+ GOF(VSR59);
545 if (o >= GOF(VSR60) && o+sz <= GOF(VSR60)+SZB(VSR60)) return 0+ GOF(VSR60);
546 if (o >= GOF(VSR61) && o+sz <= GOF(VSR61)+SZB(VSR61)) return 0+ GOF(VSR61);
547 if (o >= GOF(VSR62) && o+sz <= GOF(VSR62)+SZB(VSR62)) return 0+ GOF(VSR62);
548 if (o >= GOF(VSR63) && o+sz <= GOF(VSR63)+SZB(VSR63)) return 0+ GOF(VSR63);
sewardj7cf4e6b2008-05-01 20:24:26 +0000549
550 VG_(printf)("MC_(get_otrack_shadow_offset)(ppc32)(off=%d,sz=%d)\n",
551 offset,szB);
552 tl_assert(0);
553# undef GOF
554# undef SZB
555
556 /* -------------------- amd64 -------------------- */
557
558# elif defined(VGA_amd64)
559
560# define GOF(_fieldname) \
561 (offsetof(VexGuestAMD64State,guest_##_fieldname))
562# define SZB(_fieldname) \
563 (sizeof(((VexGuestAMD64State*)0)->guest_##_fieldname))
564 Int o = offset;
565 Int sz = szB;
566 Bool is1248 = sz == 8 || sz == 4 || sz == 2 || sz == 1;
567 tl_assert(sz > 0);
568 tl_assert(host_is_little_endian());
569
570 if (o == GOF(RAX) && is1248) return o;
571 if (o == GOF(RCX) && is1248) return o;
572 if (o == GOF(RDX) && is1248) return o;
573 if (o == GOF(RBX) && is1248) return o;
574 if (o == GOF(RSP) && is1248) return o;
575 if (o == GOF(RBP) && is1248) return o;
576 if (o == GOF(RSI) && is1248) return o;
577 if (o == GOF(RDI) && is1248) return o;
578 if (o == GOF(R8) && is1248) return o;
579 if (o == GOF(R9) && is1248) return o;
580 if (o == GOF(R10) && is1248) return o;
581 if (o == GOF(R11) && is1248) return o;
582 if (o == GOF(R12) && is1248) return o;
583 if (o == GOF(R13) && is1248) return o;
584 if (o == GOF(R14) && is1248) return o;
585 if (o == GOF(R15) && is1248) return o;
586
587 if (o == GOF(CC_DEP1) && sz == 8) return o;
588 if (o == GOF(CC_DEP2) && sz == 8) return o;
589
590 if (o == GOF(CC_OP) && sz == 8) return -1; /* slot used for %AH */
591 if (o == GOF(CC_NDEP) && sz == 8) return -1; /* slot used for %BH */
592 if (o == GOF(DFLAG) && sz == 8) return -1; /* slot used for %CH */
593 if (o == GOF(RIP) && sz == 8) return -1; /* slot unused */
sewardj71633b12009-03-30 02:27:29 +0000594 if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000595 if (o == GOF(IDFLAG) && sz == 8) return -1; /* slot used for %DH */
sewardj65864932010-09-28 16:00:11 +0000596 if (o == GOF(ACFLAG) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000597 if (o == GOF(FS_ZERO) && sz == 8) return -1; /* slot unused */
njnf76d27a2009-05-28 01:53:07 +0000598 if (o == GOF(GS_0x60) && sz == 8) return -1; /* slot unused */
sewardj105e69c2008-05-09 23:26:19 +0000599 if (o == GOF(TISTART) && sz == 8) return -1; /* slot unused */
600 if (o == GOF(TILEN) && sz == 8) return -1; /* slot unused */
sewardj3d5246f2013-01-29 21:13:00 +0000601 if (o == GOF(NRADDR) && sz == 8) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000602
603 /* Treat %AH, %BH, %CH, %DH as independent registers. To do this
604 requires finding 4 unused 32-bit slots in the second-shadow
605 guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG, since
606 none of those are tracked. */
607 tl_assert(SZB(CC_OP) == 8);
608 tl_assert(SZB(CC_NDEP) == 8);
609 tl_assert(SZB(IDFLAG) == 8);
610 tl_assert(SZB(DFLAG) == 8);
611
612 if (o == 1+ GOF(RAX) && szB == 1) return GOF(CC_OP);
613 if (o == 1+ GOF(RBX) && szB == 1) return GOF(CC_NDEP);
614 if (o == 1+ GOF(RCX) && szB == 1) return GOF(DFLAG);
615 if (o == 1+ GOF(RDX) && szB == 1) return GOF(IDFLAG);
616
617 /* skip XMM and FP admin stuff */
618 if (o == GOF(SSEROUND) && szB == 8) return -1;
619 if (o == GOF(FTOP) && szB == 4) return -1;
620 if (o == GOF(FPROUND) && szB == 8) return -1;
florian2e497412012-08-26 03:22:09 +0000621 if (o == GOF(EMNOTE) && szB == 4) return -1;
sewardj89ea7ab2008-05-27 16:08:24 +0000622 if (o == GOF(FC3210) && szB == 8) return -1;
sewardj7cf4e6b2008-05-01 20:24:26 +0000623
624 /* XMM registers */
sewardj45fa9f42012-05-21 10:18:10 +0000625 if (o >= GOF(YMM0) && o+sz <= GOF(YMM0) +SZB(YMM0)) return GOF(YMM0);
626 if (o >= GOF(YMM1) && o+sz <= GOF(YMM1) +SZB(YMM1)) return GOF(YMM1);
627 if (o >= GOF(YMM2) && o+sz <= GOF(YMM2) +SZB(YMM2)) return GOF(YMM2);
628 if (o >= GOF(YMM3) && o+sz <= GOF(YMM3) +SZB(YMM3)) return GOF(YMM3);
629 if (o >= GOF(YMM4) && o+sz <= GOF(YMM4) +SZB(YMM4)) return GOF(YMM4);
630 if (o >= GOF(YMM5) && o+sz <= GOF(YMM5) +SZB(YMM5)) return GOF(YMM5);
631 if (o >= GOF(YMM6) && o+sz <= GOF(YMM6) +SZB(YMM6)) return GOF(YMM6);
632 if (o >= GOF(YMM7) && o+sz <= GOF(YMM7) +SZB(YMM7)) return GOF(YMM7);
633 if (o >= GOF(YMM8) && o+sz <= GOF(YMM8) +SZB(YMM8)) return GOF(YMM8);
634 if (o >= GOF(YMM9) && o+sz <= GOF(YMM9) +SZB(YMM9)) return GOF(YMM9);
635 if (o >= GOF(YMM10) && o+sz <= GOF(YMM10)+SZB(YMM10)) return GOF(YMM10);
636 if (o >= GOF(YMM11) && o+sz <= GOF(YMM11)+SZB(YMM11)) return GOF(YMM11);
637 if (o >= GOF(YMM12) && o+sz <= GOF(YMM12)+SZB(YMM12)) return GOF(YMM12);
638 if (o >= GOF(YMM13) && o+sz <= GOF(YMM13)+SZB(YMM13)) return GOF(YMM13);
639 if (o >= GOF(YMM14) && o+sz <= GOF(YMM14)+SZB(YMM14)) return GOF(YMM14);
640 if (o >= GOF(YMM15) && o+sz <= GOF(YMM15)+SZB(YMM15)) return GOF(YMM15);
641 if (o >= GOF(YMM16) && o+sz <= GOF(YMM16)+SZB(YMM16)) return GOF(YMM16);
sewardj7cf4e6b2008-05-01 20:24:26 +0000642
sewardjf1a483a2008-06-13 07:44:02 +0000643 /* MMX accesses to FP regs. Need to allow for 32-bit references
644 due to dirty helpers for frstor etc, which reference the entire
645 64-byte block in one go. */
646 if (o >= GOF(FPREG[0])
647 && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
648 if (o >= GOF(FPREG[1])
649 && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
650 if (o >= GOF(FPREG[2])
651 && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
652 if (o >= GOF(FPREG[3])
653 && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
654 if (o >= GOF(FPREG[4])
655 && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
656 if (o >= GOF(FPREG[5])
657 && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
658 if (o >= GOF(FPREG[6])
659 && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
660 if (o >= GOF(FPREG[7])
661 && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
sewardj7cf4e6b2008-05-01 20:24:26 +0000662
663 /* Map high halves of %RAX,%RCX,%RDX,%RBX to the whole register.
664 This is needed because the general handling of dirty helper
665 calls is done in 4 byte chunks. Hence we will see these.
666 Currently we only expect to see artefacts from CPUID. */
667 if (o == 4+ GOF(RAX) && sz == 4) return GOF(RAX);
668 if (o == 4+ GOF(RCX) && sz == 4) return GOF(RCX);
669 if (o == 4+ GOF(RDX) && sz == 4) return GOF(RDX);
670 if (o == 4+ GOF(RBX) && sz == 4) return GOF(RBX);
671
672 VG_(printf)("MC_(get_otrack_shadow_offset)(amd64)(off=%d,sz=%d)\n",
673 offset,szB);
674 tl_assert(0);
675# undef GOF
676# undef SZB
677
678 /* --------------------- x86 --------------------- */
679
680# elif defined(VGA_x86)
681
682# define GOF(_fieldname) \
683 (offsetof(VexGuestX86State,guest_##_fieldname))
684# define SZB(_fieldname) \
685 (sizeof(((VexGuestX86State*)0)->guest_##_fieldname))
686
687 Int o = offset;
688 Int sz = szB;
689 Bool is124 = sz == 4 || sz == 2 || sz == 1;
690 tl_assert(sz > 0);
691 tl_assert(host_is_little_endian());
692
693 if (o == GOF(EAX) && is124) return o;
694 if (o == GOF(ECX) && is124) return o;
695 if (o == GOF(EDX) && is124) return o;
696 if (o == GOF(EBX) && is124) return o;
697 if (o == GOF(ESP) && is124) return o;
698 if (o == GOF(EBP) && is124) return o;
699 if (o == GOF(ESI) && is124) return o;
700 if (o == GOF(EDI) && is124) return o;
701
702 if (o == GOF(CC_DEP1) && sz == 4) return o;
703 if (o == GOF(CC_DEP2) && sz == 4) return o;
704
705 if (o == GOF(CC_OP) && sz == 4) return -1; /* slot used for %AH */
706 if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot used for %BH */
707 if (o == GOF(DFLAG) && sz == 4) return -1; /* slot used for %CH */
708 if (o == GOF(EIP) && sz == 4) return -1; /* slot unused */
sewardj71633b12009-03-30 02:27:29 +0000709 if (o == GOF(IP_AT_SYSCALL) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000710 if (o == GOF(IDFLAG) && sz == 4) return -1; /* slot used for %DH */
711 if (o == GOF(ACFLAG) && sz == 4) return -1; /* slot unused */
sewardj105e69c2008-05-09 23:26:19 +0000712 if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
713 if (o == GOF(TILEN) && sz == 4) return -1; /* slot unused */
sewardj5575f052011-01-28 00:53:37 +0000714 if (o == GOF(NRADDR) && sz == 4) return -1; /* slot unused */
sewardj7cf4e6b2008-05-01 20:24:26 +0000715
716 /* Treat %AH, %BH, %CH, %DH as independent registers. To do this
717 requires finding 4 unused 32-bit slots in the second-shadow
718 guest state, respectively: CC_OP CC_NDEP DFLAG IDFLAG since none
719 of those are tracked. */
720 tl_assert(SZB(CC_OP) == 4);
721 tl_assert(SZB(CC_NDEP) == 4);
722 tl_assert(SZB(DFLAG) == 4);
723 tl_assert(SZB(IDFLAG) == 4);
724 if (o == 1+ GOF(EAX) && szB == 1) return GOF(CC_OP);
725 if (o == 1+ GOF(EBX) && szB == 1) return GOF(CC_NDEP);
726 if (o == 1+ GOF(ECX) && szB == 1) return GOF(DFLAG);
727 if (o == 1+ GOF(EDX) && szB == 1) return GOF(IDFLAG);
728
729 /* skip XMM and FP admin stuff */
730 if (o == GOF(SSEROUND) && szB == 4) return -1;
731 if (o == GOF(FTOP) && szB == 4) return -1;
732 if (o == GOF(FPROUND) && szB == 4) return -1;
florian2e497412012-08-26 03:22:09 +0000733 if (o == GOF(EMNOTE) && szB == 4) return -1;
sewardj7cf4e6b2008-05-01 20:24:26 +0000734 if (o == GOF(FC3210) && szB == 4) return -1;
735
736 /* XMM registers */
737 if (o >= GOF(XMM0) && o+sz <= GOF(XMM0)+SZB(XMM0)) return GOF(XMM0);
738 if (o >= GOF(XMM1) && o+sz <= GOF(XMM1)+SZB(XMM1)) return GOF(XMM1);
739 if (o >= GOF(XMM2) && o+sz <= GOF(XMM2)+SZB(XMM2)) return GOF(XMM2);
740 if (o >= GOF(XMM3) && o+sz <= GOF(XMM3)+SZB(XMM3)) return GOF(XMM3);
741 if (o >= GOF(XMM4) && o+sz <= GOF(XMM4)+SZB(XMM4)) return GOF(XMM4);
742 if (o >= GOF(XMM5) && o+sz <= GOF(XMM5)+SZB(XMM5)) return GOF(XMM5);
743 if (o >= GOF(XMM6) && o+sz <= GOF(XMM6)+SZB(XMM6)) return GOF(XMM6);
744 if (o >= GOF(XMM7) && o+sz <= GOF(XMM7)+SZB(XMM7)) return GOF(XMM7);
745
746 /* MMX accesses to FP regs. Need to allow for 32-bit references
747 due to dirty helpers for frstor etc, which reference the entire
748 64-byte block in one go. */
749 if (o >= GOF(FPREG[0])
750 && o+sz <= GOF(FPREG[0])+SZB(FPREG[0])) return GOF(FPREG[0]);
751 if (o >= GOF(FPREG[1])
752 && o+sz <= GOF(FPREG[1])+SZB(FPREG[1])) return GOF(FPREG[1]);
753 if (o >= GOF(FPREG[2])
754 && o+sz <= GOF(FPREG[2])+SZB(FPREG[2])) return GOF(FPREG[2]);
755 if (o >= GOF(FPREG[3])
756 && o+sz <= GOF(FPREG[3])+SZB(FPREG[3])) return GOF(FPREG[3]);
757 if (o >= GOF(FPREG[4])
758 && o+sz <= GOF(FPREG[4])+SZB(FPREG[4])) return GOF(FPREG[4]);
759 if (o >= GOF(FPREG[5])
760 && o+sz <= GOF(FPREG[5])+SZB(FPREG[5])) return GOF(FPREG[5]);
761 if (o >= GOF(FPREG[6])
762 && o+sz <= GOF(FPREG[6])+SZB(FPREG[6])) return GOF(FPREG[6]);
763 if (o >= GOF(FPREG[7])
764 && o+sz <= GOF(FPREG[7])+SZB(FPREG[7])) return GOF(FPREG[7]);
765
766 /* skip %GS and other segment related stuff. We could shadow
767 guest_LDT and guest_GDT, although it seems pointless.
768 guest_CS .. guest_SS are too small to shadow directly and it
769 also seems pointless to shadow them indirectly (that is, in
770 the style of %AH .. %DH). */
771 if (o == GOF(CS) && sz == 2) return -1;
772 if (o == GOF(DS) && sz == 2) return -1;
773 if (o == GOF(ES) && sz == 2) return -1;
774 if (o == GOF(FS) && sz == 2) return -1;
775 if (o == GOF(GS) && sz == 2) return -1;
776 if (o == GOF(SS) && sz == 2) return -1;
777 if (o == GOF(LDT) && sz == 4) return -1;
778 if (o == GOF(GDT) && sz == 4) return -1;
779
780 VG_(printf)("MC_(get_otrack_shadow_offset)(x86)(off=%d,sz=%d)\n",
781 offset,szB);
782 tl_assert(0);
783# undef GOF
784# undef SZB
785
sewardjb5b87402011-03-07 16:05:35 +0000786 /* -------------------- s390x -------------------- */
787
788# elif defined(VGA_s390x)
789# define GOF(_fieldname) \
790 (offsetof(VexGuestS390XState,guest_##_fieldname))
791 Int o = offset;
792 Int sz = szB;
793 tl_assert(sz > 0);
794 tl_assert(host_is_big_endian());
795
796 /* no matter what byte(s) we change, we have changed the full 8 byte value
797 and need to track this change for the whole register */
798 if (o >= GOF(r0) && sz <= 8 && o <= (GOF(r15) + 8 - sz))
799 return GOF(r0) + ((o-GOF(r0)) & -8) ;
800
801
802 /* fprs are accessed 4 or 8 byte at once. Again, we track that change for
803 the full register */
804 if ((sz == 8 || sz == 4) && o >= GOF(f0) && o <= GOF(f15)+8-sz)
805 return GOF(f0) + ((o-GOF(f0)) & -8) ;
806
807 /* access registers are accessed 4 bytes at once */
808 if (sz == 4 && o >= GOF(a0) && o <= GOF(a15))
florian30e2d652012-09-03 17:34:22 +0000809 return o;
sewardjb5b87402011-03-07 16:05:35 +0000810
811 /* we access the guest counter either fully or one of the 4byte words */
812 if (o == GOF(counter) && (sz == 8 || sz ==4))
813 return o;
814 if (o == GOF(counter) + 4 && sz == 4)
815 return o;
816
florian30e2d652012-09-03 17:34:22 +0000817 if (o == GOF(EMNOTE) && sz == 4) return -1;
818
819 if (o == GOF(CC_OP) && sz == 8) return -1;
florian234955d2013-05-31 15:44:06 +0000820 /* We access CC_DEP1 either fully or bits [0:31] */
821 if (o == GOF(CC_DEP1) && (sz == 8 || sz ==4))
822 return o;
florian30e2d652012-09-03 17:34:22 +0000823 if (o == GOF(CC_DEP2) && sz == 8) return o;
824 if (o == GOF(CC_NDEP) && sz == 8) return -1;
825 if (o == GOF(TISTART) && sz == 8) return -1;
826 if (o == GOF(TILEN) && sz == 8) return -1;
827 if (o == GOF(NRADDR) && sz == 8) return -1;
828 if (o == GOF(IP_AT_SYSCALL) && sz == 8) return -1;
florian4fea8402012-09-11 23:06:02 +0000829 if (o == GOF(fpc) && sz == 4) return -1;
florian30e2d652012-09-03 17:34:22 +0000830 if (o == GOF(IA) && sz == 8) return -1;
831 if (o == (GOF(IA) + 4) && sz == 4) return -1;
832 if (o == GOF(SYSNO) && sz == 8) return -1;
sewardjb5b87402011-03-07 16:05:35 +0000833 VG_(printf)("MC_(get_otrack_shadow_offset)(s390x)(off=%d,sz=%d)\n",
834 offset,szB);
835 tl_assert(0);
836# undef GOF
837
838
sewardj59570ff2010-01-01 11:59:33 +0000839 /* --------------------- arm --------------------- */
840
841# elif defined(VGA_arm)
842
843# define GOF(_fieldname) \
844 (offsetof(VexGuestARMState,guest_##_fieldname))
845# define SZB(_fieldname) \
846 (sizeof(((VexGuestARMState*)0)->guest_##_fieldname))
847
848 Int o = offset;
849 Int sz = szB;
850 tl_assert(sz > 0);
851 tl_assert(host_is_little_endian());
852
853 if (o == GOF(R0) && sz == 4) return o;
854 if (o == GOF(R1) && sz == 4) return o;
855 if (o == GOF(R2) && sz == 4) return o;
856 if (o == GOF(R3) && sz == 4) return o;
857 if (o == GOF(R4) && sz == 4) return o;
858 if (o == GOF(R5) && sz == 4) return o;
859 if (o == GOF(R6) && sz == 4) return o;
860 if (o == GOF(R7) && sz == 4) return o;
861 if (o == GOF(R8) && sz == 4) return o;
862 if (o == GOF(R9) && sz == 4) return o;
863 if (o == GOF(R10) && sz == 4) return o;
864 if (o == GOF(R11) && sz == 4) return o;
865 if (o == GOF(R12) && sz == 4) return o;
866 if (o == GOF(R13) && sz == 4) return o;
867 if (o == GOF(R14) && sz == 4) return o;
868
869 /* EAZG: These may be completely wrong. */
sewardjca9054a2010-08-22 12:16:25 +0000870 if (o == GOF(R15T) && sz == 4) return -1; /* slot unused */
sewardj59570ff2010-01-01 11:59:33 +0000871 if (o == GOF(CC_OP) && sz == 4) return -1; /* slot unused */
872
873 if (o == GOF(CC_DEP1) && sz == 4) return o;
874 if (o == GOF(CC_DEP2) && sz == 4) return o;
875
876 if (o == GOF(CC_NDEP) && sz == 4) return -1; /* slot unused */
877
sewardjca9054a2010-08-22 12:16:25 +0000878 if (o == GOF(QFLAG32) && sz == 4) return o;
879
sewardj6fede422010-09-22 22:27:41 +0000880 if (o == GOF(GEFLAG0) && sz == 4) return o;
881 if (o == GOF(GEFLAG1) && sz == 4) return o;
882 if (o == GOF(GEFLAG2) && sz == 4) return o;
883 if (o == GOF(GEFLAG3) && sz == 4) return o;
884
sewardj59570ff2010-01-01 11:59:33 +0000885 //if (o == GOF(SYSCALLNO) && sz == 4) return -1; /* slot unused */
886 //if (o == GOF(CC) && sz == 4) return -1; /* slot unused */
florian2e497412012-08-26 03:22:09 +0000887 //if (o == GOF(EMNOTE) && sz == 4) return -1; /* slot unused */
sewardj59570ff2010-01-01 11:59:33 +0000888 //if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
889 //if (o == GOF(NRADDR) && sz == 4) return -1; /* slot unused */
890
891 if (o == GOF(FPSCR) && sz == 4) return -1;
892 if (o == GOF(TPIDRURO) && sz == 4) return -1;
sewardjca9054a2010-08-22 12:16:25 +0000893 if (o == GOF(ITSTATE) && sz == 4) return -1;
sewardj59570ff2010-01-01 11:59:33 +0000894
sewardj8f6ec702010-09-29 21:40:44 +0000895 /* Accesses to F or D registers */
896 if (sz == 4 || sz == 8) {
897 if (o >= GOF(D0) && o+sz <= GOF(D0) +SZB(D0)) return GOF(D0);
898 if (o >= GOF(D1) && o+sz <= GOF(D1) +SZB(D1)) return GOF(D1);
899 if (o >= GOF(D2) && o+sz <= GOF(D2) +SZB(D2)) return GOF(D2);
900 if (o >= GOF(D3) && o+sz <= GOF(D3) +SZB(D3)) return GOF(D3);
901 if (o >= GOF(D4) && o+sz <= GOF(D4) +SZB(D4)) return GOF(D4);
902 if (o >= GOF(D5) && o+sz <= GOF(D5) +SZB(D5)) return GOF(D5);
903 if (o >= GOF(D6) && o+sz <= GOF(D6) +SZB(D6)) return GOF(D6);
904 if (o >= GOF(D7) && o+sz <= GOF(D7) +SZB(D7)) return GOF(D7);
905 if (o >= GOF(D8) && o+sz <= GOF(D8) +SZB(D8)) return GOF(D8);
906 if (o >= GOF(D9) && o+sz <= GOF(D9) +SZB(D9)) return GOF(D9);
907 if (o >= GOF(D10) && o+sz <= GOF(D10)+SZB(D10)) return GOF(D10);
908 if (o >= GOF(D11) && o+sz <= GOF(D11)+SZB(D11)) return GOF(D11);
909 if (o >= GOF(D12) && o+sz <= GOF(D12)+SZB(D12)) return GOF(D12);
910 if (o >= GOF(D13) && o+sz <= GOF(D13)+SZB(D13)) return GOF(D13);
911 if (o >= GOF(D14) && o+sz <= GOF(D14)+SZB(D14)) return GOF(D14);
912 if (o >= GOF(D15) && o+sz <= GOF(D15)+SZB(D15)) return GOF(D15);
913 if (o >= GOF(D16) && o+sz <= GOF(D16)+SZB(D16)) return GOF(D16);
914 if (o >= GOF(D17) && o+sz <= GOF(D17)+SZB(D17)) return GOF(D17);
915 if (o >= GOF(D18) && o+sz <= GOF(D18)+SZB(D18)) return GOF(D18);
916 if (o >= GOF(D19) && o+sz <= GOF(D19)+SZB(D19)) return GOF(D19);
917 if (o >= GOF(D20) && o+sz <= GOF(D20)+SZB(D20)) return GOF(D20);
918 if (o >= GOF(D21) && o+sz <= GOF(D21)+SZB(D21)) return GOF(D21);
919 if (o >= GOF(D22) && o+sz <= GOF(D22)+SZB(D22)) return GOF(D22);
920 if (o >= GOF(D23) && o+sz <= GOF(D23)+SZB(D23)) return GOF(D23);
921 if (o >= GOF(D24) && o+sz <= GOF(D24)+SZB(D24)) return GOF(D24);
922 if (o >= GOF(D25) && o+sz <= GOF(D25)+SZB(D25)) return GOF(D25);
923 if (o >= GOF(D26) && o+sz <= GOF(D26)+SZB(D26)) return GOF(D26);
924 if (o >= GOF(D27) && o+sz <= GOF(D27)+SZB(D27)) return GOF(D27);
925 if (o >= GOF(D28) && o+sz <= GOF(D28)+SZB(D28)) return GOF(D28);
926 if (o >= GOF(D29) && o+sz <= GOF(D29)+SZB(D29)) return GOF(D29);
927 if (o >= GOF(D30) && o+sz <= GOF(D30)+SZB(D30)) return GOF(D30);
928 if (o >= GOF(D31) && o+sz <= GOF(D31)+SZB(D31)) return GOF(D31);
929 }
930
931 /* Accesses to Q registers */
932 if (sz == 16) {
933 if (o >= GOF(D0) && o+sz <= GOF(D0) +2*SZB(D0)) return GOF(D0); // Q0
934 if (o >= GOF(D2) && o+sz <= GOF(D2) +2*SZB(D2)) return GOF(D2); // Q1
935 if (o >= GOF(D4) && o+sz <= GOF(D4) +2*SZB(D4)) return GOF(D4); // Q2
936 if (o >= GOF(D6) && o+sz <= GOF(D6) +2*SZB(D6)) return GOF(D6); // Q3
937 if (o >= GOF(D8) && o+sz <= GOF(D8) +2*SZB(D8)) return GOF(D8); // Q4
938 if (o >= GOF(D10) && o+sz <= GOF(D10)+2*SZB(D10)) return GOF(D10); // Q5
939 if (o >= GOF(D12) && o+sz <= GOF(D12)+2*SZB(D12)) return GOF(D12); // Q6
940 if (o >= GOF(D14) && o+sz <= GOF(D14)+2*SZB(D14)) return GOF(D14); // Q7
941 if (o >= GOF(D16) && o+sz <= GOF(D16)+2*SZB(D16)) return GOF(D16); // Q8
942 if (o >= GOF(D18) && o+sz <= GOF(D18)+2*SZB(D18)) return GOF(D18); // Q9
943 if (o >= GOF(D20) && o+sz <= GOF(D20)+2*SZB(D20)) return GOF(D20); // Q10
944 if (o >= GOF(D22) && o+sz <= GOF(D22)+2*SZB(D22)) return GOF(D22); // Q11
945 if (o >= GOF(D24) && o+sz <= GOF(D24)+2*SZB(D24)) return GOF(D24); // Q12
946 if (o >= GOF(D26) && o+sz <= GOF(D26)+2*SZB(D26)) return GOF(D26); // Q13
947 if (o >= GOF(D28) && o+sz <= GOF(D28)+2*SZB(D28)) return GOF(D28); // Q14
948 if (o >= GOF(D30) && o+sz <= GOF(D30)+2*SZB(D30)) return GOF(D30); // Q15
949 }
sewardj59570ff2010-01-01 11:59:33 +0000950
sewardjb29b6492012-12-13 15:17:40 +0000951 if (o == GOF(TISTART) && sz == 4) return -1;
952 if (o == GOF(TILEN) && sz == 4) return -1;
953
sewardj59570ff2010-01-01 11:59:33 +0000954 VG_(printf)("MC_(get_otrack_shadow_offset)(arm)(off=%d,sz=%d)\n",
955 offset,szB);
956 tl_assert(0);
957# undef GOF
958# undef SZB
959
sewardj5db15402012-06-07 09:13:21 +0000960 /* --------------------- mips32 --------------------- */
961
962# elif defined(VGA_mips32)
963
964# define GOF(_fieldname) \
965 (offsetof(VexGuestMIPS32State,guest_##_fieldname))
966# define SZB(_fieldname) \
967 (sizeof(((VexGuestMIPS32State*)0)->guest_##_fieldname))
968
969 Int o = offset;
970 Int sz = szB;
971 tl_assert(sz > 0);
972# if defined (VG_LITTLEENDIAN)
973 tl_assert(host_is_little_endian());
974# elif defined (VG_BIGENDIAN)
975 tl_assert(host_is_big_endian());
976# else
977# error "Unknown endianness"
978# endif
979
980 if (o == GOF(r0) && sz == 4) return o;
981 if (o == GOF(r1) && sz == 4) return o;
982 if (o == GOF(r2) && sz == 4) return o;
983 if (o == GOF(r3) && sz == 4) return o;
984 if (o == GOF(r4) && sz == 4) return o;
985 if (o == GOF(r5) && sz == 4) return o;
986 if (o == GOF(r6) && sz == 4) return o;
987 if (o == GOF(r7) && sz == 4) return o;
988 if (o == GOF(r8) && sz == 4) return o;
989 if (o == GOF(r9) && sz == 4) return o;
990 if (o == GOF(r10) && sz == 4) return o;
991 if (o == GOF(r11) && sz == 4) return o;
992 if (o == GOF(r12) && sz == 4) return o;
993 if (o == GOF(r13) && sz == 4) return o;
994 if (o == GOF(r14) && sz == 4) return o;
995 if (o == GOF(r15) && sz == 4) return o;
996 if (o == GOF(r16) && sz == 4) return o;
997 if (o == GOF(r17) && sz == 4) return o;
998 if (o == GOF(r18) && sz == 4) return o;
999 if (o == GOF(r19) && sz == 4) return o;
1000 if (o == GOF(r20) && sz == 4) return o;
1001 if (o == GOF(r21) && sz == 4) return o;
1002 if (o == GOF(r22) && sz == 4) return o;
1003 if (o == GOF(r23) && sz == 4) return o;
1004 if (o == GOF(r24) && sz == 4) return o;
1005 if (o == GOF(r25) && sz == 4) return o;
1006 if (o == GOF(r26) && sz == 4) return o;
1007 if (o == GOF(r27) && sz == 4) return o;
1008 if (o == GOF(r28) && sz == 4) return o;
1009 if (o == GOF(r29) && sz == 4) return o;
1010 if (o == GOF(r30) && sz == 4) return o;
1011 if (o == GOF(r31) && sz == 4) return o;
1012 if (o == GOF(PC) && sz == 4) return -1; /* slot unused */
1013
1014 if (o == GOF(HI) && sz == 4) return o;
1015 if (o == GOF(LO) && sz == 4) return o;
1016
1017 if (o == GOF(FIR) && sz == 4) return -1; /* slot unused */
1018 if (o == GOF(FCCR) && sz == 4) return -1; /* slot unused */
1019 if (o == GOF(FEXR) && sz == 4) return -1; /* slot unused */
1020 if (o == GOF(FENR) && sz == 4) return -1; /* slot unused */
1021 if (o == GOF(FCSR) && sz == 4) return -1; /* slot unused */
1022 if (o == GOF(ULR) && sz == 4) return -1;
1023
florian2e497412012-08-26 03:22:09 +00001024 if (o == GOF(EMNOTE) && sz == 4) return -1; /* slot unused */
sewardj5db15402012-06-07 09:13:21 +00001025 if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
1026 if (o == GOF(TILEN) && sz == 4) return -1; /* slot unused */
1027 if (o == GOF(NRADDR) && sz == 4) return -1; /* slot unused */
1028
1029 if (o >= GOF(f0) && o+sz <= GOF(f0) +SZB(f0)) return GOF(f0);
1030 if (o >= GOF(f1) && o+sz <= GOF(f1) +SZB(f1)) return GOF(f1);
1031 if (o >= GOF(f2) && o+sz <= GOF(f2) +SZB(f2)) return GOF(f2);
1032 if (o >= GOF(f3) && o+sz <= GOF(f3) +SZB(f3)) return GOF(f3);
1033 if (o >= GOF(f4) && o+sz <= GOF(f4) +SZB(f4)) return GOF(f4);
1034 if (o >= GOF(f5) && o+sz <= GOF(f5) +SZB(f5)) return GOF(f5);
1035 if (o >= GOF(f6) && o+sz <= GOF(f6) +SZB(f6)) return GOF(f6);
1036 if (o >= GOF(f7) && o+sz <= GOF(f7) +SZB(f7)) return GOF(f7);
1037 if (o >= GOF(f8) && o+sz <= GOF(f8) +SZB(f8)) return GOF(f8);
1038 if (o >= GOF(f9) && o+sz <= GOF(f9) +SZB(f9)) return GOF(f9);
1039 if (o >= GOF(f10) && o+sz <= GOF(f10)+SZB(f10)) return GOF(f10);
1040 if (o >= GOF(f11) && o+sz <= GOF(f11)+SZB(f11)) return GOF(f11);
1041 if (o >= GOF(f12) && o+sz <= GOF(f12)+SZB(f12)) return GOF(f12);
1042 if (o >= GOF(f13) && o+sz <= GOF(f13)+SZB(f13)) return GOF(f13);
1043 if (o >= GOF(f14) && o+sz <= GOF(f14)+SZB(f14)) return GOF(f14);
1044 if (o >= GOF(f15) && o+sz <= GOF(f15)+SZB(f15)) return GOF(f15);
1045
1046 if (o >= GOF(f16) && o+sz <= GOF(f16)+SZB(f16)) return GOF(f16);
1047 if (o >= GOF(f17) && o+sz <= GOF(f17) +SZB(f17)) return GOF(f17);
1048 if (o >= GOF(f18) && o+sz <= GOF(f18) +SZB(f18)) return GOF(f18);
1049 if (o >= GOF(f19) && o+sz <= GOF(f19) +SZB(f19)) return GOF(f19);
1050 if (o >= GOF(f20) && o+sz <= GOF(f20) +SZB(f20)) return GOF(f20);
1051 if (o >= GOF(f21) && o+sz <= GOF(f21) +SZB(f21)) return GOF(f21);
1052 if (o >= GOF(f22) && o+sz <= GOF(f22) +SZB(f22)) return GOF(f22);
1053 if (o >= GOF(f23) && o+sz <= GOF(f23) +SZB(f23)) return GOF(f23);
1054 if (o >= GOF(f24) && o+sz <= GOF(f24) +SZB(f24)) return GOF(f24);
1055 if (o >= GOF(f25) && o+sz <= GOF(f25) +SZB(f25)) return GOF(f25);
1056 if (o >= GOF(f26) && o+sz <= GOF(f26)+SZB(f26)) return GOF(f26);
1057 if (o >= GOF(f27) && o+sz <= GOF(f27)+SZB(f27)) return GOF(f27);
1058 if (o >= GOF(f28) && o+sz <= GOF(f28)+SZB(f28)) return GOF(f28);
1059 if (o >= GOF(f29) && o+sz <= GOF(f29)+SZB(f29)) return GOF(f29);
1060 if (o >= GOF(f30) && o+sz <= GOF(f30)+SZB(f30)) return GOF(f30);
1061 if (o >= GOF(f31) && o+sz <= GOF(f31)+SZB(f31)) return GOF(f31);
1062
dejanj5f790e82013-07-25 08:22:08 +00001063 /* Slot unused. */
1064 if ((o > GOF(NRADDR)) && (o <= GOF(NRADDR) +12 )) return -1;
1065
1066 /* MIPS32 DSP ASE(r2) specific registers. */
1067 if (o == GOF(DSPControl) && sz == 4) return o;
1068 if (o == GOF(ac0) && sz == 8) return o;
1069 if (o == GOF(ac1) && sz == 8) return o;
1070 if (o == GOF(ac2) && sz == 8) return o;
1071 if (o == GOF(ac3) && sz == 8) return o;
sewardj5db15402012-06-07 09:13:21 +00001072
1073 VG_(printf)("MC_(get_otrack_shadow_offset)(mips)(off=%d,sz=%d)\n",
1074 offset,szB);
1075 tl_assert(0);
1076# undef GOF
1077# undef SZB
1078
petarj4df0bfc2013-02-27 23:17:33 +00001079 /* --------------------- mips64 --------------------- */
1080
1081# elif defined(VGA_mips64)
1082
1083# define GOF(_fieldname) \
1084 (offsetof(VexGuestMIPS64State,guest_##_fieldname))
1085# define SZB(_fieldname) \
1086 (sizeof(((VexGuestMIPS64State*)0)->guest_##_fieldname))
1087
1088 Int o = offset;
1089 Int sz = szB;
1090 tl_assert(sz > 0);
1091#if defined (VG_LITTLEENDIAN)
1092 tl_assert(host_is_little_endian());
1093#elif defined (VG_BIGENDIAN)
1094 tl_assert(host_is_big_endian());
1095#endif
1096
1097 if (o >= GOF(r0) && sz <= 8 && o <= (GOF(r31) + 8 - sz))
1098 return GOF(r0) + ((o-GOF(r0)) & -8) ;
1099
1100 if (o == GOF(PC) && sz == 8) return -1; /* slot unused */
1101
1102 if (o == GOF(HI) && sz == 8) return o;
1103 if (o == GOF(LO) && sz == 8) return o;
1104
1105 if (o == GOF(FIR) && sz == 4) return -1; /* slot unused */
1106 if (o == GOF(FCCR) && sz == 4) return -1; /* slot unused */
1107 if (o == GOF(FEXR) && sz == 4) return -1; /* slot unused */
1108 if (o == GOF(FENR) && sz == 4) return -1; /* slot unused */
1109 if (o == GOF(FCSR) && sz == 4) return -1; /* slot unused */
1110 if (o == GOF(ULR) && sz == 8) return o;
1111
1112 if (o == GOF(EMNOTE) && sz == 4) return -1; /* slot unused */
1113 if (o == GOF(TISTART) && sz == 4) return -1; /* slot unused */
1114 if (o == GOF(TILEN) && sz == 4) return -1; /* slot unused */
1115 if (o == GOF(NRADDR) && sz == 4) return -1; /* slot unused */
1116
1117 if (o >= GOF(f0) && o+sz <= GOF(f0) +SZB(f0)) return GOF(f0);
1118 if (o >= GOF(f1) && o+sz <= GOF(f1) +SZB(f1)) return GOF(f1);
1119 if (o >= GOF(f2) && o+sz <= GOF(f2) +SZB(f2)) return GOF(f2);
1120 if (o >= GOF(f3) && o+sz <= GOF(f3) +SZB(f3)) return GOF(f3);
1121 if (o >= GOF(f4) && o+sz <= GOF(f4) +SZB(f4)) return GOF(f4);
1122 if (o >= GOF(f5) && o+sz <= GOF(f5) +SZB(f5)) return GOF(f5);
1123 if (o >= GOF(f6) && o+sz <= GOF(f6) +SZB(f6)) return GOF(f6);
1124 if (o >= GOF(f7) && o+sz <= GOF(f7) +SZB(f7)) return GOF(f7);
1125 if (o >= GOF(f8) && o+sz <= GOF(f8) +SZB(f8)) return GOF(f8);
1126 if (o >= GOF(f9) && o+sz <= GOF(f9) +SZB(f9)) return GOF(f9);
1127 if (o >= GOF(f10) && o+sz <= GOF(f10)+SZB(f10)) return GOF(f10);
1128 if (o >= GOF(f11) && o+sz <= GOF(f11)+SZB(f11)) return GOF(f11);
1129 if (o >= GOF(f12) && o+sz <= GOF(f12)+SZB(f12)) return GOF(f12);
1130 if (o >= GOF(f13) && o+sz <= GOF(f13)+SZB(f13)) return GOF(f13);
1131 if (o >= GOF(f14) && o+sz <= GOF(f14)+SZB(f14)) return GOF(f14);
1132 if (o >= GOF(f15) && o+sz <= GOF(f15)+SZB(f15)) return GOF(f15);
1133 if (o >= GOF(f16) && o+sz <= GOF(f16)+SZB(f16)) return GOF(f16);
1134 if (o >= GOF(f17) && o+sz <= GOF(f17)+SZB(f17)) return GOF(f17);
1135 if (o >= GOF(f18) && o+sz <= GOF(f18)+SZB(f18)) return GOF(f18);
1136 if (o >= GOF(f19) && o+sz <= GOF(f19)+SZB(f19)) return GOF(f19);
1137 if (o >= GOF(f20) && o+sz <= GOF(f20)+SZB(f20)) return GOF(f20);
1138 if (o >= GOF(f21) && o+sz <= GOF(f21)+SZB(f21)) return GOF(f21);
1139 if (o >= GOF(f22) && o+sz <= GOF(f22)+SZB(f22)) return GOF(f22);
1140 if (o >= GOF(f23) && o+sz <= GOF(f23)+SZB(f23)) return GOF(f23);
1141 if (o >= GOF(f24) && o+sz <= GOF(f24)+SZB(f24)) return GOF(f24);
1142 if (o >= GOF(f25) && o+sz <= GOF(f25)+SZB(f25)) return GOF(f25);
1143 if (o >= GOF(f26) && o+sz <= GOF(f26)+SZB(f26)) return GOF(f26);
1144 if (o >= GOF(f27) && o+sz <= GOF(f27)+SZB(f27)) return GOF(f27);
1145 if (o >= GOF(f28) && o+sz <= GOF(f28)+SZB(f28)) return GOF(f28);
1146 if (o >= GOF(f29) && o+sz <= GOF(f29)+SZB(f29)) return GOF(f29);
1147 if (o >= GOF(f30) && o+sz <= GOF(f30)+SZB(f30)) return GOF(f30);
1148 if (o >= GOF(f31) && o+sz <= GOF(f31)+SZB(f31)) return GOF(f31);
1149
1150 if ((o > GOF(NRADDR)) && (o <= GOF(NRADDR) +12 )) return -1;
1151
1152 VG_(printf)("MC_(get_otrack_shadow_offset)(mips)(off=%d,sz=%d)\n",
1153 offset,szB);
1154 tl_assert(0);
1155# undef GOF
1156# undef SZB
1157
sewardj7cf4e6b2008-05-01 20:24:26 +00001158# else
1159# error "FIXME: not implemented for this architecture"
1160# endif
1161}
1162
1163
1164/* Let 'arr' describe an indexed reference to a guest state section
1165 (guest state array).
1166
1167 This function returns the corresponding guest state type to be used
1168 when indexing the corresponding array in the second shadow (origin
1169 tracking) area. If the array is not to be origin-tracked, return
1170 Ity_INVALID.
1171
1172 This function must agree with MC_(get_otrack_shadow_offset) above.
1173 See comments at the start of MC_(get_otrack_shadow_offset).
1174*/
1175IRType MC_(get_otrack_reg_array_equiv_int_type) ( IRRegArray* arr )
1176{
1177 /* -------------------- ppc64 -------------------- */
1178# if defined(VGA_ppc64)
1179 /* The redir stack. */
1180 if (arr->base == offsetof(VexGuestPPC64State,guest_REDIR_STACK[0])
1181 && arr->elemTy == Ity_I64
1182 && arr->nElems == VEX_GUEST_PPC64_REDIR_STACK_SIZE)
1183 return Ity_I64;
1184
1185 VG_(printf)("get_reg_array_equiv_int_type(ppc64): unhandled: ");
1186 ppIRRegArray(arr);
1187 VG_(printf)("\n");
1188 tl_assert(0);
1189
1190 /* -------------------- ppc32 -------------------- */
1191# elif defined(VGA_ppc32)
1192 /* The redir stack. */
1193 if (arr->base == offsetof(VexGuestPPC32State,guest_REDIR_STACK[0])
1194 && arr->elemTy == Ity_I32
1195 && arr->nElems == VEX_GUEST_PPC32_REDIR_STACK_SIZE)
1196 return Ity_I32;
1197
1198 VG_(printf)("get_reg_array_equiv_int_type(ppc32): unhandled: ");
1199 ppIRRegArray(arr);
1200 VG_(printf)("\n");
1201 tl_assert(0);
1202
1203 /* -------------------- amd64 -------------------- */
1204# elif defined(VGA_amd64)
1205 /* Ignore the FP tag array - pointless to shadow, and in any case
1206 the elements are too small */
1207 if (arr->base == offsetof(VexGuestAMD64State,guest_FPTAG)
1208 && arr->elemTy == Ity_I8 && arr->nElems == 8)
1209 return Ity_INVALID;
1210
1211 /* The FP register array */
1212 if (arr->base == offsetof(VexGuestAMD64State,guest_FPREG[0])
1213 && arr->elemTy == Ity_F64 && arr->nElems == 8)
1214 return Ity_I64;
1215
1216 VG_(printf)("get_reg_array_equiv_int_type(amd64): unhandled: ");
1217 ppIRRegArray(arr);
1218 VG_(printf)("\n");
1219 tl_assert(0);
1220
1221 /* --------------------- x86 --------------------- */
1222# elif defined(VGA_x86)
1223 /* Ignore the FP tag array - pointless to shadow, and in any case
1224 the elements are too small */
1225 if (arr->base == offsetof(VexGuestX86State,guest_FPTAG)
1226 && arr->elemTy == Ity_I8 && arr->nElems == 8)
1227 return Ity_INVALID;
1228
1229 /* The FP register array */
1230 if (arr->base == offsetof(VexGuestX86State,guest_FPREG[0])
1231 && arr->elemTy == Ity_F64 && arr->nElems == 8)
1232 return Ity_I64;
1233
1234 VG_(printf)("get_reg_array_equiv_int_type(x86): unhandled: ");
1235 ppIRRegArray(arr);
1236 VG_(printf)("\n");
1237 tl_assert(0);
1238
sewardj59570ff2010-01-01 11:59:33 +00001239 /* --------------------- arm --------------------- */
1240# elif defined(VGA_arm)
sewardj59570ff2010-01-01 11:59:33 +00001241 VG_(printf)("get_reg_array_equiv_int_type(arm): unhandled: ");
1242 ppIRRegArray(arr);
1243 VG_(printf)("\n");
1244 tl_assert(0);
1245
sewardjb5b87402011-03-07 16:05:35 +00001246 /* --------------------- s390x --------------------- */
1247# elif defined(VGA_s390x)
1248 /* Should never het here because s390x does not use Ist_PutI
1249 and Iex_GetI. */
1250 tl_assert(0);
sewardj5db15402012-06-07 09:13:21 +00001251
1252/* --------------------- mips32 --------------------- */
1253# elif defined(VGA_mips32)
1254 VG_(printf)("get_reg_array_equiv_int_type(mips32): unhandled: ");
1255 ppIRRegArray(arr);
1256 VG_(printf)("\n");
1257 tl_assert(0);
1258
petarj4df0bfc2013-02-27 23:17:33 +00001259 /* --------------------- mips64 --------------------- */
1260# elif defined(VGA_mips64)
1261 VG_(printf)("get_reg_array_equiv_int_type(mips64): unhandled: ");
1262 ppIRRegArray(arr);
1263 VG_(printf)("\n");
1264 tl_assert(0);
sewardj7cf4e6b2008-05-01 20:24:26 +00001265# else
1266# error "FIXME: not implemented for this architecture"
1267# endif
1268}
1269
1270
1271/*--------------------------------------------------------------------*/
1272/*--- end mc_machine.c ---*/
1273/*--------------------------------------------------------------------*/