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/CPUState.h" // Include the X86 variant
18#include "DebugServer2/Architecture/X86_64/RegistersDescriptors.h"
19
20#include <cstring>
21
22namespace ds2 {
23namespace Architecture {
24namespace X86_64 {
25
26//
27// Shared between X86 and X86-64
28//
32using ds2::Architecture::X86::XFeature;
33
34struct EAVXVector {
35 uint64_t value[8]; // 512-bit values
36};
37
38//
39// Import the X86 variant
40//
42
43//
44// Define the 64-bit variant
45//
46struct CPUState64 {
47 union {
48 uint64_t regs[24];
49 struct {
50 uint64_t rax, rcx, rdx, rbx, rsi, rdi, rsp, rbp, r8, r9, r10, r11, r12,
51 r13, r14, r15;
52 uint64_t rip;
53 struct {
54 uint32_t cs;
55 uint32_t : 32;
56 };
57 struct {
58 uint32_t ss;
59 uint32_t : 32;
60 };
61 struct {
62 uint32_t ds;
63 uint32_t : 32;
64 };
65 struct {
66 uint32_t es;
67 uint32_t : 32;
68 };
69 struct {
70 uint32_t fs;
71 uint32_t : 32;
72 };
73 struct {
74 uint32_t gs;
75 uint32_t : 32;
76 };
77 struct {
78 uint32_t eflags;
79 uint32_t : 32;
80 };
81 };
82 } gp;
83
84 struct {
85 X87Register regs[8];
86 uint16_t fstw;
87 uint16_t fctw;
88 uint16_t ftag;
89 uint32_t fioff;
90 uint32_t fiseg;
91 uint32_t fooff;
92 uint32_t foseg;
93 uint16_t fop;
94 } x87;
95
96 union {
97 struct {
98 uint32_t mxcsr;
99 uint32_t mxcsrmask;
100 struct {
101 // Dirty hack to map EAVX register locations
102 union {
103 EAVXVector _eavx[32];
104 AVXVector _avx[64];
105 SSEVector _sse[128];
106 };
107 SSEVector const &operator[](size_t index) const {
108 return _sse[index << 2];
109 }
110 SSEVector &operator[](size_t index) { return _sse[index << 2]; }
111 } regs;
112 } sse;
113
114 struct {
115 uint32_t mxcsr;
116 uint32_t mxcsrmask;
117 struct {
118 // Dirty hack to map EAVX register locations
119 union {
120 EAVXVector _eavx[32];
121 AVXVector _avx[64];
122 };
123 AVXVector const &operator[](size_t index) const {
124 return _avx[index << 1];
125 }
126 AVXVector &operator[](size_t index) { return _avx[index << 1]; }
127 } regs;
128 } avx;
129
130 struct {
131 uint32_t mxcsr;
132 uint32_t mxcsrmask;
133 EAVXVector regs[32];
134 } eavx;
135 };
136
137 struct {
138 uint64_t xfeatures_mask;
139 } xsave_header;
140
141 struct {
142 uint64_t dr[8];
143 } dr;
144
145 uint64_t xcr0;
146
147#if defined(OS_LINUX)
148 struct {
149 uint64_t orig_rax;
150 uint64_t fs_base;
151 uint64_t gs_base;
152 } linux_gp;
153#endif
154
155public:
156 CPUState64() { clear(); }
157
158 inline void clear() {
159 std::memset(&gp, 0, sizeof(gp));
160 std::memset(&x87, 0, sizeof(x87));
161 std::memset(&xsave_header, 0, sizeof(xsave_header));
162 std::memset(&eavx, 0, sizeof(eavx));
163 std::memset(&dr, 0, sizeof(dr));
164 std::memset(&xcr0, 0, sizeof(xcr0));
165#if defined(OS_LINUX)
166 std::memset(&linux_gp, 0, sizeof(linux_gp));
167#endif
168 }
169
170public:
171 //
172 // Accessors
173 //
174 inline uint64_t pc() const { return gp.rip; }
175 inline void setPC(uint64_t pc) { gp.rip = pc; }
176
177 inline uint64_t sp() const { return gp.rsp; }
178 inline void setSP(uint64_t sp) { gp.rsp = sp; }
179
180 inline uint64_t retval() const { return gp.rax; }
181
182public:
183#define _REGVALUE(REG) \
184 GPRegisterValue { sizeof(gp.REG), gp.REG }
185 //
186 // These two functions interprets regs as GDB packed registers,
187 // the order of GPR state, which is NOT the same order as the reg_gdb_*
188 // (*sigh*)
189 // is as follow:
190 //
191 // rax, rbx, rcx, rdx, rsi, rdi, rbp, rsp, r8,
192 // r9, r10, r11, r12, r13, r14, r15, rip,
193 // eflags, cs, ss, ds, es, fs, gs
194 //
195 inline void getGPState(GPRegisterValueVector &regs) const {
196 regs.clear();
197 regs.push_back(_REGVALUE(rax));
198 regs.push_back(_REGVALUE(rbx));
199 regs.push_back(_REGVALUE(rcx));
200 regs.push_back(_REGVALUE(rdx));
201 regs.push_back(_REGVALUE(rsi));
202 regs.push_back(_REGVALUE(rdi));
203 regs.push_back(_REGVALUE(rbp));
204 regs.push_back(_REGVALUE(rsp));
205 regs.push_back(_REGVALUE(r8));
206 regs.push_back(_REGVALUE(r9));
207 regs.push_back(_REGVALUE(r10));
208 regs.push_back(_REGVALUE(r11));
209 regs.push_back(_REGVALUE(r12));
210 regs.push_back(_REGVALUE(r13));
211 regs.push_back(_REGVALUE(r14));
212 regs.push_back(_REGVALUE(r15));
213 regs.push_back(_REGVALUE(rip));
214 regs.push_back(_REGVALUE(eflags));
215 regs.push_back(_REGVALUE(cs));
216 regs.push_back(_REGVALUE(ss));
217 regs.push_back(_REGVALUE(ds));
218 regs.push_back(_REGVALUE(es));
219 regs.push_back(_REGVALUE(fs));
220 regs.push_back(_REGVALUE(gs));
221 }
222
223 inline void setGPState(std::vector<uint64_t> const &regs) {
224 gp.rax = regs[0];
225 gp.rbx = regs[1];
226 gp.rcx = regs[2];
227 gp.rdx = regs[3];
228 gp.rsi = regs[4];
229 gp.rdi = regs[5];
230 gp.rbp = regs[6];
231 gp.rsp = regs[7];
232 gp.r8 = regs[8];
233 gp.r9 = regs[9];
234 gp.r10 = regs[10];
235 gp.r11 = regs[11];
236 gp.r12 = regs[12];
237 gp.r13 = regs[13];
238 gp.r14 = regs[14];
239 gp.r15 = regs[15];
240 gp.rip = regs[16];
241 gp.eflags = regs[17];
242 gp.cs = regs[18];
243 gp.ss = regs[19];
244 gp.ds = regs[20];
245 gp.es = regs[21];
246 gp.fs = regs[22];
247 gp.gs = regs[23];
248 }
249
250public:
251 inline void getStopGPState(GPRegisterStopMap &regs, bool forLLDB) const {
252 auto set = [&](uint32_t lldbReg, uint32_t gdbReg,
253 const GPRegisterValue &value) {
254 regs[forLLDB ? lldbReg : gdbReg] = value;
255 };
256
257 set(reg_lldb_rax, reg_gdb_rax, _REGVALUE(rax));
258 set(reg_lldb_rcx, reg_gdb_rcx, _REGVALUE(rcx));
259 set(reg_lldb_rdx, reg_gdb_rdx, _REGVALUE(rdx));
260 set(reg_lldb_rbx, reg_gdb_rbx, _REGVALUE(rbx));
261 set(reg_lldb_rsi, reg_gdb_rsi, _REGVALUE(rsi));
262 set(reg_lldb_rdi, reg_gdb_rdi, _REGVALUE(rdi));
263 set(reg_lldb_rsp, reg_gdb_rsp, _REGVALUE(rsp));
264 set(reg_lldb_rbp, reg_gdb_rbp, _REGVALUE(rbp));
265 set(reg_lldb_r8, reg_gdb_r8, _REGVALUE(r8));
266 set(reg_lldb_r9, reg_gdb_r9, _REGVALUE(r9));
267 set(reg_lldb_r10, reg_gdb_r10, _REGVALUE(r10));
268 set(reg_lldb_r11, reg_gdb_r11, _REGVALUE(r11));
269 set(reg_lldb_r12, reg_gdb_r12, _REGVALUE(r12));
270 set(reg_lldb_r13, reg_gdb_r13, _REGVALUE(r13));
271 set(reg_lldb_r14, reg_gdb_r14, _REGVALUE(r14));
272 set(reg_lldb_r15, reg_gdb_r15, _REGVALUE(r15));
273 set(reg_lldb_rip, reg_gdb_rip, _REGVALUE(rip));
274 set(reg_lldb_eflags, reg_gdb_eflags, _REGVALUE(eflags));
275 set(reg_lldb_cs, reg_gdb_cs, _REGVALUE(cs));
276 set(reg_lldb_ss, reg_gdb_ss, _REGVALUE(ss));
277 set(reg_lldb_ds, reg_gdb_ds, _REGVALUE(ds));
278 set(reg_lldb_es, reg_gdb_es, _REGVALUE(es));
279 set(reg_lldb_fs, reg_gdb_fs, _REGVALUE(fs));
280 set(reg_lldb_gs, reg_gdb_gs, _REGVALUE(gs));
281 }
282#undef _REGVALUE
283
284public:
285 inline bool getLLDBRegisterPtr(int regno, void **ptr, size_t *length) const {
286#define _GETREG2(T, REG, FLD) \
287 case reg_lldb_##REG: \
288 *ptr = &const_cast<CPUState64 *>(this)->T.FLD, *length = sizeof(T.FLD); \
289 break
290#define _GETREG8L(T, REG, FREG) \
291 case reg_lldb_##REG: \
292 *ptr = \
293 reinterpret_cast<uint8_t *>(&const_cast<CPUState64 *>(this)->T.FREG), \
294 *length = sizeof(uint8_t); \
295 break
296#define _GETREG8H(T, REG, FREG) \
297 case reg_lldb_##REG: \
298 *ptr = \
299 reinterpret_cast<uint8_t *>(&const_cast<CPUState64 *>(this)->T.FREG) + \
300 1, \
301 *length = sizeof(uint8_t); \
302 break
303#define _GETREG16(T, REG, FREG) \
304 case reg_lldb_##REG: \
305 *ptr = \
306 reinterpret_cast<uint16_t *>(&const_cast<CPUState64 *>(this)->T.FREG), \
307 *length = sizeof(uint16_t); \
308 break
309#define _GETREG32(T, REG, FREG) \
310 case reg_lldb_##REG: \
311 *ptr = \
312 reinterpret_cast<uint32_t *>(&const_cast<CPUState64 *>(this)->T.FREG), \
313 *length = sizeof(uint32_t); \
314 break
315#define _GETREG(T, REG) _GETREG2(T, REG, REG)
316
317 switch (regno) {
318 _GETREG(gp, rax);
319 _GETREG(gp, rbx);
320 _GETREG(gp, rcx);
321 _GETREG(gp, rdx);
322 _GETREG(gp, rsi);
323 _GETREG(gp, rdi);
324 _GETREG(gp, rsp);
325 _GETREG(gp, rbp);
326 _GETREG(gp, r8);
327 _GETREG(gp, r9);
328 _GETREG(gp, r10);
329 _GETREG(gp, r11);
330 _GETREG(gp, r12);
331 _GETREG(gp, r13);
332 _GETREG(gp, r14);
333 _GETREG(gp, r15);
334 _GETREG(gp, rip);
335 _GETREG(gp, cs);
336 _GETREG(gp, ss);
337 _GETREG(gp, ds);
338 _GETREG(gp, es);
339 _GETREG(gp, fs);
340 _GETREG(gp, gs);
341 _GETREG(gp, eflags);
342
343 _GETREG2(x87, st0, regs[0].data);
344 _GETREG2(x87, st1, regs[1].data);
345 _GETREG2(x87, st2, regs[2].data);
346 _GETREG2(x87, st3, regs[3].data);
347 _GETREG2(x87, st4, regs[4].data);
348 _GETREG2(x87, st5, regs[5].data);
349 _GETREG2(x87, st6, regs[6].data);
350 _GETREG2(x87, st7, regs[7].data);
351 _GETREG2(x87, fstat, fstw);
352 _GETREG2(x87, fctrl, fctw);
353 _GETREG(x87, ftag);
354 _GETREG2(x87, fiseg, fiseg);
355 _GETREG2(x87, fioff, fioff);
356 _GETREG2(x87, foseg, foseg);
357 _GETREG2(x87, fooff, fooff);
358 _GETREG(x87, fop);
359
360 _GETREG32(gp, eax, rax);
361 _GETREG32(gp, ebx, rbx);
362 _GETREG32(gp, ecx, rcx);
363 _GETREG32(gp, edx, rdx);
364 _GETREG32(gp, esi, rsi);
365 _GETREG32(gp, edi, rdi);
366 _GETREG32(gp, esp, rsp);
367 _GETREG32(gp, ebp, rbp);
368 _GETREG32(gp, r8d, r8);
369 _GETREG32(gp, r9d, r9);
370 _GETREG32(gp, r10d, r10);
371 _GETREG32(gp, r11d, r11);
372 _GETREG32(gp, r12d, r12);
373 _GETREG32(gp, r13d, r13);
374 _GETREG32(gp, r14d, r14);
375 _GETREG32(gp, r15d, r15);
376
377 _GETREG16(gp, ax, rax);
378 _GETREG16(gp, bx, rbx);
379 _GETREG16(gp, cx, rcx);
380 _GETREG16(gp, dx, rdx);
381 _GETREG16(gp, si, rsi);
382 _GETREG16(gp, di, rdi);
383 _GETREG16(gp, sp, rsp);
384 _GETREG16(gp, bp, rbp);
385 _GETREG16(gp, r8w, r8);
386 _GETREG16(gp, r9w, r9);
387 _GETREG16(gp, r10w, r10);
388 _GETREG16(gp, r11w, r11);
389 _GETREG16(gp, r12w, r12);
390 _GETREG16(gp, r13w, r13);
391 _GETREG16(gp, r14w, r14);
392 _GETREG16(gp, r15w, r15);
393
394 _GETREG8L(gp, al, rax);
395 _GETREG8L(gp, bl, rbx);
396 _GETREG8L(gp, cl, rcx);
397 _GETREG8L(gp, dl, rdx);
398 _GETREG8L(gp, sil, rsi);
399 _GETREG8L(gp, dil, rdi);
400 _GETREG8L(gp, spl, rsp);
401 _GETREG8L(gp, bpl, rbp);
402 _GETREG8L(gp, r8l, r8);
403 _GETREG8L(gp, r9l, r9);
404 _GETREG8L(gp, r10l, r10);
405 _GETREG8L(gp, r11l, r11);
406 _GETREG8L(gp, r12l, r12);
407 _GETREG8L(gp, r13l, r13);
408 _GETREG8L(gp, r14l, r14);
409 _GETREG8L(gp, r15l, r15);
410
411 _GETREG8H(gp, ah, rax);
412 _GETREG8H(gp, bh, rbx);
413 _GETREG8H(gp, ch, rcx);
414 _GETREG8H(gp, dh, rdx);
415
416 _GETREG(avx, mxcsr);
417 _GETREG(avx, mxcsrmask);
418 _GETREG2(avx, ymm0, regs[0]);
419 _GETREG2(avx, ymm1, regs[1]);
420 _GETREG2(avx, ymm2, regs[2]);
421 _GETREG2(avx, ymm3, regs[3]);
422 _GETREG2(avx, ymm4, regs[4]);
423 _GETREG2(avx, ymm5, regs[5]);
424 _GETREG2(avx, ymm6, regs[6]);
425 _GETREG2(avx, ymm7, regs[7]);
426 _GETREG2(avx, ymm8, regs[8]);
427 _GETREG2(avx, ymm9, regs[9]);
428 _GETREG2(avx, ymm10, regs[10]);
429 _GETREG2(avx, ymm11, regs[11]);
430 _GETREG2(avx, ymm12, regs[12]);
431 _GETREG2(avx, ymm13, regs[13]);
432 _GETREG2(avx, ymm14, regs[14]);
433 _GETREG2(avx, ymm15, regs[15]);
434
435 _GETREG2(sse, xmm0, regs[16]);
436 _GETREG2(sse, xmm1, regs[17]);
437 _GETREG2(sse, xmm2, regs[18]);
438 _GETREG2(sse, xmm3, regs[19]);
439 _GETREG2(sse, xmm4, regs[20]);
440 _GETREG2(sse, xmm5, regs[21]);
441 _GETREG2(sse, xmm6, regs[22]);
442 _GETREG2(sse, xmm7, regs[23]);
443 _GETREG2(sse, xmm8, regs[24]);
444 _GETREG2(sse, xmm9, regs[25]);
445 _GETREG2(sse, xmm10, regs[26]);
446 _GETREG2(sse, xmm11, regs[27]);
447 _GETREG2(sse, xmm12, regs[28]);
448 _GETREG2(sse, xmm13, regs[29]);
449 _GETREG2(sse, xmm14, regs[30]);
450 _GETREG2(sse, xmm15, regs[31]);
451
452 default:
453 return false;
454 }
455#undef _GETREG16
456#undef _GETREG8H
457#undef _GETREG8L
458#undef _GETREG
459#undef _GETREG2
460
461 return true;
462 }
463
464 inline bool getGDBRegisterPtr(int regno, void **ptr, size_t *length) const {
465#define _GETREG2(T, REG, FLD) \
466 case reg_gdb_##REG: \
467 *ptr = &const_cast<CPUState64 *>(this)->T.FLD, *length = sizeof(T.FLD); \
468 break
469#define _GETREG(T, REG) _GETREG2(T, REG, REG)
470
471 switch (regno) {
472 _GETREG(gp, rax);
473 _GETREG(gp, rbx);
474 _GETREG(gp, rcx);
475 _GETREG(gp, rdx);
476 _GETREG(gp, rsi);
477 _GETREG(gp, rdi);
478 _GETREG(gp, rsp);
479 _GETREG(gp, rbp);
480 _GETREG(gp, r8);
481 _GETREG(gp, r9);
482 _GETREG(gp, r10);
483 _GETREG(gp, r11);
484 _GETREG(gp, r12);
485 _GETREG(gp, r13);
486 _GETREG(gp, r14);
487 _GETREG(gp, r15);
488 _GETREG(gp, rip);
489 _GETREG(gp, cs);
490 _GETREG(gp, ss);
491 _GETREG(gp, ds);
492 _GETREG(gp, es);
493 _GETREG(gp, fs);
494 _GETREG(gp, gs);
495 _GETREG(gp, eflags);
496
497 _GETREG2(x87, st0, regs[0].data);
498 _GETREG2(x87, st1, regs[1].data);
499 _GETREG2(x87, st2, regs[2].data);
500 _GETREG2(x87, st3, regs[3].data);
501 _GETREG2(x87, st4, regs[4].data);
502 _GETREG2(x87, st5, regs[5].data);
503 _GETREG2(x87, st6, regs[6].data);
504 _GETREG2(x87, st7, regs[7].data);
505 _GETREG2(x87, fstat, fstw);
506 _GETREG2(x87, fctrl, fctw);
507 _GETREG(x87, ftag);
508 _GETREG2(x87, fiseg, fiseg);
509 _GETREG2(x87, fioff, fioff);
510 _GETREG2(x87, foseg, foseg);
511 _GETREG2(x87, fooff, fooff);
512 _GETREG(x87, fop);
513
514 // ymm0 maps to xmm0 for gdb
515 _GETREG2(sse, ymm0, regs[0]);
516 _GETREG2(sse, ymm1, regs[1]);
517 _GETREG2(sse, ymm2, regs[2]);
518 _GETREG2(sse, ymm3, regs[3]);
519 _GETREG2(sse, ymm4, regs[4]);
520 _GETREG2(sse, ymm5, regs[5]);
521 _GETREG2(sse, ymm6, regs[6]);
522 _GETREG2(sse, ymm7, regs[7]);
523 _GETREG2(sse, ymm8, regs[8]);
524 _GETREG2(sse, ymm9, regs[9]);
525 _GETREG2(sse, ymm10, regs[10]);
526 _GETREG2(sse, ymm11, regs[11]);
527 _GETREG2(sse, ymm12, regs[12]);
528 _GETREG2(sse, ymm13, regs[13]);
529 _GETREG2(sse, ymm14, regs[14]);
530 _GETREG2(sse, ymm15, regs[15]);
531
532 _GETREG(sse, mxcsr);
533
534#if defined(OS_LINUX)
535 _GETREG(linux_gp, orig_rax);
536#endif
537
538 default:
539 return false;
540 }
541#undef _GETREG
542#undef _GETREG2
543
544 return true;
545 }
546};
547
548//
549// Define the union of the two variants, this is the public
550// structure.
551//
552
553struct CPUState {
554 bool is32; // Select which is valid between state32 and state64.
555
556 union {
557 CPUState32 state32;
558 CPUState64 state64;
559 };
560
561 CPUState() : state64() {}
562
563 //
564 // Accessors
565 //
566 inline uint64_t pc() const {
567 return is32 ? static_cast<uint64_t>(state32.pc()) : state64.pc();
568 }
569 inline void setPC(uint64_t pc) {
570 if (is32)
571 state32.setPC(pc);
572 else
573 state64.setPC(pc);
574 }
575
576 inline uint64_t sp() const {
577 return is32 ? static_cast<uint64_t>(state32.sp()) : state64.sp();
578 }
579 inline void setSP(uint64_t sp) {
580 if (is32)
581 state32.setSP(sp);
582 else
583 state64.setSP(sp);
584 }
585
586 inline uint64_t retval() const {
587 return is32 ? static_cast<uint64_t>(state32.retval()) : state64.retval();
588 }
589
590public:
591 inline void getGPState(GPRegisterValueVector &regs) const {
592 if (is32) {
593 state32.getGPState(regs);
594 } else {
595 state64.getGPState(regs);
596 }
597 }
598
599 inline void setGPState(std::vector<uint64_t> const &regs) {
600 if (is32) {
601 state32.setGPState(regs);
602 } else {
603 state64.setGPState(regs);
604 }
605 }
606
607public:
608 inline void getStopGPState(GPRegisterStopMap &regs, bool forLLDB) const {
609 if (is32) {
610 state32.getStopGPState(regs, forLLDB);
611 } else {
612 state64.getStopGPState(regs, forLLDB);
613 }
614 }
615
616public:
617 inline bool getLLDBRegisterPtr(int regno, void **ptr, size_t *length) const {
618 if (is32) {
619 return state32.getLLDBRegisterPtr(regno, ptr, length);
620 } else {
621 return state64.getLLDBRegisterPtr(regno, ptr, length);
622 }
623 }
624
625 inline bool getGDBRegisterPtr(int regno, void **ptr, size_t *length) const {
626 if (is32) {
627 return state32.getGDBRegisterPtr(regno, ptr, length);
628 } else {
629 return state64.getGDBRegisterPtr(regno, ptr, length);
630 }
631 }
632};
633} // namespace X86_64
634} // namespace Architecture
635} // namespace ds2
Definition RegisterLayout.h:167
Definition CPUState.h:31
Definition CPUState.h:53
Definition CPUState.h:27
Definition CPUState.h:35
Definition CPUState.h:553