blob: bbdb8995fe1aa2ac68b61a26f362255138c1918b [file] [log] [blame]
sewardj0c2cb622004-09-06 23:21:21 +00001
2/*---------------------------------------------------------------*/
3/*--- ---*/
4/*--- This file (libvex_guest_x86.h) is ---*/
5/*--- Copyright (c) 2004 OpenWorks LLP. All rights reserved. ---*/
6/*--- ---*/
7/*---------------------------------------------------------------*/
8
sewardjf8ed9d82004-11-12 17:40:23 +00009/*
10 This file is part of LibVEX, a library for dynamic binary
11 instrumentation and translation.
12
13 Copyright (C) 2004 OpenWorks, LLP.
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; Version 2 dated June 1991 of the
18 license.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or liability
23 for damages. See the GNU General Public License for more details.
24
25 Neither the names of the U.S. Department of Energy nor the
26 University of California nor the names of its contributors may be
27 used to endorse or promote products derived from this software
28 without prior written permission.
29
30 You should have received a copy of the GNU General Public License
31 along with this program; if not, write to the Free Software
32 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
33 USA.
34*/
35
sewardj0c2cb622004-09-06 23:21:21 +000036#ifndef __LIBVEX_PUB_GUEST_X86_H
37#define __LIBVEX_PUB_GUEST_X86_H
38
39#include "libvex_basictypes.h"
40
41/*---------------------------------------------------------------*/
sewardjf6dc3ce2004-10-19 01:03:46 +000042/*--- Vex's representation of the x86 CPU state. ---*/
43/*---------------------------------------------------------------*/
44
45/* The integer parts should be pretty straightforward. */
46
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. */
51
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.
55
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).
61
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.
64
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.
67
68 In general, a reference to a register ST(i) actually references
69 F[ (ftop+i) & 7 ].
70
71 FTAG0 .. FTAG0+7 are the tags. Each is a byte, zero means empty,
72 non-zero means non-empty.
73
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.
81
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:
85
86 * fxam can read a register in any state without taking an underflow
87 fault.
88
89 * fst from st(0) to st(i) does not take an overflow fault even if the
90 destination is already full.
91
92 FPUCW[15:0] is the FPU's control word. FPUCW[31:16] is unused.
93
94 FC3210 contains the C3, C2, C1 and C0 bits in the same place they
95 are in the FPU's status word. (bits 14, 10, 9, 8 respectively).
96 All other bits should be zero. The relevant mask to select just
97 those bits is 0x4700. To select C3, C2 and C0 only, the mask is
98 0x4500.
99*/
100
101typedef
102 struct {
103 UInt guest_EAX;
104 UInt guest_ECX;
105 UInt guest_EDX;
106 UInt guest_EBX;
107 UInt guest_ESP;
108 UInt guest_EBP;
109 UInt guest_ESI;
110 UInt guest_EDI;
sewardj2a2ba8b2004-11-08 13:14:06 +0000111 /* 4-word thunk used to calculate O S Z A C P flags. */
sewardjf6dc3ce2004-10-19 01:03:46 +0000112 UInt guest_CC_OP;
sewardj2a2ba8b2004-11-08 13:14:06 +0000113 UInt guest_CC_DEP1;
114 UInt guest_CC_DEP2;
115 UInt guest_CC_NDEP;
116 /* The D flag is stored here, encoded as either -1 or +1 */
sewardjf6dc3ce2004-10-19 01:03:46 +0000117 UInt guest_DFLAG;
sewardj006a6a22004-10-26 00:50:52 +0000118 /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */
119 UInt guest_IDFLAG;
sewardjf6dc3ce2004-10-19 01:03:46 +0000120 /* EIP */
121 UInt guest_EIP;
122 /* FPU */
123 UInt guest_FTOP;
124 ULong guest_FPREG[8];
125 UChar guest_FPTAG[8];
126 UInt guest_FPUCW;
127 UInt guest_FC3210;
sewardj063f02f2004-10-20 12:36:12 +0000128 /* Segment registers. */
129 UShort guest_CS;
130 UShort guest_DS;
131 UShort guest_ES;
132 UShort guest_FS;
133 UShort guest_GS;
134 UShort guest_SS;
sewardj81ec4182004-10-25 23:15:52 +0000135 /* Padding to make it have an 8-aligned size */
sewardj2a2ba8b2004-11-08 13:14:06 +0000136 UInt padding;
sewardjf6dc3ce2004-10-19 01:03:46 +0000137 }
138 VexGuestX86State;
139
140
sewardj8d2291c2004-10-25 14:50:21 +0000141
sewardjf6dc3ce2004-10-19 01:03:46 +0000142/*---------------------------------------------------------------*/
sewardj0c2cb622004-09-06 23:21:21 +0000143/*--- Utility functions for x86 guest stuff. ---*/
144/*---------------------------------------------------------------*/
145
sewardj8d2291c2004-10-25 14:50:21 +0000146
sewardj8d2291c2004-10-25 14:50:21 +0000147/* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */
148
sewardj76bdc802004-10-25 15:33:26 +0000149
150/* Initialise all guest x86 state. The FPU is put in default mode. */
151extern
152void LibVEX_GuestX86_initialise ( /*OUT*/VexGuestX86State* vex_state );
153
154
sewardjf6dc3ce2004-10-19 01:03:46 +0000155/* Convert a saved x87 FPU image (as created by fsave) and write it
156 into the supplied VexGuestX86State structure. The non-FP parts of
157 said structure are left unchanged.
sewardj0c2cb622004-09-06 23:21:21 +0000158*/
sewardjf6dc3ce2004-10-19 01:03:46 +0000159extern
sewardj76bdc802004-10-25 15:33:26 +0000160void LibVEX_GuestX86_put_x87 ( /*IN*/UChar* x87_state,
161 /*OUT*/VexGuestX86State* vex_state );
sewardj0c2cb622004-09-06 23:21:21 +0000162
sewardjf6dc3ce2004-10-19 01:03:46 +0000163/* Extract from the supplied VexGuestX86State structure, an x87 FPU
164 image. */
165extern
sewardj76bdc802004-10-25 15:33:26 +0000166void LibVEX_GuestX86_get_x87 ( /*IN*/VexGuestX86State* vex_state,
167 /*OUT*/UChar* x87_state );
sewardjf6dc3ce2004-10-19 01:03:46 +0000168
169
170/* Given a 32-bit word containing native x86 %eflags values, set the
171 eflag-related fields in the supplied VexGuestX86State accordingly.
172 All other fields are left unchanged. */
173
174extern
sewardj76bdc802004-10-25 15:33:26 +0000175void LibVEX_GuestX86_put_eflags ( UInt eflags_native,
176 /*OUT*/VexGuestX86State* vex_state );
sewardjf6dc3ce2004-10-19 01:03:46 +0000177
178/* Extract from the supplied VexGuestX86State structure the
179 corresponding native %eflags value. */
180
181extern
sewardj76bdc802004-10-25 15:33:26 +0000182UInt LibVEX_GuestX86_get_eflags ( /*IN*/VexGuestX86State* vex_state );
sewardjf6dc3ce2004-10-19 01:03:46 +0000183
sewardj0c2cb622004-09-06 23:21:21 +0000184
185#endif /* ndef __LIBVEX_PUB_GUEST_X86_H */
186
187/*---------------------------------------------------------------*/
188/*--- libvex_guest_x86.h ---*/
189/*---------------------------------------------------------------*/