blob: 72a03e4e5f31b068458464ad99dd427d0f98b1bf [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
9#ifndef __LIBVEX_PUB_GUEST_X86_H
10#define __LIBVEX_PUB_GUEST_X86_H
11
12#include "libvex_basictypes.h"
13
14/*---------------------------------------------------------------*/
sewardjf6dc3ce2004-10-19 01:03:46 +000015/*--- Vex's representation of the x86 CPU state. ---*/
16/*---------------------------------------------------------------*/
17
18/* The integer parts should be pretty straightforward. */
19
20/* Hmm, subregisters. The simulated state is stored in memory in the
21 host's byte ordering, so we can't say here what the offsets of %ax,
22 %al, %ah etc are since that depends on the host's byte ordering,
23 which we don't know. */
24
25/* FPU. For now, just simulate 8 64-bit registers, their tags, and
26 the reg-stack top pointer, of which only the least significant
27 three bits are relevant.
28
29 The model is:
30 F0 .. F7 are the 8 registers. FTOP[2:0] contains the
31 index of the current 'stack top' -- pretty meaningless, but
32 still. FTOP is a 32-bit value. FTOP[31:3] can be anything
33 (not guaranteed to be zero).
34
35 When a value is pushed onto the stack, ftop is first replaced by
36 (ftop-1) & 7, and then F[ftop] is assigned the value.
37
38 When a value is popped off the stack, the value is read from
39 F[ftop], and then ftop is replaced by (ftop+1) & 7.
40
41 In general, a reference to a register ST(i) actually references
42 F[ (ftop+i) & 7 ].
43
44 FTAG0 .. FTAG0+7 are the tags. Each is a byte, zero means empty,
45 non-zero means non-empty.
46
47 The general rule appears to be that a read or modify of a register
48 gets a stack underflow fault if the register is empty. A write of
49 a register (only a write, not a modify) gets a stack overflow fault
50 if the register is full. Note that "over" vs "under" is pretty
51 meaningless since the FP stack pointer can move around arbitrarily,
52 so it's really just two different kinds of exceptions:
53 register-empty and register full.
54
55 Naturally Intel (in its infinite wisdom) has seen fit to throw in
56 some ad-hoc inconsistencies to the fault-generation rules of the
57 above para, just to complicate everything. Known inconsistencies:
58
59 * fxam can read a register in any state without taking an underflow
60 fault.
61
62 * fst from st(0) to st(i) does not take an overflow fault even if the
63 destination is already full.
64
65 FPUCW[15:0] is the FPU's control word. FPUCW[31:16] is unused.
66
67 FC3210 contains the C3, C2, C1 and C0 bits in the same place they
68 are in the FPU's status word. (bits 14, 10, 9, 8 respectively).
69 All other bits should be zero. The relevant mask to select just
70 those bits is 0x4700. To select C3, C2 and C0 only, the mask is
71 0x4500.
72*/
73
74typedef
75 struct {
76 UInt guest_EAX;
77 UInt guest_ECX;
78 UInt guest_EDX;
79 UInt guest_EBX;
80 UInt guest_ESP;
81 UInt guest_EBP;
82 UInt guest_ESI;
83 UInt guest_EDI;
84 /* 3-word thunk used to calculate O S Z A C P flags. */
85 UInt guest_CC_OP;
86 UInt guest_CC_SRC;
87 UInt guest_CC_DST;
88 /* The D flag is stored here, as either -1 or +1 */
89 UInt guest_DFLAG;
90 /* EIP */
91 UInt guest_EIP;
92 /* FPU */
93 UInt guest_FTOP;
94 ULong guest_FPREG[8];
95 UChar guest_FPTAG[8];
96 UInt guest_FPUCW;
97 UInt guest_FC3210;
sewardj063f02f2004-10-20 12:36:12 +000098 /* Segment registers. */
99 UShort guest_CS;
100 UShort guest_DS;
101 UShort guest_ES;
102 UShort guest_FS;
103 UShort guest_GS;
104 UShort guest_SS;
sewardjf6dc3ce2004-10-19 01:03:46 +0000105 }
106 VexGuestX86State;
107
108
sewardj8d2291c2004-10-25 14:50:21 +0000109/* This is logically part of the guest state description. */
110/* Not visible to library client. */
111extern Bool guest_x86_state_requires_precise_mem_exns ( Int, Int );
112
113
114
sewardjf6dc3ce2004-10-19 01:03:46 +0000115/*---------------------------------------------------------------*/
sewardj0c2cb622004-09-06 23:21:21 +0000116/*--- Utility functions for x86 guest stuff. ---*/
117/*---------------------------------------------------------------*/
118
sewardj8d2291c2004-10-25 14:50:21 +0000119
120
121
122/* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */
123
sewardjf6dc3ce2004-10-19 01:03:46 +0000124/* Convert a saved x87 FPU image (as created by fsave) and write it
125 into the supplied VexGuestX86State structure. The non-FP parts of
126 said structure are left unchanged.
sewardj0c2cb622004-09-06 23:21:21 +0000127*/
sewardjf6dc3ce2004-10-19 01:03:46 +0000128extern
129void x87_to_vex ( /*IN*/UChar* x87_state,
130 /*OUT*/VexGuestX86State* vex_state );
sewardj0c2cb622004-09-06 23:21:21 +0000131
sewardjf6dc3ce2004-10-19 01:03:46 +0000132/* Extract from the supplied VexGuestX86State structure, an x87 FPU
133 image. */
134extern
135void vex_to_x87 ( /*IN*/VexGuestX86State* vex_state,
136 /*OUT*/UChar* x87_state );
137
138
139/* Given a 32-bit word containing native x86 %eflags values, set the
140 eflag-related fields in the supplied VexGuestX86State accordingly.
141 All other fields are left unchanged. */
142
143extern
144void eflags_to_vex ( UInt eflags_native,
145 /*OUT*/VexGuestX86State* vex_state );
146
147/* Extract from the supplied VexGuestX86State structure the
148 corresponding native %eflags value. */
149
150extern
151UInt vex_to_eflags ( /*IN*/VexGuestX86State* vex_state );
152
sewardj300361f2004-10-19 15:47:32 +0000153extern
sewardj96604c12004-10-19 15:55:45 +0000154void vex_initialise_x87 ( /* MOD*/VexGuestX86State* vex_state );
sewardj0c2cb622004-09-06 23:21:21 +0000155
156#endif /* ndef __LIBVEX_PUB_GUEST_X86_H */
157
158/*---------------------------------------------------------------*/
159/*--- libvex_guest_x86.h ---*/
160/*---------------------------------------------------------------*/