1 | //===-- RegisterContextDarwin_i386.h ----------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H |
10 | #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H |
11 | |
12 | #include "lldb/Target/RegisterContext.h" |
13 | #include "lldb/lldb-private.h" |
14 | |
15 | class RegisterContextDarwin_i386 : public lldb_private::RegisterContext { |
16 | public: |
17 | RegisterContextDarwin_i386(lldb_private::Thread &thread, |
18 | uint32_t concrete_frame_idx); |
19 | |
20 | ~RegisterContextDarwin_i386() override; |
21 | |
22 | void InvalidateAllRegisters() override; |
23 | |
24 | size_t GetRegisterCount() override; |
25 | |
26 | const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; |
27 | |
28 | size_t GetRegisterSetCount() override; |
29 | |
30 | const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; |
31 | |
32 | bool ReadRegister(const lldb_private::RegisterInfo *reg_info, |
33 | lldb_private::RegisterValue &value) override; |
34 | |
35 | bool WriteRegister(const lldb_private::RegisterInfo *reg_info, |
36 | const lldb_private::RegisterValue &value) override; |
37 | |
38 | bool ReadAllRegisterValues(lldb::WritableDataBufferSP &data_sp) override; |
39 | |
40 | bool WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; |
41 | |
42 | uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, |
43 | uint32_t num) override; |
44 | |
45 | bool HardwareSingleStep(bool enable) override; |
46 | |
47 | struct GPR { |
48 | uint32_t eax; |
49 | uint32_t ebx; |
50 | uint32_t ecx; |
51 | uint32_t edx; |
52 | uint32_t edi; |
53 | uint32_t esi; |
54 | uint32_t ebp; |
55 | uint32_t esp; |
56 | uint32_t ss; |
57 | uint32_t eflags; |
58 | uint32_t eip; |
59 | uint32_t cs; |
60 | uint32_t ds; |
61 | uint32_t es; |
62 | uint32_t fs; |
63 | uint32_t gs; |
64 | }; |
65 | |
66 | struct MMSReg { |
67 | uint8_t bytes[10]; |
68 | uint8_t pad[6]; |
69 | }; |
70 | |
71 | struct XMMReg { |
72 | uint8_t bytes[16]; |
73 | }; |
74 | |
75 | struct FPU { |
76 | uint32_t pad[2]; |
77 | uint16_t fcw; |
78 | uint16_t fsw; |
79 | uint8_t ftw; |
80 | uint8_t pad1; |
81 | uint16_t fop; |
82 | uint32_t ip; |
83 | uint16_t cs; |
84 | uint16_t pad2; |
85 | uint32_t dp; |
86 | uint16_t ds; |
87 | uint16_t pad3; |
88 | uint32_t mxcsr; |
89 | uint32_t mxcsrmask; |
90 | MMSReg stmm[8]; |
91 | XMMReg xmm[8]; |
92 | uint8_t pad4[14 * 16]; |
93 | int pad5; |
94 | }; |
95 | |
96 | struct EXC { |
97 | uint32_t trapno; |
98 | uint32_t err; |
99 | uint32_t faultvaddr; |
100 | }; |
101 | |
102 | protected: |
103 | enum { GPRRegSet = 1, FPURegSet = 2, EXCRegSet = 3 }; |
104 | |
105 | enum { |
106 | GPRWordCount = sizeof(GPR) / sizeof(uint32_t), |
107 | FPUWordCount = sizeof(FPU) / sizeof(uint32_t), |
108 | EXCWordCount = sizeof(EXC) / sizeof(uint32_t) |
109 | }; |
110 | |
111 | enum { Read = 0, Write = 1, kNumErrors = 2 }; |
112 | |
113 | GPR gpr; |
114 | FPU fpu; |
115 | EXC exc; |
116 | int gpr_errs[2]; // Read/Write errors |
117 | int fpu_errs[2]; // Read/Write errors |
118 | int exc_errs[2]; // Read/Write errors |
119 | |
120 | void InvalidateAllRegisterStates() { |
121 | SetError(flavor: GPRRegSet, err_idx: Read, err: -1); |
122 | SetError(flavor: FPURegSet, err_idx: Read, err: -1); |
123 | SetError(flavor: EXCRegSet, err_idx: Read, err: -1); |
124 | } |
125 | |
126 | int GetError(int flavor, uint32_t err_idx) const { |
127 | if (err_idx < kNumErrors) { |
128 | switch (flavor) { |
129 | // When getting all errors, just OR all values together to see if |
130 | // we got any kind of error. |
131 | case GPRRegSet: |
132 | return gpr_errs[err_idx]; |
133 | case FPURegSet: |
134 | return fpu_errs[err_idx]; |
135 | case EXCRegSet: |
136 | return exc_errs[err_idx]; |
137 | default: |
138 | break; |
139 | } |
140 | } |
141 | return -1; |
142 | } |
143 | |
144 | bool SetError(int flavor, uint32_t err_idx, int err) { |
145 | if (err_idx < kNumErrors) { |
146 | switch (flavor) { |
147 | case GPRRegSet: |
148 | gpr_errs[err_idx] = err; |
149 | return true; |
150 | |
151 | case FPURegSet: |
152 | fpu_errs[err_idx] = err; |
153 | return true; |
154 | |
155 | case EXCRegSet: |
156 | exc_errs[err_idx] = err; |
157 | return true; |
158 | |
159 | default: |
160 | break; |
161 | } |
162 | } |
163 | return false; |
164 | } |
165 | |
166 | bool RegisterSetIsCached(int set) const { return GetError(flavor: set, err_idx: Read) == 0; } |
167 | |
168 | void LogGPR(lldb_private::Log *log, const char *title); |
169 | |
170 | int ReadGPR(bool force); |
171 | |
172 | int ReadFPU(bool force); |
173 | |
174 | int ReadEXC(bool force); |
175 | |
176 | int WriteGPR(); |
177 | |
178 | int WriteFPU(); |
179 | |
180 | int WriteEXC(); |
181 | |
182 | // Subclasses override these to do the actual reading. |
183 | virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) = 0; |
184 | |
185 | virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0; |
186 | |
187 | virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0; |
188 | |
189 | virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0; |
190 | |
191 | virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0; |
192 | |
193 | virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0; |
194 | |
195 | int ReadRegisterSet(uint32_t set, bool force); |
196 | |
197 | int WriteRegisterSet(uint32_t set); |
198 | |
199 | static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num); |
200 | |
201 | static int GetSetForNativeRegNum(int reg_num); |
202 | |
203 | static size_t GetRegisterInfosCount(); |
204 | |
205 | static const lldb_private::RegisterInfo *GetRegisterInfos(); |
206 | }; |
207 | |
208 | #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_I386_H |
209 | |