DebugServer2
Loading...
Searching...
No Matches
CPUState.h
1//
2// Copyright (c) 2014-present, Facebook, Inc.
3// All rights reserved.
4//
5// This source code is licensed under the University of Illinois/NCSA Open
6// Source License found in the LICENSE file in the root directory of this
7// source tree. An additional grant of patent rights can be found in the
8// PATENTS file in the same directory.
9//
10
11#pragma once
12
13#if !defined(CPUSTATE_H_INTERNAL)
14#error "You shall not include this file directly."
15#endif
16
17#include "DebugServer2/Architecture/X86/RegistersDescriptors.h"
18
19#include <cstring>
20
21namespace ds2 {
22namespace Architecture {
23namespace X86 {
24
25#pragma pack(push, 1)
26
27struct SSEVector {
28 uint64_t value[2]; // 128-bit values
29};
30
31struct AVXVector {
32 uint64_t value[4]; // 256-bit values
33};
34
36 uint8_t data[10];
37};
38
39enum XFeature : uint64_t {
40 X86_X87 = 1 << 0,
41 X86_SSE = 1 << 1,
42 X86_AVX = 1 << 2,
43 X86_MPX_BNDREGS = 1 << 3,
44 X86_MPX_CSR = 1 << 4,
45 X86_AVX_512_OPMASK = 1 << 5,
46 X86_AVX_512_HI256 = 1 << 6,
47 X86_AVX_512_ZMM = 1 << 7,
48 X86_PROC_TRACE = 1 << 8,
49 X86_PROT_KEYS_USER_REGS = 1 << 9,
50 X86_UNKNOWN_XFEATURE = 1 << 10,
51};
52
53struct CPUState {
54 union {
55 uint32_t regs[16];
56 struct {
57 uint32_t eax, ecx, edx, ebx, esi, edi, esp, ebp, eip, cs, ss, ds, es, fs,
58 gs, eflags;
59 };
60 } gp;
61
62 struct {
63 X87Register regs[8];
64 uint16_t fstw;
65 uint16_t fctw;
66 uint16_t ftag;
67 uint32_t fiseg;
68 uint32_t fioff;
69 uint32_t foseg;
70 uint32_t fooff;
71 uint16_t fop;
72 } x87;
73
74 union {
75 struct {
76 uint32_t mxcsr;
77 uint32_t mxcsrmask;
78 struct {
79 // Dirty hack to map AVX register locations
80 union {
81 AVXVector _avx[8];
82 SSEVector _sse[16];
83 };
84 SSEVector const &operator[](size_t index) const {
85 return _sse[index << 1];
86 }
87 SSEVector &operator[](size_t index) { return _sse[index << 1]; }
88 } regs;
89 } sse;
90
91 struct {
92 uint32_t mxcsr;
93 uint32_t mxcsrmask;
94 AVXVector regs[8];
95 } avx;
96 };
97
98 struct {
99 uint64_t xfeatures_mask;
100 } xsave_header;
101
102 struct {
103 uint32_t dr[8];
104 } dr;
105
106 uint64_t xcr0;
107
108#if defined(OS_LINUX)
109 struct {
110 uint32_t orig_eax;
111 } linux_gp;
112#endif
113
114public:
115 CPUState() { clear(); }
116
117 inline void clear() {
118 std::memset(&gp, 0, sizeof(gp));
119 std::memset(&x87, 0, sizeof(x87));
120 std::memset(&xsave_header, 0, sizeof(xsave_header));
121 std::memset(&avx, 0, sizeof(avx));
122 std::memset(&dr, 0, sizeof(dr));
123 std::memset(&xcr0, 0, sizeof(xcr0));
124#if defined(OS_LINUX)
125 std::memset(&linux_gp, 0, sizeof(linux_gp));
126#endif
127 }
128
129public:
130 //
131 // Accessors
132 //
133 inline uint32_t pc() const { return gp.eip; }
134 inline void setPC(uint32_t pc) { gp.eip = pc; }
135
136 inline uint32_t xpc() const { return gp.eip; }
137
138 inline uint32_t sp() const { return gp.esp; }
139 inline void setSP(uint32_t sp) { gp.esp = sp; }
140
141 inline uint32_t retval() const { return gp.eax; }
142
143public:
144#define _REGVALUE(REG) \
145 GPRegisterValue { sizeof(gp.REG), gp.REG }
146 //
147 // These two functions interprets regs as GDB packed registers,
148 // the order of GPR state, which is NOT the same order as the reg_gdb_*
149 // (*sigh*)
150 // is as follow:
151 //
152 // eax, ebx, ecx, edx, esi, edi, ebp, esp, eip, eflags, cs, ss, ds, es, fs, gs
153 //
154 inline void getGPState(GPRegisterValueVector &regs) const {
155 regs.clear();
156 regs.push_back(_REGVALUE(eax));
157 regs.push_back(_REGVALUE(ebx));
158 regs.push_back(_REGVALUE(ecx));
159 regs.push_back(_REGVALUE(edx));
160 regs.push_back(_REGVALUE(esi));
161 regs.push_back(_REGVALUE(edi));
162 regs.push_back(_REGVALUE(ebp));
163 regs.push_back(_REGVALUE(esp));
164 regs.push_back(_REGVALUE(eip));
165 regs.push_back(_REGVALUE(eflags));
166 regs.push_back(_REGVALUE(cs));
167 regs.push_back(_REGVALUE(ss));
168 regs.push_back(_REGVALUE(ds));
169 regs.push_back(_REGVALUE(es));
170 regs.push_back(_REGVALUE(fs));
171 regs.push_back(_REGVALUE(gs));
172 }
173
174 inline void setGPState(std::vector<uint64_t> const &regs) {
175 gp.eax = static_cast<uint32_t>(regs[0]);
176 gp.ebx = static_cast<uint32_t>(regs[1]);
177 gp.ecx = static_cast<uint32_t>(regs[2]);
178 gp.edx = static_cast<uint32_t>(regs[3]);
179 gp.esi = static_cast<uint32_t>(regs[4]);
180 gp.edi = static_cast<uint32_t>(regs[5]);
181 gp.ebp = static_cast<uint32_t>(regs[6]);
182 gp.esp = static_cast<uint32_t>(regs[7]);
183 gp.eip = static_cast<uint32_t>(regs[8]);
184 gp.eflags = static_cast<uint32_t>(regs[9]);
185 gp.cs = static_cast<uint32_t>(regs[10]);
186 gp.ss = static_cast<uint32_t>(regs[11]);
187 gp.ds = static_cast<uint32_t>(regs[12]);
188 gp.es = static_cast<uint32_t>(regs[13]);
189 gp.fs = static_cast<uint32_t>(regs[14]);
190 gp.gs = static_cast<uint32_t>(regs[15]);
191 }
192
193public:
194 inline void getStopGPState(GPRegisterStopMap &regs, bool forLLDB) const {
195 if (forLLDB) {
196#define _SETREG(REG) regs[reg_lldb_##REG] = _REGVALUE(REG)
197 _SETREG(eax);
198 _SETREG(ebx);
199 _SETREG(ecx);
200 _SETREG(edx);
201 _SETREG(ebx);
202 _SETREG(esi);
203 _SETREG(edi);
204 _SETREG(ebp);
205 _SETREG(esp);
206 _SETREG(eip);
207 _SETREG(cs);
208 _SETREG(ss);
209 _SETREG(ds);
210 _SETREG(es);
211 _SETREG(fs);
212 _SETREG(gs);
213 _SETREG(eflags);
214#undef _SETREG
215 } else {
216#define _SETREG(REG) regs[reg_gdb_##REG] = _REGVALUE(REG)
217 _SETREG(eax);
218 _SETREG(ebx);
219 _SETREG(ecx);
220 _SETREG(edx);
221 _SETREG(ebx);
222 _SETREG(esi);
223 _SETREG(edi);
224 _SETREG(ebp);
225 _SETREG(esp);
226 _SETREG(eip);
227 _SETREG(cs);
228 _SETREG(ss);
229 _SETREG(ds);
230 _SETREG(es);
231 _SETREG(fs);
232 _SETREG(gs);
233 _SETREG(eflags);
234#undef _SETREG
235 }
236 }
237#undef _REGVALUE
238
239public:
240 inline bool getLLDBRegisterPtr(int regno, void **ptr, size_t *length) const {
241#define _GETREG2(T, REG, FLD) \
242 case reg_lldb_##REG: \
243 *ptr = &const_cast<CPUState *>(this)->T.FLD, *length = sizeof(T.FLD); \
244 break
245#define _GETREG8L(T, REG, FREG) \
246 case reg_lldb_##REG: \
247 *ptr = reinterpret_cast<uint8_t *>(&const_cast<CPUState *>(this)->T.FREG), \
248 *length = sizeof(uint8_t); \
249 break
250#define _GETREG8H(T, REG, FREG) \
251 case reg_lldb_##REG: \
252 *ptr = \
253 reinterpret_cast<uint8_t *>(&const_cast<CPUState *>(this)->T.FREG) + \
254 1, \
255 *length = sizeof(uint8_t); \
256 break
257#define _GETREG16(T, REG, FREG) \
258 case reg_lldb_##REG: \
259 *ptr = \
260 reinterpret_cast<uint16_t *>(&const_cast<CPUState *>(this)->T.FREG), \
261 *length = sizeof(uint16_t); \
262 break
263#define _GETREG(T, REG) _GETREG2(T, REG, REG)
264
265 switch (regno) {
266 _GETREG(gp, eax);
267 _GETREG(gp, ebx);
268 _GETREG(gp, ecx);
269 _GETREG(gp, edx);
270 _GETREG(gp, esi);
271 _GETREG(gp, edi);
272 _GETREG(gp, esp);
273 _GETREG(gp, ebp);
274 _GETREG(gp, eip);
275 _GETREG(gp, cs);
276 _GETREG(gp, ss);
277 _GETREG(gp, ds);
278 _GETREG(gp, es);
279 _GETREG(gp, fs);
280 _GETREG(gp, gs);
281 _GETREG(gp, eflags);
282
283 _GETREG16(gp, ax, eax);
284 _GETREG16(gp, bx, ebx);
285 _GETREG16(gp, cx, ecx);
286 _GETREG16(gp, dx, edx);
287 _GETREG16(gp, si, esi);
288 _GETREG16(gp, di, edi);
289 _GETREG16(gp, sp, esp);
290 _GETREG16(gp, bp, ebp);
291
292 _GETREG8L(gp, al, eax);
293 _GETREG8L(gp, bl, ebx);
294 _GETREG8L(gp, cl, ecx);
295 _GETREG8L(gp, dl, edx);
296
297 _GETREG8H(gp, ah, eax);
298 _GETREG8H(gp, bh, ebx);
299 _GETREG8H(gp, ch, ecx);
300 _GETREG8H(gp, dh, edx);
301
302 _GETREG2(x87, st0, regs[0].data);
303 _GETREG2(x87, st1, regs[1].data);
304 _GETREG2(x87, st2, regs[2].data);
305 _GETREG2(x87, st3, regs[3].data);
306 _GETREG2(x87, st4, regs[4].data);
307 _GETREG2(x87, st5, regs[5].data);
308 _GETREG2(x87, st6, regs[6].data);
309 _GETREG2(x87, st7, regs[7].data);
310 _GETREG2(x87, fstat, fstw);
311 _GETREG2(x87, fctrl, fctw);
312 _GETREG(x87, ftag);
313 _GETREG(x87, fiseg);
314 _GETREG(x87, fioff);
315 _GETREG(x87, foseg);
316 _GETREG(x87, fooff);
317 _GETREG(x87, fop);
318
319 _GETREG(avx, mxcsr);
320 _GETREG(avx, mxcsrmask);
321 _GETREG2(avx, ymm0, regs[0]);
322 _GETREG2(avx, ymm1, regs[1]);
323 _GETREG2(avx, ymm2, regs[2]);
324 _GETREG2(avx, ymm3, regs[3]);
325 _GETREG2(avx, ymm4, regs[4]);
326 _GETREG2(avx, ymm5, regs[5]);
327 _GETREG2(avx, ymm6, regs[6]);
328 _GETREG2(avx, ymm7, regs[7]);
329
330 default:
331 return false;
332 }
333#undef _GETREG16
334#undef _GETREG8H
335#undef _GETREG8L
336#undef _GETREG
337#undef _GETREG2
338
339 return true;
340 }
341
342 inline bool getGDBRegisterPtr(int regno, void **ptr, size_t *length) const {
343#define _GETREG2(T, REG, FLD) \
344 case reg_gdb_##REG: \
345 *ptr = &const_cast<CPUState *>(this)->T.FLD, *length = sizeof(T.FLD); \
346 break
347#define _GETREG(T, REG) _GETREG2(T, REG, REG)
348
349 switch (regno) {
350 _GETREG(gp, eax);
351 _GETREG(gp, ebx);
352 _GETREG(gp, ecx);
353 _GETREG(gp, edx);
354 _GETREG(gp, esi);
355 _GETREG(gp, edi);
356 _GETREG(gp, esp);
357 _GETREG(gp, ebp);
358 _GETREG(gp, eip);
359 _GETREG(gp, cs);
360 _GETREG(gp, ss);
361 _GETREG(gp, ds);
362 _GETREG(gp, es);
363 _GETREG(gp, fs);
364 _GETREG(gp, gs);
365 _GETREG(gp, eflags);
366
367 _GETREG2(x87, st0, regs[0].data);
368 _GETREG2(x87, st1, regs[1].data);
369 _GETREG2(x87, st2, regs[2].data);
370 _GETREG2(x87, st3, regs[3].data);
371 _GETREG2(x87, st4, regs[4].data);
372 _GETREG2(x87, st5, regs[5].data);
373 _GETREG2(x87, st6, regs[6].data);
374 _GETREG2(x87, st7, regs[7].data);
375 _GETREG2(x87, fstat, fstw);
376 _GETREG2(x87, fctrl, fctw);
377 _GETREG(x87, ftag);
378 _GETREG(x87, fiseg);
379 _GETREG(x87, fioff);
380 _GETREG(x87, foseg);
381 _GETREG(x87, fooff);
382 _GETREG(x87, fop);
383
384 // ymm0 maps to xmm0 for gdb
385 _GETREG2(sse, ymm0, regs[0]);
386 _GETREG2(sse, ymm1, regs[1]);
387 _GETREG2(sse, ymm2, regs[2]);
388 _GETREG2(sse, ymm3, regs[3]);
389 _GETREG2(sse, ymm4, regs[4]);
390 _GETREG2(sse, ymm5, regs[5]);
391 _GETREG2(sse, ymm6, regs[6]);
392 _GETREG2(sse, ymm7, regs[7]);
393
394 _GETREG(sse, mxcsr);
395
396#if defined(OS_LINUX)
397 _GETREG(linux_gp, orig_eax);
398#endif
399
400 default:
401 return false;
402 }
403#undef _GETREG
404#undef _GETREG2
405
406 return true;
407 }
408};
409
410#pragma pack(pop)
411} // namespace X86
412} // namespace Architecture
413} // namespace ds2
Definition CPUState.h:31
Definition CPUState.h:53
Definition CPUState.h:27
Definition CPUState.h:35