1 
2 /*---------------------------------------------------------------*/
3 /*--- begin                              libvex_guest_amd64.h ---*/
4 /*---------------------------------------------------------------*/
5 
6 /*
7    This file is part of Valgrind, a dynamic binary instrumentation
8    framework.
9 
10    Copyright (C) 2004-2013 OpenWorks LLP
11       info@open-works.net
12 
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.
17 
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.
22 
23    You should have received a copy of the GNU General Public License
24    along with this program; if not, write to the Free Software
25    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26    02110-1301, USA.
27 
28    The GNU General Public License is contained in the file COPYING.
29 
30    Neither the names of the U.S. Department of Energy nor the
31    University of California nor the names of its contributors may be
32    used to endorse or promote products derived from this software
33    without prior written permission.
34 */
35 
36 #ifndef __LIBVEX_PUB_GUEST_AMD64_H
37 #define __LIBVEX_PUB_GUEST_AMD64_H
38 
39 #include "libvex_basictypes.h"
40 
41 
42 /*---------------------------------------------------------------*/
43 /*--- Vex's representation of the AMD64 CPU state.            ---*/
44 /*---------------------------------------------------------------*/
45 
46 /* See detailed comments at the top of libvex_guest_x86.h for
47    further info.  This representation closely follows the
48    x86 representation.
49 */
50 
51 
52 typedef
53    struct {
54       /* Event check fail addr, counter, and padding to make RAX 16
55          aligned. */
56       /*   0 */ ULong  host_EvC_FAILADDR;
57       /*   8 */ UInt   host_EvC_COUNTER;
58       /*  12 */ UInt   pad0;
59       /*  16 */ ULong  guest_RAX;
60       /*  24 */ ULong  guest_RCX;
61       /*  32 */ ULong  guest_RDX;
62       /*  40 */ ULong  guest_RBX;
63       /*  48 */ ULong  guest_RSP;
64       /*  56 */ ULong  guest_RBP;
65       /*  64 */ ULong  guest_RSI;
66       /*  72 */ ULong  guest_RDI;
67       /*  80 */ ULong  guest_R8;
68       /*  88 */ ULong  guest_R9;
69       /*  96 */ ULong  guest_R10;
70       /* 104 */ ULong  guest_R11;
71       /* 112 */ ULong  guest_R12;
72       /* 120 */ ULong  guest_R13;
73       /* 128 */ ULong  guest_R14;
74       /* 136 */ ULong  guest_R15;
75       /* 4-word thunk used to calculate O S Z A C P flags. */
76       /* 144 */ ULong  guest_CC_OP;
77       /* 152 */ ULong  guest_CC_DEP1;
78       /* 160 */ ULong  guest_CC_DEP2;
79       /* 168 */ ULong  guest_CC_NDEP;
80       /* The D flag is stored here, encoded as either -1 or +1 */
81       /* 176 */ ULong  guest_DFLAG;
82       /* 184 */ ULong  guest_RIP;
83       /* Bit 18 (AC) of eflags stored here, as either 0 or 1. */
84       /* ... */ ULong  guest_ACFLAG;
85       /* Bit 21 (ID) of eflags stored here, as either 0 or 1. */
86       /* 192 */ ULong guest_IDFLAG;
87       /* Probably a lot more stuff too.
88          D,ID flags
89          16  128-bit SSE registers
90          all the old x87 FPU gunk
91          segment registers */
92 
93       /* HACK to e.g. make tls on amd64-linux work.  %fs only ever seems to
94          hold a constant value (zero on linux main thread, 0x63 in other
95          threads), and so guest_FS_CONST holds
96          the 64-bit offset associated with this constant %fs value. */
97       /* 200 */ ULong guest_FS_CONST;
98 
99       /* YMM registers.  Note that these must be allocated
100          consecutively in order that the SSE4.2 PCMP{E,I}STR{I,M}
101          helpers can treat them as an array.  YMM16 is a fake reg used
102          as an intermediary in handling aforementioned insns. */
103       /* 208 */ULong guest_SSEROUND;
104       /* 216 */U256  guest_YMM0;
105       U256  guest_YMM1;
106       U256  guest_YMM2;
107       U256  guest_YMM3;
108       U256  guest_YMM4;
109       U256  guest_YMM5;
110       U256  guest_YMM6;
111       U256  guest_YMM7;
112       U256  guest_YMM8;
113       U256  guest_YMM9;
114       U256  guest_YMM10;
115       U256  guest_YMM11;
116       U256  guest_YMM12;
117       U256  guest_YMM13;
118       U256  guest_YMM14;
119       U256  guest_YMM15;
120       U256  guest_YMM16;
121 
122       /* FPU */
123       /* Note.  Setting guest_FTOP to be ULong messes up the
124          delicately-balanced PutI/GetI optimisation machinery.
125          Therefore best to leave it as a UInt. */
126       UInt  guest_FTOP;
127       UInt  pad1;
128       ULong guest_FPREG[8];
129       UChar guest_FPTAG[8];
130       ULong guest_FPROUND;
131       ULong guest_FC3210;
132 
133       /* Emulation notes */
134       UInt  guest_EMNOTE;
135       UInt  pad2;
136 
137       /* Translation-invalidation area description.  Not used on amd64
138          (there is no invalidate-icache insn), but needed so as to
139          allow users of the library to uniformly assume that the guest
140          state contains these two fields -- otherwise there is
141          compilation breakage.  On amd64, these two fields are set to
142          zero by LibVEX_GuestAMD64_initialise and then should be
143          ignored forever thereafter. */
144       ULong guest_CMSTART;
145       ULong guest_CMLEN;
146 
147       /* Used to record the unredirected guest address at the start of
148          a translation whose start has been redirected.  By reading
149          this pseudo-register shortly afterwards, the translation can
150          find out what the corresponding no-redirection address was.
151          Note, this is only set for wrap-style redirects, not for
152          replace-style ones. */
153       ULong guest_NRADDR;
154 
155       /* Used for Darwin syscall dispatching. */
156       ULong guest_SC_CLASS;
157 
158       /* HACK to make e.g. tls on darwin work, wine on linux work, ...
159          %gs only ever seems to hold a constant value (e.g. 0x60 on darwin,
160          0x6b on linux), and so guest_GS_CONST holds the 64-bit offset
161          associated with this constant %gs value.  (A direct analogue
162          of the %fs-const hack for amd64-linux). */
163       ULong guest_GS_CONST;
164 
165       /* Needed for Darwin (but mandated for all guest architectures):
166          RIP at the last syscall insn (int 0x80/81/82, sysenter,
167          syscall).  Used when backing up to restart a syscall that has
168          been interrupted by a signal. */
169       ULong guest_IP_AT_SYSCALL;
170 
171       /* Padding to make it have an 16-aligned size */
172       ULong pad3;
173    }
174    VexGuestAMD64State;
175 
176 
177 
178 /*---------------------------------------------------------------*/
179 /*--- Utility functions for amd64 guest stuff.                ---*/
180 /*---------------------------------------------------------------*/
181 
182 /* ALL THE FOLLOWING ARE VISIBLE TO LIBRARY CLIENT */
183 
184 /* Initialise all guest amd64 state.  The FPU is put in default
185    mode. */
186 extern
187 void LibVEX_GuestAMD64_initialise ( /*OUT*/VexGuestAMD64State* vex_state );
188 
189 
190 /* Extract from the supplied VexGuestAMD64State structure the
191    corresponding native %rflags value. */
192 extern
193 ULong LibVEX_GuestAMD64_get_rflags ( /*IN*/const VexGuestAMD64State* vex_state );
194 
195 /* Set the carry flag in the given state to 'new_carry_flag', which
196    should be zero or one. */
197 extern
198 void
199 LibVEX_GuestAMD64_put_rflag_c ( ULong new_carry_flag,
200                                 /*MOD*/VexGuestAMD64State* vex_state );
201 
202 
203 #endif /* ndef __LIBVEX_PUB_GUEST_AMD64_H */
204 
205 /*---------------------------------------------------------------*/
206 /*---                                    libvex_guest_amd64.h ---*/
207 /*---------------------------------------------------------------*/
208