non-linux regtest: update cmdline expecteds
[valgrind.git] / VEX / pub / libvex_guest_x86.h
blob50de8d37983bd0d07970deee6a0f9cd17cf6bdde
2 /*---------------------------------------------------------------*/
3 /*--- begin libvex_guest_x86.h ---*/
4 /*---------------------------------------------------------------*/
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
10 Copyright (C) 2004-2017 OpenWorks LLP
11 info@open-works.net
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, see <http://www.gnu.org/licenses/>.
26 The GNU General Public License is contained in the file COPYING.
28 Neither the names of the U.S. Department of Energy nor the
29 University of California nor the names of its contributors may be
30 used to endorse or promote products derived from this software
31 without prior written permission.
34 #ifndef __LIBVEX_PUB_GUEST_X86_H
35 #define __LIBVEX_PUB_GUEST_X86_H
37 #include "libvex_basictypes.h"
38 #include "libvex_emnote.h"
41 /*---------------------------------------------------------------*/
42 /*--- Vex's representation of the x86 CPU state. ---*/
43 /*---------------------------------------------------------------*/
45 /* The integer parts should be pretty straightforward. */
47 /* Hmm, subregisters. The simulated state is stored in memory in the
48 host's byte ordering, so we can't say here what the offsets of %ax,
49 %al, %ah etc are since that depends on the host's byte ordering,
50 which we don't know. */
52 /* FPU. For now, just simulate 8 64-bit registers, their tags, and
53 the reg-stack top pointer, of which only the least significant
54 three bits are relevant.
56 The model is:
57 F0 .. F7 are the 8 registers. FTOP[2:0] contains the
58 index of the current 'stack top' -- pretty meaningless, but
59 still. FTOP is a 32-bit value. FTOP[31:3] can be anything
60 (not guaranteed to be zero).
62 When a value is pushed onto the stack, ftop is first replaced by
63 (ftop-1) & 7, and then F[ftop] is assigned the value.
65 When a value is popped off the stack, the value is read from
66 F[ftop], and then ftop is replaced by (ftop+1) & 7.
68 In general, a reference to a register ST(i) actually references
69 F[ (ftop+i) & 7 ].
71 FTAG0 .. FTAG0+7 are the tags. Each is a byte, zero means empty,
72 non-zero means non-empty.
74 The general rule appears to be that a read or modify of a register
75 gets a stack underflow fault if the register is empty. A write of
76 a register (only a write, not a modify) gets a stack overflow fault
77 if the register is full. Note that "over" vs "under" is pretty
78 meaningless since the FP stack pointer can move around arbitrarily,
79 so it's really just two different kinds of exceptions:
80 register-empty and register full.
82 Naturally Intel (in its infinite wisdom) has seen fit to throw in
83 some ad-hoc inconsistencies to the fault-generation rules of the
84 above para, just to complicate everything. Known inconsistencies:
86 * fxam can read a register in any state without taking an underflow
87 fault.
89 * fst from st(0) to st(i) does not take an overflow fault even if the
90 destination is already full.
92 FPROUND[1:0] is the FPU's notional rounding mode, encoded as per
93 the IRRoundingMode type (see libvex_ir.h). This just happens to be
94 the Intel encoding. Note carefully, the rounding mode is only
95 observed on float-to-int conversions, and on float-to-float
96 rounding, but not for general float-to-float operations, which are
97 always rounded-to-nearest.
99 Loads/stores of the FPU control word are faked accordingly -- on
100 loads, everything except the rounding mode is ignored, and on
101 stores, you get a vanilla control world (0x037F) with the rounding
102 mode patched in. Hence the only values you can get are 0x037F,
103 0x077F, 0x0B7F or 0x0F7F. Vex will emit an emulation warning if
104 you try and load a control word which either (1) unmasks FP
105 exceptions, or (2) changes the default (80-bit) precision.
107 FC3210 contains the C3, C2, C1 and C0 bits in the same place they
108 are in the FPU's status word. (bits 14, 10, 9, 8 respectively).
109 All other bits should be zero. The relevant mask to select just
110 those bits is 0x4700. To select C3, C2 and C0 only, the mask is
111 0x4500.
113 SSEROUND[1:0] is the SSE unit's notional rounding mode, encoded as
114 per the IRRoundingMode type. As with the FPU control word, the
115 rounding mode is the only part of %MXCSR that Vex observes. On
116 storing %MXCSR, you will get a vanilla word (0x1F80) with the
117 rounding mode patched in. Hence the only values you will get are
118 0x1F80, 0x3F80, 0x5F80 or 0x7F80. Vex will emit an emulation
119 warning if you try and load a control word which either (1) unmasks
120 any exceptions, (2) sets FZ (flush-to-zero) to 1, or (3) sets DAZ
121 (denormals-are-zeroes) to 1.
123 Segments: initial prefixes of local and global segment descriptor
124 tables are modelled. guest_LDT is either zero (NULL) or points in
125 the host address space to an array of VEX_GUEST_X86_LDT_NENT
126 descriptors, which have the type VexGuestX86SegDescr, defined
127 below. Similarly, guest_GDT is either zero or points in the host
128 address space to an array of VEX_GUEST_X86_GDT_NENT descriptors.
129 The only place where these are used are in the helper function
130 x86g_use_seg(). LibVEX's client is responsible for pointing
131 guest_LDT and guest_GDT at suitable tables. The contents of these
132 tables are expected not to change during the execution of any given
133 superblock, but they may validly be changed by LibVEX's client in
134 between superblock executions.
136 Since x86g_use_seg() only expects these tables to have
137 VEX_GUEST_X86_{LDT,GDT}_NENT entries, LibVEX's client should not
138 attempt to write entries beyond those limits.
140 typedef
141 struct {
142 /* Event check fail addr and counter. */
143 UInt host_EvC_FAILADDR; /* 0 */
144 UInt host_EvC_COUNTER; /* 4 */
145 UInt guest_EAX; /* 8 */
146 UInt guest_ECX;
147 UInt guest_EDX;
148 UInt guest_EBX;
149 UInt guest_ESP;
150 UInt guest_EBP;
151 UInt guest_ESI;
152 UInt guest_EDI; /* 36 */
154 /* 4-word thunk used to calculate O S Z A C P flags. */
155 UInt guest_CC_OP; /* 40 */
156 UInt guest_CC_DEP1;
157 UInt guest_CC_DEP2;
158 UInt guest_CC_NDEP; /* 52 */
159 /* The D flag is stored here, encoded as either -1 or +1 */
160 UInt guest_DFLAG; /* 56 */
161 /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */
162 UInt guest_IDFLAG; /* 60 */
163 /* Bit 18 (AC) of eflags stored here, as either 0 or 1. */
164 UInt guest_ACFLAG; /* 64 */
166 /* EIP */
167 UInt guest_EIP; /* 68 */
169 /* FPU */
170 ULong guest_FPREG[8]; /* 72 */
171 UChar guest_FPTAG[8]; /* 136 */
172 UInt guest_FPROUND; /* 144 */
173 UInt guest_FC3210; /* 148 */
174 UInt guest_FTOP; /* 152 */
176 /* SSE */
177 UInt guest_SSEROUND; /* 156 */
178 U128 guest_XMM0; /* 160 */
179 U128 guest_XMM1;
180 U128 guest_XMM2;
181 U128 guest_XMM3;
182 U128 guest_XMM4;
183 U128 guest_XMM5;
184 U128 guest_XMM6;
185 U128 guest_XMM7;
187 /* Segment registers. */
188 UShort guest_CS;
189 UShort guest_DS;
190 UShort guest_ES;
191 UShort guest_FS;
192 UShort guest_GS;
193 UShort guest_SS;
194 /* LDT/GDT stuff. */
195 ULong guest_LDT; /* host addr, a VexGuestX86SegDescr* */
196 ULong guest_GDT; /* host addr, a VexGuestX86SegDescr* */
198 /* Emulation notes */
199 UInt guest_EMNOTE;
201 /* For clflush/clinval: record start and length of area */
202 UInt guest_CMSTART;
203 UInt guest_CMLEN;
205 /* Used to record the unredirected guest address at the start of
206 a translation whose start has been redirected. By reading
207 this pseudo-register shortly afterwards, the translation can
208 find out what the corresponding no-redirection address was.
209 Note, this is only set for wrap-style redirects, not for
210 replace-style ones. */
211 UInt guest_NRADDR;
213 /* Used for Darwin syscall dispatching. */
214 UInt guest_SC_CLASS;
216 /* Needed for Darwin (but mandated for all guest architectures):
217 EIP at the last syscall insn (int 0x80/81/82, sysenter,
218 syscall). Used when backing up to restart a syscall that has
219 been interrupted by a signal. */
220 UInt guest_IP_AT_SYSCALL;
222 UInt guest_SETC;
224 /* Padding to make it have an 16-aligned size */
225 UInt padding1;
226 UInt padding2;
228 VexGuestX86State;
230 #define VEX_GUEST_X86_LDT_NENT /*64*/ 8192 /* use complete LDT */
231 #define VEX_GUEST_X86_GDT_NENT /*16*/ 8192 /* use complete GDT */
234 /*---------------------------------------------------------------*/
235 /*--- Types for x86 guest stuff. ---*/
236 /*---------------------------------------------------------------*/
238 /* VISIBLE TO LIBRARY CLIENT */
240 /* This is the hardware-format for a segment descriptor, ie what the
241 x86 actually deals with. It is 8 bytes long. It's ugly. */
243 typedef struct {
244 union {
245 struct {
246 UShort LimitLow;
247 UShort BaseLow;
248 UInt BaseMid : 8;
249 UInt Type : 5;
250 UInt Dpl : 2;
251 UInt Pres : 1;
252 UInt LimitHi : 4;
253 UInt Sys : 1;
254 UInt Reserved_0 : 1;
255 UInt Default_Big : 1;
256 UInt Granularity : 1;
257 UInt BaseHi : 8;
258 } Bits;
259 struct {
260 UInt word1;
261 UInt word2;
262 } Words;
264 LdtEnt;
265 } VexGuestX86SegDescr;
268 /*---------------------------------------------------------------*/
269 /*--- Utility functions for x86 guest stuff. ---*/
270 /*---------------------------------------------------------------*/
272 /* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */
274 /* Initialise all guest x86 state. The FPU is put in default mode. */
275 extern
276 void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state );
279 /* Extract from the supplied VexGuestX86State structure the
280 corresponding native %eflags value. */
281 extern
282 UInt LibVEX_GuestX86_get_eflags ( /*IN*/const VexGuestX86State* vex_state );
284 /* Put eflags into the given state. */
285 extern
286 void LibVEX_GuestX86_put_eflags ( UInt eflags,
287 /*MOD*/VexGuestX86State* vex_state );
289 /* Set the carry flag in the given state to 'new_carry_flag', which
290 should be zero or one. */
291 extern
292 void
293 LibVEX_GuestX86_put_eflag_c ( UInt new_carry_flag,
294 /*MOD*/VexGuestX86State* vex_state );
296 /* Do x87 save from the supplied VexGuestX86State structure and store the
297 result at the given address which represents a buffer of at least 108
298 bytes. */
299 extern
300 void LibVEX_GuestX86_get_x87 ( /*IN*/VexGuestX86State* vex_state,
301 /*OUT*/UChar* x87_state );
303 /* Do x87 restore from the supplied address and store read values to the given
304 VexGuestX86State structure. */
305 extern
306 VexEmNote LibVEX_GuestX86_put_x87 ( /*IN*/UChar* x87_state,
307 /*MOD*/VexGuestX86State* vex_state);
309 /* Return mxcsr from the supplied VexGuestX86State structure. */
310 extern
311 UInt LibVEX_GuestX86_get_mxcsr ( /*IN*/VexGuestX86State* vex_state );
313 /* Modify the given VexGuestX86State structure according to the passed mxcsr
314 value. */
315 extern
316 VexEmNote LibVEX_GuestX86_put_mxcsr ( /*IN*/UInt mxcsr,
317 /*MOD*/VexGuestX86State* vex_state);
319 #endif /* ndef __LIBVEX_PUB_GUEST_X86_H */
321 /*---------------------------------------------------------------*/
322 /*--- libvex_guest_x86.h ---*/
323 /*---------------------------------------------------------------*/