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 if (forLLDB) {
253#define _SETREG(REG) regs[reg_lldb_##REG] = _REGVALUE(REG)
254 _SETREG(rax);
255 _SETREG(rcx);
256 _SETREG(rdx);
257 _SETREG(rbx);
258 _SETREG(rsi);
259 _SETREG(rdi);
260 _SETREG(rsp);
261 _SETREG(rbp);
262 _SETREG(r8);
263 _SETREG(r9);
264 _SETREG(r10);
265 _SETREG(r11);
266 _SETREG(r12);
267 _SETREG(r13);
268 _SETREG(r14);
269 _SETREG(r15);
270 _SETREG(rip);
271 _SETREG(eflags);
272 _SETREG(cs);
273 _SETREG(ss);
274 _SETREG(ds);
275 _SETREG(es);
276 _SETREG(fs);
277 _SETREG(gs);
278#undef _SETREG
279 } else {
280#define _SETREG(REG) regs[reg_gdb_##REG] = _REGVALUE(REG)
281 _SETREG(rax);
282 _SETREG(rcx);
283 _SETREG(rdx);
284 _SETREG(rbx);
285 _SETREG(rsi);
286 _SETREG(rdi);
287 _SETREG(rsp);
288 _SETREG(rbp);
289 _SETREG(r8);
290 _SETREG(r9);
291 _SETREG(r10);
292 _SETREG(r11);
293 _SETREG(r12);
294 _SETREG(r13);
295 _SETREG(r14);
296 _SETREG(r15);
297 _SETREG(rip);
298 _SETREG(eflags);
299 _SETREG(cs);
300 _SETREG(ss);
301 _SETREG(ds);
302 _SETREG(es);
303 _SETREG(fs);
304 _SETREG(gs);
305#undef _SETREG
306 }
307 }
308#undef _REGVALUE
309
310public:
311 inline bool getLLDBRegisterPtr(int regno, void **ptr, size_t *length) const {
312#define _GETREG2(T, REG, FLD) \
313 case reg_lldb_##REG: \
314 *ptr = &const_cast<CPUState64 *>(this)->T.FLD, *length = sizeof(T.FLD); \
315 break
316#define _GETREG8L(T, REG, FREG) \
317 case reg_lldb_##REG: \
318 *ptr = \
319 reinterpret_cast<uint8_t *>(&const_cast<CPUState64 *>(this)->T.FREG), \
320 *length = sizeof(uint8_t); \
321 break
322#define _GETREG8H(T, REG, FREG) \
323 case reg_lldb_##REG: \
324 *ptr = \
325 reinterpret_cast<uint8_t *>(&const_cast<CPUState64 *>(this)->T.FREG) + \
326 1, \
327 *length = sizeof(uint8_t); \
328 break
329#define _GETREG16(T, REG, FREG) \
330 case reg_lldb_##REG: \
331 *ptr = \
332 reinterpret_cast<uint16_t *>(&const_cast<CPUState64 *>(this)->T.FREG), \
333 *length = sizeof(uint16_t); \
334 break
335#define _GETREG32(T, REG, FREG) \
336 case reg_lldb_##REG: \
337 *ptr = \
338 reinterpret_cast<uint32_t *>(&const_cast<CPUState64 *>(this)->T.FREG), \
339 *length = sizeof(uint32_t); \
340 break
341#define _GETREG(T, REG) _GETREG2(T, REG, REG)
342
343 switch (regno) {
344 _GETREG(gp, rax);
345 _GETREG(gp, rbx);
346 _GETREG(gp, rcx);
347 _GETREG(gp, rdx);
348 _GETREG(gp, rsi);
349 _GETREG(gp, rdi);
350 _GETREG(gp, rsp);
351 _GETREG(gp, rbp);
352 _GETREG(gp, r8);
353 _GETREG(gp, r9);
354 _GETREG(gp, r10);
355 _GETREG(gp, r11);
356 _GETREG(gp, r12);
357 _GETREG(gp, r13);
358 _GETREG(gp, r14);
359 _GETREG(gp, r15);
360 _GETREG(gp, rip);
361 _GETREG(gp, cs);
362 _GETREG(gp, ss);
363 _GETREG(gp, ds);
364 _GETREG(gp, es);
365 _GETREG(gp, fs);
366 _GETREG(gp, gs);
367 _GETREG(gp, eflags);
368
369 _GETREG2(x87, st0, regs[0].data);
370 _GETREG2(x87, st1, regs[1].data);
371 _GETREG2(x87, st2, regs[2].data);
372 _GETREG2(x87, st3, regs[3].data);
373 _GETREG2(x87, st4, regs[4].data);
374 _GETREG2(x87, st5, regs[5].data);
375 _GETREG2(x87, st6, regs[6].data);
376 _GETREG2(x87, st7, regs[7].data);
377 _GETREG2(x87, fstat, fstw);
378 _GETREG2(x87, fctrl, fctw);
379 _GETREG(x87, ftag);
380 _GETREG2(x87, fiseg, fiseg);
381 _GETREG2(x87, fioff, fioff);
382 _GETREG2(x87, foseg, foseg);
383 _GETREG2(x87, fooff, fooff);
384 _GETREG(x87, fop);
385
386 _GETREG32(gp, eax, rax);
387 _GETREG32(gp, ebx, rbx);
388 _GETREG32(gp, ecx, rcx);
389 _GETREG32(gp, edx, rdx);
390 _GETREG32(gp, esi, rsi);
391 _GETREG32(gp, edi, rdi);
392 _GETREG32(gp, esp, rsp);
393 _GETREG32(gp, ebp, rbp);
394 _GETREG32(gp, r8d, r8);
395 _GETREG32(gp, r9d, r9);
396 _GETREG32(gp, r10d, r10);
397 _GETREG32(gp, r11d, r11);
398 _GETREG32(gp, r12d, r12);
399 _GETREG32(gp, r13d, r13);
400 _GETREG32(gp, r14d, r14);
401 _GETREG32(gp, r15d, r15);
402
403 _GETREG16(gp, ax, rax);
404 _GETREG16(gp, bx, rbx);
405 _GETREG16(gp, cx, rcx);
406 _GETREG16(gp, dx, rdx);
407 _GETREG16(gp, si, rsi);
408 _GETREG16(gp, di, rdi);
409 _GETREG16(gp, sp, rsp);
410 _GETREG16(gp, bp, rbp);
411 _GETREG16(gp, r8w, r8);
412 _GETREG16(gp, r9w, r9);
413 _GETREG16(gp, r10w, r10);
414 _GETREG16(gp, r11w, r11);
415 _GETREG16(gp, r12w, r12);
416 _GETREG16(gp, r13w, r13);
417 _GETREG16(gp, r14w, r14);
418 _GETREG16(gp, r15w, r15);
419
420 _GETREG8L(gp, al, rax);
421 _GETREG8L(gp, bl, rbx);
422 _GETREG8L(gp, cl, rcx);
423 _GETREG8L(gp, dl, rdx);
424 _GETREG8L(gp, sil, rsi);
425 _GETREG8L(gp, dil, rdi);
426 _GETREG8L(gp, spl, rsp);
427 _GETREG8L(gp, bpl, rbp);
428 _GETREG8L(gp, r8l, r8);
429 _GETREG8L(gp, r9l, r9);
430 _GETREG8L(gp, r10l, r10);
431 _GETREG8L(gp, r11l, r11);
432 _GETREG8L(gp, r12l, r12);
433 _GETREG8L(gp, r13l, r13);
434 _GETREG8L(gp, r14l, r14);
435 _GETREG8L(gp, r15l, r15);
436
437 _GETREG8H(gp, ah, rax);
438 _GETREG8H(gp, bh, rbx);
439 _GETREG8H(gp, ch, rcx);
440 _GETREG8H(gp, dh, rdx);
441
442 _GETREG(avx, mxcsr);
443 _GETREG(avx, mxcsrmask);
444 _GETREG2(avx, ymm0, regs[0]);
445 _GETREG2(avx, ymm1, regs[1]);
446 _GETREG2(avx, ymm2, regs[2]);
447 _GETREG2(avx, ymm3, regs[3]);
448 _GETREG2(avx, ymm4, regs[4]);
449 _GETREG2(avx, ymm5, regs[5]);
450 _GETREG2(avx, ymm6, regs[6]);
451 _GETREG2(avx, ymm7, regs[7]);
452 _GETREG2(avx, ymm8, regs[8]);
453 _GETREG2(avx, ymm9, regs[9]);
454 _GETREG2(avx, ymm10, regs[10]);
455 _GETREG2(avx, ymm11, regs[11]);
456 _GETREG2(avx, ymm12, regs[12]);
457 _GETREG2(avx, ymm13, regs[13]);
458 _GETREG2(avx, ymm14, regs[14]);
459 _GETREG2(avx, ymm15, regs[15]);
460
461 _GETREG2(sse, xmm0, regs[16]);
462 _GETREG2(sse, xmm1, regs[17]);
463 _GETREG2(sse, xmm2, regs[18]);
464 _GETREG2(sse, xmm3, regs[19]);
465 _GETREG2(sse, xmm4, regs[20]);
466 _GETREG2(sse, xmm5, regs[21]);
467 _GETREG2(sse, xmm6, regs[22]);
468 _GETREG2(sse, xmm7, regs[23]);
469 _GETREG2(sse, xmm8, regs[24]);
470 _GETREG2(sse, xmm9, regs[25]);
471 _GETREG2(sse, xmm10, regs[26]);
472 _GETREG2(sse, xmm11, regs[27]);
473 _GETREG2(sse, xmm12, regs[28]);
474 _GETREG2(sse, xmm13, regs[29]);
475 _GETREG2(sse, xmm14, regs[30]);
476 _GETREG2(sse, xmm15, regs[31]);
477
478 default:
479 return false;
480 }
481#undef _GETREG16
482#undef _GETREG8H
483#undef _GETREG8L
484#undef _GETREG
485#undef _GETREG2
486
487 return true;
488 }
489
490 inline bool getGDBRegisterPtr(int regno, void **ptr, size_t *length) const {
491#define _GETREG2(T, REG, FLD) \
492 case reg_gdb_##REG: \
493 *ptr = &const_cast<CPUState64 *>(this)->T.FLD, *length = sizeof(T.FLD); \
494 break
495#define _GETREG(T, REG) _GETREG2(T, REG, REG)
496
497 switch (regno) {
498 _GETREG(gp, rax);
499 _GETREG(gp, rbx);
500 _GETREG(gp, rcx);
501 _GETREG(gp, rdx);
502 _GETREG(gp, rsi);
503 _GETREG(gp, rdi);
504 _GETREG(gp, rsp);
505 _GETREG(gp, rbp);
506 _GETREG(gp, r8);
507 _GETREG(gp, r9);
508 _GETREG(gp, r10);
509 _GETREG(gp, r11);
510 _GETREG(gp, r12);
511 _GETREG(gp, r13);
512 _GETREG(gp, r14);
513 _GETREG(gp, r15);
514 _GETREG(gp, rip);
515 _GETREG(gp, cs);
516 _GETREG(gp, ss);
517 _GETREG(gp, ds);
518 _GETREG(gp, es);
519 _GETREG(gp, fs);
520 _GETREG(gp, gs);
521 _GETREG(gp, eflags);
522
523 _GETREG2(x87, st0, regs[0].data);
524 _GETREG2(x87, st1, regs[1].data);
525 _GETREG2(x87, st2, regs[2].data);
526 _GETREG2(x87, st3, regs[3].data);
527 _GETREG2(x87, st4, regs[4].data);
528 _GETREG2(x87, st5, regs[5].data);
529 _GETREG2(x87, st6, regs[6].data);
530 _GETREG2(x87, st7, regs[7].data);
531 _GETREG2(x87, fstat, fstw);
532 _GETREG2(x87, fctrl, fctw);
533 _GETREG(x87, ftag);
534 _GETREG2(x87, fiseg, fiseg);
535 _GETREG2(x87, fioff, fioff);
536 _GETREG2(x87, foseg, foseg);
537 _GETREG2(x87, fooff, fooff);
538 _GETREG(x87, fop);
539
540 // ymm0 maps to xmm0 for gdb
541 _GETREG2(sse, ymm0, regs[0]);
542 _GETREG2(sse, ymm1, regs[1]);
543 _GETREG2(sse, ymm2, regs[2]);
544 _GETREG2(sse, ymm3, regs[3]);
545 _GETREG2(sse, ymm4, regs[4]);
546 _GETREG2(sse, ymm5, regs[5]);
547 _GETREG2(sse, ymm6, regs[6]);
548 _GETREG2(sse, ymm7, regs[7]);
549 _GETREG2(sse, ymm8, regs[8]);
550 _GETREG2(sse, ymm9, regs[9]);
551 _GETREG2(sse, ymm10, regs[10]);
552 _GETREG2(sse, ymm11, regs[11]);
553 _GETREG2(sse, ymm12, regs[12]);
554 _GETREG2(sse, ymm13, regs[13]);
555 _GETREG2(sse, ymm14, regs[14]);
556 _GETREG2(sse, ymm15, regs[15]);
557
558 _GETREG(sse, mxcsr);
559
560#if defined(OS_LINUX)
561 _GETREG(linux_gp, orig_rax);
562#endif
563
564 default:
565 return false;
566 }
567#undef _GETREG
568#undef _GETREG2
569
570 return true;
571 }
572};
573
574//
575// Define the union of the two variants, this is the public
576// structure.
577//
578
579struct CPUState {
580 bool is32; // Select which is valid between state32 and state64.
581
582 union {
583 CPUState32 state32;
584 CPUState64 state64;
585 };
586
587 CPUState() : state64() {}
588
589 //
590 // Accessors
591 //
592 inline uint64_t pc() const {
593 return is32 ? static_cast<uint64_t>(state32.pc()) : state64.pc();
594 }
595 inline void setPC(uint64_t pc) {
596 if (is32)
597 state32.setPC(pc);
598 else
599 state64.setPC(pc);
600 }
601
602 inline uint64_t sp() const {
603 return is32 ? static_cast<uint64_t>(state32.sp()) : state64.sp();
604 }
605 inline void setSP(uint64_t sp) {
606 if (is32)
607 state32.setSP(sp);
608 else
609 state64.setSP(sp);
610 }
611
612 inline uint64_t retval() const {
613 return is32 ? static_cast<uint64_t>(state32.retval()) : state64.retval();
614 }
615
616public:
617 inline void getGPState(GPRegisterValueVector &regs) const {
618 if (is32) {
619 state32.getGPState(regs);
620 } else {
621 state64.getGPState(regs);
622 }
623 }
624
625 inline void setGPState(std::vector<uint64_t> const &regs) {
626 if (is32) {
627 state32.setGPState(regs);
628 } else {
629 state64.setGPState(regs);
630 }
631 }
632
633public:
634 inline void getStopGPState(GPRegisterStopMap &regs, bool forLLDB) const {
635 if (is32) {
636 state32.getStopGPState(regs, forLLDB);
637 } else {
638 state64.getStopGPState(regs, forLLDB);
639 }
640 }
641
642public:
643 inline bool getLLDBRegisterPtr(int regno, void **ptr, size_t *length) const {
644 if (is32) {
645 return state32.getLLDBRegisterPtr(regno, ptr, length);
646 } else {
647 return state64.getLLDBRegisterPtr(regno, ptr, length);
648 }
649 }
650
651 inline bool getGDBRegisterPtr(int regno, void **ptr, size_t *length) const {
652 if (is32) {
653 return state32.getGDBRegisterPtr(regno, ptr, length);
654 } else {
655 return state64.getGDBRegisterPtr(regno, ptr, length);
656 }
657 }
658};
659} // namespace X86_64
660} // namespace Architecture
661} // namespace ds2
Definition CPUState.h:31
Definition CPUState.h:53
Definition CPUState.h:27
Definition CPUState.h:35
Definition CPUState.h:579