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