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/ARM/RegistersDescriptors.h"
18
19#include <cstring>
20
21namespace ds2 {
22namespace Architecture {
23namespace ARM {
24
25struct VFPSingle {
26#ifdef ENDIAN_BIG
27 uint32_t : 32;
28 uint32_t value;
29#else
30 uint32_t value;
31 uint32_t : 32;
32#endif
33};
34
35struct VFPDouble {
36 uint64_t value;
37};
38
39struct VFPQuad {
40#ifdef ENDIAN_BIG
41 uint64_t hi;
42 uint64_t lo;
43#else
44 uint64_t lo;
45 uint64_t hi;
46#endif
47};
48
49#pragma pack(push, 1)
50
51struct CPUState {
52 union {
53 uint32_t regs[16 + 1];
54 struct {
55 uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, ip, sp, lr, pc,
56 cpsr;
57 };
58 } gp;
59
60 struct {
61 union {
62 VFPSingle sng[32];
63 VFPDouble dbl[32];
64 VFPQuad quad[16];
65 };
66 uint32_t fpscr;
67 } vfp;
68
69 struct {
70 // Breakpoints
71 uint32_t bp_ctrl[32];
72 uint32_t bp_addr[32];
73
74 // Watchpoints
75 uint32_t wp_ctrl[32];
76 uint32_t wp_addr[32];
77 } hbp;
78
79public:
80 CPUState() { clear(); }
81
82 inline void clear() {
83 std::memset(&gp, 0, sizeof(gp));
84 std::memset(&vfp, 0, sizeof(vfp));
85 std::memset(&hbp, 0, sizeof(hbp));
86 }
87
88public:
89 //
90 // Accessors
91 //
92 inline uint32_t pc() const { return gp.pc; }
93 inline void setPC(uint32_t pc) { gp.pc = pc; }
94
95 //
96 // xpc returns the thumb bit
97 //
98 inline uint32_t xpc() const { return gp.pc | (isThumb() ? 1 : 0); }
99
100 inline uint32_t sp() const { return gp.sp; }
101 inline void setSP(uint32_t sp) { gp.sp = sp; }
102
103 inline uint32_t retval() const { return gp.r0; }
104
105 inline bool isThumb() const { return (gp.cpsr & (1 << 5)) != 0; }
106
107public:
108 inline void getGPState(GPRegisterValueVector &regs) const {
109 regs.clear();
110 for (size_t n = 0; n < array_sizeof(gp.regs); n++) {
111 regs.push_back(GPRegisterValue{sizeof(gp.regs[n]), gp.regs[n]});
112 }
113 }
114
115 inline void setGPState(std::vector<uint64_t> const &regs) {
116 for (size_t n = 0; n < regs.size() && n < array_sizeof(gp.regs); n++) {
117 gp.regs[n] = regs[n];
118 }
119 }
120
121public:
122 inline void getStopGPState(GPRegisterStopMap &regs, bool forLLDB) const {
123 if (forLLDB) {
124 for (size_t n = 0; n < 16; n++) {
125 regs[n + reg_lldb_r0] = GPRegisterValue{sizeof(gp.regs[n]), gp.regs[n]};
126 }
127 regs[reg_lldb_cpsr] = GPRegisterValue{sizeof(gp.cpsr), gp.cpsr};
128 } else {
129 //
130 // GDB can live with non-zero registers
131 //
132 for (size_t n = 0; n < 16; n++) {
133 if (n >= 13) {
134 regs[n + reg_gdb_r0] =
135 GPRegisterValue{sizeof(gp.regs[n]), gp.regs[n]};
136 }
137 }
138 regs[reg_gdb_cpsr] = GPRegisterValue{sizeof(gp.cpsr), gp.cpsr};
139 }
140 }
141
142public:
143 inline bool getLLDBRegisterPtr(int regno, void **ptr, size_t *length) const {
144 if (regno >= reg_lldb_r0 && regno <= reg_lldb_r15) {
145 *ptr = const_cast<uint32_t *>(&gp.regs[regno - reg_lldb_r0]);
146 *length = sizeof(gp.regs[0]);
147 } else if (regno == reg_lldb_cpsr) {
148 *ptr = const_cast<uint32_t *>(&gp.cpsr);
149 *length = sizeof(gp.cpsr);
150 } else if (regno >= reg_lldb_d0 && regno <= reg_lldb_d31) {
151 *ptr = const_cast<VFPDouble *>(&vfp.dbl[regno - reg_lldb_d0]);
152 *length = sizeof(vfp.dbl[0]);
153 } else if (regno >= reg_lldb_s0 && regno <= reg_lldb_s31) {
154 *ptr = const_cast<uint32_t *>(&vfp.sng[regno - reg_lldb_s0].value);
155 *length = sizeof(vfp.sng[0].value);
156 } else if (regno >= reg_lldb_q0 && regno <= reg_lldb_q15) {
157 *ptr = const_cast<VFPQuad *>(&vfp.quad[regno - reg_lldb_q0]);
158 *length = sizeof(vfp.quad[0]);
159 } else if (regno == reg_lldb_fpscr) {
160 *ptr = const_cast<uint32_t *>(&vfp.fpscr);
161 *length = sizeof(vfp.fpscr);
162 } else {
163 return false;
164 }
165
166 return true;
167 }
168
169 inline bool getGDBRegisterPtr(int regno, void **ptr, size_t *length) const {
170 if (regno >= reg_gdb_r0 && regno <= reg_gdb_r15) {
171 *ptr = const_cast<uint32_t *>(&gp.regs[regno - reg_gdb_r0]);
172 *length = sizeof(gp.regs[0]);
173 } else if (regno == reg_gdb_cpsr) {
174 *ptr = const_cast<uint32_t *>(&gp.cpsr);
175 *length = sizeof(gp.cpsr);
176 } else if (regno >= reg_gdb_d0 && regno <= reg_gdb_d31) {
177 *ptr = const_cast<VFPDouble *>(&vfp.dbl[regno - reg_gdb_d0]);
178 *length = sizeof(vfp.dbl[0]);
179 } else if (regno == reg_gdb_fpscr) {
180 *ptr = const_cast<uint32_t *>(&vfp.fpscr);
181 *length = sizeof(vfp.fpscr);
182 } else {
183 return false;
184 }
185
186 return true;
187 }
188};
189
190#pragma pack(pop)
191} // namespace ARM
192} // namespace Architecture
193} // namespace ds2
Definition CPUState.h:51
Definition CPUState.h:35
Definition CPUState.h:39
Definition CPUState.h:25
Definition RegisterLayout.h:167