1 //===-- RegisterContextDarwin_x86_64.cpp ----------------------------------===//
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 #include <cinttypes>
10 #include <cstdarg>
11 #include <cstddef>
12
13 #include <memory>
14
15 #include "lldb/Utility/DataBufferHeap.h"
16 #include "lldb/Utility/DataExtractor.h"
17 #include "lldb/Utility/Endian.h"
18 #include "lldb/Utility/Log.h"
19 #include "lldb/Utility/RegisterValue.h"
20 #include "lldb/Utility/Scalar.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/Support/Compiler.h"
23
24 #include "RegisterContextDarwin_x86_64.h"
25
26 using namespace lldb;
27 using namespace lldb_private;
28
29 enum {
30 gpr_rax = 0,
31 gpr_rbx,
32 gpr_rcx,
33 gpr_rdx,
34 gpr_rdi,
35 gpr_rsi,
36 gpr_rbp,
37 gpr_rsp,
38 gpr_r8,
39 gpr_r9,
40 gpr_r10,
41 gpr_r11,
42 gpr_r12,
43 gpr_r13,
44 gpr_r14,
45 gpr_r15,
46 gpr_rip,
47 gpr_rflags,
48 gpr_cs,
49 gpr_fs,
50 gpr_gs,
51
52 fpu_fcw,
53 fpu_fsw,
54 fpu_ftw,
55 fpu_fop,
56 fpu_ip,
57 fpu_cs,
58 fpu_dp,
59 fpu_ds,
60 fpu_mxcsr,
61 fpu_mxcsrmask,
62 fpu_stmm0,
63 fpu_stmm1,
64 fpu_stmm2,
65 fpu_stmm3,
66 fpu_stmm4,
67 fpu_stmm5,
68 fpu_stmm6,
69 fpu_stmm7,
70 fpu_xmm0,
71 fpu_xmm1,
72 fpu_xmm2,
73 fpu_xmm3,
74 fpu_xmm4,
75 fpu_xmm5,
76 fpu_xmm6,
77 fpu_xmm7,
78 fpu_xmm8,
79 fpu_xmm9,
80 fpu_xmm10,
81 fpu_xmm11,
82 fpu_xmm12,
83 fpu_xmm13,
84 fpu_xmm14,
85 fpu_xmm15,
86
87 exc_trapno,
88 exc_err,
89 exc_faultvaddr,
90
91 k_num_registers,
92
93 // Aliases
94 fpu_fctrl = fpu_fcw,
95 fpu_fstat = fpu_fsw,
96 fpu_ftag = fpu_ftw,
97 fpu_fiseg = fpu_cs,
98 fpu_fioff = fpu_ip,
99 fpu_foseg = fpu_ds,
100 fpu_fooff = fpu_dp
101 };
102
103 enum ehframe_dwarf_regnums {
104 ehframe_dwarf_gpr_rax = 0,
105 ehframe_dwarf_gpr_rdx,
106 ehframe_dwarf_gpr_rcx,
107 ehframe_dwarf_gpr_rbx,
108 ehframe_dwarf_gpr_rsi,
109 ehframe_dwarf_gpr_rdi,
110 ehframe_dwarf_gpr_rbp,
111 ehframe_dwarf_gpr_rsp,
112 ehframe_dwarf_gpr_r8,
113 ehframe_dwarf_gpr_r9,
114 ehframe_dwarf_gpr_r10,
115 ehframe_dwarf_gpr_r11,
116 ehframe_dwarf_gpr_r12,
117 ehframe_dwarf_gpr_r13,
118 ehframe_dwarf_gpr_r14,
119 ehframe_dwarf_gpr_r15,
120 ehframe_dwarf_gpr_rip,
121 ehframe_dwarf_fpu_xmm0,
122 ehframe_dwarf_fpu_xmm1,
123 ehframe_dwarf_fpu_xmm2,
124 ehframe_dwarf_fpu_xmm3,
125 ehframe_dwarf_fpu_xmm4,
126 ehframe_dwarf_fpu_xmm5,
127 ehframe_dwarf_fpu_xmm6,
128 ehframe_dwarf_fpu_xmm7,
129 ehframe_dwarf_fpu_xmm8,
130 ehframe_dwarf_fpu_xmm9,
131 ehframe_dwarf_fpu_xmm10,
132 ehframe_dwarf_fpu_xmm11,
133 ehframe_dwarf_fpu_xmm12,
134 ehframe_dwarf_fpu_xmm13,
135 ehframe_dwarf_fpu_xmm14,
136 ehframe_dwarf_fpu_xmm15,
137 ehframe_dwarf_fpu_stmm0,
138 ehframe_dwarf_fpu_stmm1,
139 ehframe_dwarf_fpu_stmm2,
140 ehframe_dwarf_fpu_stmm3,
141 ehframe_dwarf_fpu_stmm4,
142 ehframe_dwarf_fpu_stmm5,
143 ehframe_dwarf_fpu_stmm6,
144 ehframe_dwarf_fpu_stmm7
145
146 };
147
148 #define GPR_OFFSET(reg) \
149 (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::GPR, reg))
150 #define FPU_OFFSET(reg) \
151 (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::FPU, reg) + \
152 sizeof(RegisterContextDarwin_x86_64::GPR))
153 #define EXC_OFFSET(reg) \
154 (LLVM_EXTENSION offsetof(RegisterContextDarwin_x86_64::EXC, reg) + \
155 sizeof(RegisterContextDarwin_x86_64::GPR) + \
156 sizeof(RegisterContextDarwin_x86_64::FPU))
157
158 // These macros will auto define the register name, alt name, register size,
159 // register offset, encoding, format and native register. This ensures that the
160 // register state structures are defined correctly and have the correct sizes
161 // and offsets.
162 #define DEFINE_GPR(reg, alt) \
163 #reg, alt, sizeof(((RegisterContextDarwin_x86_64::GPR *) NULL)->reg), \
164 GPR_OFFSET(reg), eEncodingUint, eFormatHex
165 #define DEFINE_FPU_UINT(reg) \
166 #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg), \
167 FPU_OFFSET(reg), eEncodingUint, eFormatHex
168 #define DEFINE_FPU_VECT(reg, i) \
169 #reg #i, NULL, \
170 sizeof(((RegisterContextDarwin_x86_64::FPU *) NULL)->reg[i].bytes), \
171 FPU_OFFSET(reg[i]), eEncodingVector, eFormatVectorOfUInt8, \
172 {ehframe_dwarf_fpu_##reg##i, \
173 ehframe_dwarf_fpu_##reg##i, LLDB_INVALID_REGNUM, \
174 LLDB_INVALID_REGNUM, fpu_##reg##i }, \
175 nullptr, nullptr,
176 #define DEFINE_EXC(reg) \
177 #reg, NULL, sizeof(((RegisterContextDarwin_x86_64::EXC *) NULL)->reg), \
178 EXC_OFFSET(reg), eEncodingUint, eFormatHex
179
180 #define REG_CONTEXT_SIZE \
181 (sizeof(RegisterContextDarwin_x86_64::GPR) + \
182 sizeof(RegisterContextDarwin_x86_64::FPU) + \
183 sizeof(RegisterContextDarwin_x86_64::EXC))
184
185 // General purpose registers for 64 bit
186 static RegisterInfo g_register_infos[] = {
187 // Macro auto defines most stuff EH_FRAME DWARF
188 // GENERIC PROCESS PLUGIN LLDB
189 // =============================== ======================
190 // =================== ========================== ====================
191 // ===================
192 {DEFINE_GPR(rax, nullptr),
193 {ehframe_dwarf_gpr_rax, ehframe_dwarf_gpr_rax, LLDB_INVALID_REGNUM,
194 LLDB_INVALID_REGNUM, gpr_rax},
195 nullptr,
196 nullptr,
197 },
198 {DEFINE_GPR(rbx, nullptr),
199 {ehframe_dwarf_gpr_rbx, ehframe_dwarf_gpr_rbx, LLDB_INVALID_REGNUM,
200 LLDB_INVALID_REGNUM, gpr_rbx},
201 nullptr,
202 nullptr,
203 },
204 {DEFINE_GPR(rcx, nullptr),
205 {ehframe_dwarf_gpr_rcx, ehframe_dwarf_gpr_rcx, LLDB_INVALID_REGNUM,
206 LLDB_INVALID_REGNUM, gpr_rcx},
207 nullptr,
208 nullptr,
209 },
210 {DEFINE_GPR(rdx, nullptr),
211 {ehframe_dwarf_gpr_rdx, ehframe_dwarf_gpr_rdx, LLDB_INVALID_REGNUM,
212 LLDB_INVALID_REGNUM, gpr_rdx},
213 nullptr,
214 nullptr,
215 },
216 {DEFINE_GPR(rdi, nullptr),
217 {ehframe_dwarf_gpr_rdi, ehframe_dwarf_gpr_rdi, LLDB_INVALID_REGNUM,
218 LLDB_INVALID_REGNUM, gpr_rdi},
219 nullptr,
220 nullptr,
221 },
222 {DEFINE_GPR(rsi, nullptr),
223 {ehframe_dwarf_gpr_rsi, ehframe_dwarf_gpr_rsi, LLDB_INVALID_REGNUM,
224 LLDB_INVALID_REGNUM, gpr_rsi},
225 nullptr,
226 nullptr,
227 },
228 {DEFINE_GPR(rbp, "fp"),
229 {ehframe_dwarf_gpr_rbp, ehframe_dwarf_gpr_rbp, LLDB_REGNUM_GENERIC_FP,
230 LLDB_INVALID_REGNUM, gpr_rbp},
231 nullptr,
232 nullptr,
233 },
234 {DEFINE_GPR(rsp, "sp"),
235 {ehframe_dwarf_gpr_rsp, ehframe_dwarf_gpr_rsp, LLDB_REGNUM_GENERIC_SP,
236 LLDB_INVALID_REGNUM, gpr_rsp},
237 nullptr,
238 nullptr,
239 },
240 {DEFINE_GPR(r8, nullptr),
241 {ehframe_dwarf_gpr_r8, ehframe_dwarf_gpr_r8, LLDB_INVALID_REGNUM,
242 LLDB_INVALID_REGNUM, gpr_r8},
243 nullptr,
244 nullptr,
245 },
246 {DEFINE_GPR(r9, nullptr),
247 {ehframe_dwarf_gpr_r9, ehframe_dwarf_gpr_r9, LLDB_INVALID_REGNUM,
248 LLDB_INVALID_REGNUM, gpr_r9},
249 nullptr,
250 nullptr,
251 },
252 {DEFINE_GPR(r10, nullptr),
253 {ehframe_dwarf_gpr_r10, ehframe_dwarf_gpr_r10, LLDB_INVALID_REGNUM,
254 LLDB_INVALID_REGNUM, gpr_r10},
255 nullptr,
256 nullptr,
257 },
258 {DEFINE_GPR(r11, nullptr),
259 {ehframe_dwarf_gpr_r11, ehframe_dwarf_gpr_r11, LLDB_INVALID_REGNUM,
260 LLDB_INVALID_REGNUM, gpr_r11},
261 nullptr,
262 nullptr,
263 },
264 {DEFINE_GPR(r12, nullptr),
265 {ehframe_dwarf_gpr_r12, ehframe_dwarf_gpr_r12, LLDB_INVALID_REGNUM,
266 LLDB_INVALID_REGNUM, gpr_r12},
267 nullptr,
268 nullptr,
269 },
270 {DEFINE_GPR(r13, nullptr),
271 {ehframe_dwarf_gpr_r13, ehframe_dwarf_gpr_r13, LLDB_INVALID_REGNUM,
272 LLDB_INVALID_REGNUM, gpr_r13},
273 nullptr,
274 nullptr,
275 },
276 {DEFINE_GPR(r14, nullptr),
277 {ehframe_dwarf_gpr_r14, ehframe_dwarf_gpr_r14, LLDB_INVALID_REGNUM,
278 LLDB_INVALID_REGNUM, gpr_r14},
279 nullptr,
280 nullptr,
281 },
282 {DEFINE_GPR(r15, nullptr),
283 {ehframe_dwarf_gpr_r15, ehframe_dwarf_gpr_r15, LLDB_INVALID_REGNUM,
284 LLDB_INVALID_REGNUM, gpr_r15},
285 nullptr,
286 nullptr,
287 },
288 {DEFINE_GPR(rip, "pc"),
289 {ehframe_dwarf_gpr_rip, ehframe_dwarf_gpr_rip, LLDB_REGNUM_GENERIC_PC,
290 LLDB_INVALID_REGNUM, gpr_rip},
291 nullptr,
292 nullptr,
293 },
294 {DEFINE_GPR(rflags, "flags"),
295 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_REGNUM_GENERIC_FLAGS,
296 LLDB_INVALID_REGNUM, gpr_rflags},
297 nullptr,
298 nullptr,
299 },
300 {DEFINE_GPR(cs, nullptr),
301 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
302 LLDB_INVALID_REGNUM, gpr_cs},
303 nullptr,
304 nullptr,
305 },
306 {DEFINE_GPR(fs, nullptr),
307 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
308 LLDB_INVALID_REGNUM, gpr_fs},
309 nullptr,
310 nullptr,
311 },
312 {DEFINE_GPR(gs, nullptr),
313 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
314 LLDB_INVALID_REGNUM, gpr_gs},
315 nullptr,
316 nullptr,
317 },
318
319 {DEFINE_FPU_UINT(fcw),
320 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
321 LLDB_INVALID_REGNUM, fpu_fcw},
322 nullptr,
323 nullptr,
324 },
325 {DEFINE_FPU_UINT(fsw),
326 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
327 LLDB_INVALID_REGNUM, fpu_fsw},
328 nullptr,
329 nullptr,
330 },
331 {DEFINE_FPU_UINT(ftw),
332 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
333 LLDB_INVALID_REGNUM, fpu_ftw},
334 nullptr,
335 nullptr,
336 },
337 {DEFINE_FPU_UINT(fop),
338 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
339 LLDB_INVALID_REGNUM, fpu_fop},
340 nullptr,
341 nullptr,
342 },
343 {DEFINE_FPU_UINT(ip),
344 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
345 LLDB_INVALID_REGNUM, fpu_ip},
346 nullptr,
347 nullptr,
348 },
349 {DEFINE_FPU_UINT(cs),
350 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
351 LLDB_INVALID_REGNUM, fpu_cs},
352 nullptr,
353 nullptr,
354 },
355 {DEFINE_FPU_UINT(dp),
356 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
357 LLDB_INVALID_REGNUM, fpu_dp},
358 nullptr,
359 nullptr,
360 },
361 {DEFINE_FPU_UINT(ds),
362 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
363 LLDB_INVALID_REGNUM, fpu_ds},
364 nullptr,
365 nullptr,
366 },
367 {DEFINE_FPU_UINT(mxcsr),
368 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
369 LLDB_INVALID_REGNUM, fpu_mxcsr},
370 nullptr,
371 nullptr,
372 },
373 {DEFINE_FPU_UINT(mxcsrmask),
374 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
375 LLDB_INVALID_REGNUM, fpu_mxcsrmask},
376 nullptr,
377 nullptr,
378 },
379 {DEFINE_FPU_VECT(stmm, 0)},
380 {DEFINE_FPU_VECT(stmm, 1)},
381 {DEFINE_FPU_VECT(stmm, 2)},
382 {DEFINE_FPU_VECT(stmm, 3)},
383 {DEFINE_FPU_VECT(stmm, 4)},
384 {DEFINE_FPU_VECT(stmm, 5)},
385 {DEFINE_FPU_VECT(stmm, 6)},
386 {DEFINE_FPU_VECT(stmm, 7)},
387 {DEFINE_FPU_VECT(xmm, 0)},
388 {DEFINE_FPU_VECT(xmm, 1)},
389 {DEFINE_FPU_VECT(xmm, 2)},
390 {DEFINE_FPU_VECT(xmm, 3)},
391 {DEFINE_FPU_VECT(xmm, 4)},
392 {DEFINE_FPU_VECT(xmm, 5)},
393 {DEFINE_FPU_VECT(xmm, 6)},
394 {DEFINE_FPU_VECT(xmm, 7)},
395 {DEFINE_FPU_VECT(xmm, 8)},
396 {DEFINE_FPU_VECT(xmm, 9)},
397 {DEFINE_FPU_VECT(xmm, 10)},
398 {DEFINE_FPU_VECT(xmm, 11)},
399 {DEFINE_FPU_VECT(xmm, 12)},
400 {DEFINE_FPU_VECT(xmm, 13)},
401 {DEFINE_FPU_VECT(xmm, 14)},
402 {DEFINE_FPU_VECT(xmm, 15)},
403
404 {DEFINE_EXC(trapno),
405 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
406 LLDB_INVALID_REGNUM, exc_trapno},
407 nullptr,
408 nullptr,
409 },
410 {DEFINE_EXC(err),
411 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
412 LLDB_INVALID_REGNUM, exc_err},
413 nullptr,
414 nullptr,
415 },
416 {DEFINE_EXC(faultvaddr),
417 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
418 LLDB_INVALID_REGNUM, exc_faultvaddr},
419 nullptr,
420 nullptr,
421 }};
422
423 static size_t k_num_register_infos = std::size(g_register_infos);
424
RegisterContextDarwin_x86_64(Thread & thread,uint32_t concrete_frame_idx)425 RegisterContextDarwin_x86_64::RegisterContextDarwin_x86_64(
426 Thread &thread, uint32_t concrete_frame_idx)
427 : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {
428 uint32_t i;
429 for (i = 0; i < kNumErrors; i++) {
430 gpr_errs[i] = -1;
431 fpu_errs[i] = -1;
432 exc_errs[i] = -1;
433 }
434 }
435
436 RegisterContextDarwin_x86_64::~RegisterContextDarwin_x86_64() = default;
437
InvalidateAllRegisters()438 void RegisterContextDarwin_x86_64::InvalidateAllRegisters() {
439 InvalidateAllRegisterStates();
440 }
441
GetRegisterCount()442 size_t RegisterContextDarwin_x86_64::GetRegisterCount() {
443 assert(k_num_register_infos == k_num_registers);
444 return k_num_registers;
445 }
446
447 const RegisterInfo *
GetRegisterInfoAtIndex(size_t reg)448 RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex(size_t reg) {
449 assert(k_num_register_infos == k_num_registers);
450 if (reg < k_num_registers)
451 return &g_register_infos[reg];
452 return nullptr;
453 }
454
GetRegisterInfosCount()455 size_t RegisterContextDarwin_x86_64::GetRegisterInfosCount() {
456 return k_num_register_infos;
457 }
458
459 const lldb_private::RegisterInfo *
GetRegisterInfos()460 RegisterContextDarwin_x86_64::GetRegisterInfos() {
461 return g_register_infos;
462 }
463
464 static uint32_t g_gpr_regnums[] = {
465 gpr_rax, gpr_rbx, gpr_rcx, gpr_rdx, gpr_rdi, gpr_rsi, gpr_rbp,
466 gpr_rsp, gpr_r8, gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_r13,
467 gpr_r14, gpr_r15, gpr_rip, gpr_rflags, gpr_cs, gpr_fs, gpr_gs};
468
469 static uint32_t g_fpu_regnums[] = {
470 fpu_fcw, fpu_fsw, fpu_ftw, fpu_fop, fpu_ip, fpu_cs,
471 fpu_dp, fpu_ds, fpu_mxcsr, fpu_mxcsrmask, fpu_stmm0, fpu_stmm1,
472 fpu_stmm2, fpu_stmm3, fpu_stmm4, fpu_stmm5, fpu_stmm6, fpu_stmm7,
473 fpu_xmm0, fpu_xmm1, fpu_xmm2, fpu_xmm3, fpu_xmm4, fpu_xmm5,
474 fpu_xmm6, fpu_xmm7, fpu_xmm8, fpu_xmm9, fpu_xmm10, fpu_xmm11,
475 fpu_xmm12, fpu_xmm13, fpu_xmm14, fpu_xmm15};
476
477 static uint32_t g_exc_regnums[] = {exc_trapno, exc_err, exc_faultvaddr};
478
479 // Number of registers in each register set
480 const size_t k_num_gpr_registers = std::size(g_gpr_regnums);
481 const size_t k_num_fpu_registers = std::size(g_fpu_regnums);
482 const size_t k_num_exc_registers = std::size(g_exc_regnums);
483
484 // Register set definitions. The first definitions at register set index of
485 // zero is for all registers, followed by other registers sets. The register
486 // information for the all register set need not be filled in.
487 static const RegisterSet g_reg_sets[] = {
488 {
489 "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,
490 },
491 {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},
492 {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};
493
494 const size_t k_num_regsets = std::size(g_reg_sets);
495
GetRegisterSetCount()496 size_t RegisterContextDarwin_x86_64::GetRegisterSetCount() {
497 return k_num_regsets;
498 }
499
500 const RegisterSet *
GetRegisterSet(size_t reg_set)501 RegisterContextDarwin_x86_64::GetRegisterSet(size_t reg_set) {
502 if (reg_set < k_num_regsets)
503 return &g_reg_sets[reg_set];
504 return nullptr;
505 }
506
GetSetForNativeRegNum(int reg_num)507 int RegisterContextDarwin_x86_64::GetSetForNativeRegNum(int reg_num) {
508 if (reg_num < fpu_fcw)
509 return GPRRegSet;
510 else if (reg_num < exc_trapno)
511 return FPURegSet;
512 else if (reg_num < k_num_registers)
513 return EXCRegSet;
514 return -1;
515 }
516
ReadGPR(bool force)517 int RegisterContextDarwin_x86_64::ReadGPR(bool force) {
518 int set = GPRRegSet;
519 if (force || !RegisterSetIsCached(set)) {
520 SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));
521 }
522 return GetError(GPRRegSet, Read);
523 }
524
ReadFPU(bool force)525 int RegisterContextDarwin_x86_64::ReadFPU(bool force) {
526 int set = FPURegSet;
527 if (force || !RegisterSetIsCached(set)) {
528 SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));
529 }
530 return GetError(FPURegSet, Read);
531 }
532
ReadEXC(bool force)533 int RegisterContextDarwin_x86_64::ReadEXC(bool force) {
534 int set = EXCRegSet;
535 if (force || !RegisterSetIsCached(set)) {
536 SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));
537 }
538 return GetError(EXCRegSet, Read);
539 }
540
WriteGPR()541 int RegisterContextDarwin_x86_64::WriteGPR() {
542 int set = GPRRegSet;
543 if (!RegisterSetIsCached(set)) {
544 SetError(set, Write, -1);
545 return -1;
546 }
547 SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));
548 SetError(set, Read, -1);
549 return GetError(set, Write);
550 }
551
WriteFPU()552 int RegisterContextDarwin_x86_64::WriteFPU() {
553 int set = FPURegSet;
554 if (!RegisterSetIsCached(set)) {
555 SetError(set, Write, -1);
556 return -1;
557 }
558 SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));
559 SetError(set, Read, -1);
560 return GetError(set, Write);
561 }
562
WriteEXC()563 int RegisterContextDarwin_x86_64::WriteEXC() {
564 int set = EXCRegSet;
565 if (!RegisterSetIsCached(set)) {
566 SetError(set, Write, -1);
567 return -1;
568 }
569 SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));
570 SetError(set, Read, -1);
571 return GetError(set, Write);
572 }
573
ReadRegisterSet(uint32_t set,bool force)574 int RegisterContextDarwin_x86_64::ReadRegisterSet(uint32_t set, bool force) {
575 switch (set) {
576 case GPRRegSet:
577 return ReadGPR(force);
578 case FPURegSet:
579 return ReadFPU(force);
580 case EXCRegSet:
581 return ReadEXC(force);
582 default:
583 break;
584 }
585 return -1;
586 }
587
WriteRegisterSet(uint32_t set)588 int RegisterContextDarwin_x86_64::WriteRegisterSet(uint32_t set) {
589 // Make sure we have a valid context to set.
590 switch (set) {
591 case GPRRegSet:
592 return WriteGPR();
593 case FPURegSet:
594 return WriteFPU();
595 case EXCRegSet:
596 return WriteEXC();
597 default:
598 break;
599 }
600 return -1;
601 }
602
ReadRegister(const RegisterInfo * reg_info,RegisterValue & value)603 bool RegisterContextDarwin_x86_64::ReadRegister(const RegisterInfo *reg_info,
604 RegisterValue &value) {
605 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
606 int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
607 if (set == -1)
608 return false;
609
610 if (ReadRegisterSet(set, false) != 0)
611 return false;
612
613 switch (reg) {
614 case gpr_rax:
615 case gpr_rbx:
616 case gpr_rcx:
617 case gpr_rdx:
618 case gpr_rdi:
619 case gpr_rsi:
620 case gpr_rbp:
621 case gpr_rsp:
622 case gpr_r8:
623 case gpr_r9:
624 case gpr_r10:
625 case gpr_r11:
626 case gpr_r12:
627 case gpr_r13:
628 case gpr_r14:
629 case gpr_r15:
630 case gpr_rip:
631 case gpr_rflags:
632 case gpr_cs:
633 case gpr_fs:
634 case gpr_gs:
635 value = (&gpr.rax)[reg - gpr_rax];
636 break;
637
638 case fpu_fcw:
639 value = fpu.fcw;
640 break;
641
642 case fpu_fsw:
643 value = fpu.fsw;
644 break;
645
646 case fpu_ftw:
647 value = fpu.ftw;
648 break;
649
650 case fpu_fop:
651 value = fpu.fop;
652 break;
653
654 case fpu_ip:
655 value = fpu.ip;
656 break;
657
658 case fpu_cs:
659 value = fpu.cs;
660 break;
661
662 case fpu_dp:
663 value = fpu.dp;
664 break;
665
666 case fpu_ds:
667 value = fpu.ds;
668 break;
669
670 case fpu_mxcsr:
671 value = fpu.mxcsr;
672 break;
673
674 case fpu_mxcsrmask:
675 value = fpu.mxcsrmask;
676 break;
677
678 case fpu_stmm0:
679 case fpu_stmm1:
680 case fpu_stmm2:
681 case fpu_stmm3:
682 case fpu_stmm4:
683 case fpu_stmm5:
684 case fpu_stmm6:
685 case fpu_stmm7:
686 value.SetBytes(fpu.stmm[reg - fpu_stmm0].bytes, reg_info->byte_size,
687 endian::InlHostByteOrder());
688 break;
689
690 case fpu_xmm0:
691 case fpu_xmm1:
692 case fpu_xmm2:
693 case fpu_xmm3:
694 case fpu_xmm4:
695 case fpu_xmm5:
696 case fpu_xmm6:
697 case fpu_xmm7:
698 case fpu_xmm8:
699 case fpu_xmm9:
700 case fpu_xmm10:
701 case fpu_xmm11:
702 case fpu_xmm12:
703 case fpu_xmm13:
704 case fpu_xmm14:
705 case fpu_xmm15:
706 value.SetBytes(fpu.xmm[reg - fpu_xmm0].bytes, reg_info->byte_size,
707 endian::InlHostByteOrder());
708 break;
709
710 case exc_trapno:
711 value = exc.trapno;
712 break;
713
714 case exc_err:
715 value = exc.err;
716 break;
717
718 case exc_faultvaddr:
719 value = exc.faultvaddr;
720 break;
721
722 default:
723 return false;
724 }
725 return true;
726 }
727
WriteRegister(const RegisterInfo * reg_info,const RegisterValue & value)728 bool RegisterContextDarwin_x86_64::WriteRegister(const RegisterInfo *reg_info,
729 const RegisterValue &value) {
730 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
731 int set = RegisterContextDarwin_x86_64::GetSetForNativeRegNum(reg);
732
733 if (set == -1)
734 return false;
735
736 if (ReadRegisterSet(set, false) != 0)
737 return false;
738
739 switch (reg) {
740 case gpr_rax:
741 case gpr_rbx:
742 case gpr_rcx:
743 case gpr_rdx:
744 case gpr_rdi:
745 case gpr_rsi:
746 case gpr_rbp:
747 case gpr_rsp:
748 case gpr_r8:
749 case gpr_r9:
750 case gpr_r10:
751 case gpr_r11:
752 case gpr_r12:
753 case gpr_r13:
754 case gpr_r14:
755 case gpr_r15:
756 case gpr_rip:
757 case gpr_rflags:
758 case gpr_cs:
759 case gpr_fs:
760 case gpr_gs:
761 (&gpr.rax)[reg - gpr_rax] = value.GetAsUInt64();
762 break;
763
764 case fpu_fcw:
765 fpu.fcw = value.GetAsUInt16();
766 break;
767
768 case fpu_fsw:
769 fpu.fsw = value.GetAsUInt16();
770 break;
771
772 case fpu_ftw:
773 fpu.ftw = value.GetAsUInt8();
774 break;
775
776 case fpu_fop:
777 fpu.fop = value.GetAsUInt16();
778 break;
779
780 case fpu_ip:
781 fpu.ip = value.GetAsUInt32();
782 break;
783
784 case fpu_cs:
785 fpu.cs = value.GetAsUInt16();
786 break;
787
788 case fpu_dp:
789 fpu.dp = value.GetAsUInt32();
790 break;
791
792 case fpu_ds:
793 fpu.ds = value.GetAsUInt16();
794 break;
795
796 case fpu_mxcsr:
797 fpu.mxcsr = value.GetAsUInt32();
798 break;
799
800 case fpu_mxcsrmask:
801 fpu.mxcsrmask = value.GetAsUInt32();
802 break;
803
804 case fpu_stmm0:
805 case fpu_stmm1:
806 case fpu_stmm2:
807 case fpu_stmm3:
808 case fpu_stmm4:
809 case fpu_stmm5:
810 case fpu_stmm6:
811 case fpu_stmm7:
812 ::memcpy(fpu.stmm[reg - fpu_stmm0].bytes, value.GetBytes(),
813 value.GetByteSize());
814 break;
815
816 case fpu_xmm0:
817 case fpu_xmm1:
818 case fpu_xmm2:
819 case fpu_xmm3:
820 case fpu_xmm4:
821 case fpu_xmm5:
822 case fpu_xmm6:
823 case fpu_xmm7:
824 case fpu_xmm8:
825 case fpu_xmm9:
826 case fpu_xmm10:
827 case fpu_xmm11:
828 case fpu_xmm12:
829 case fpu_xmm13:
830 case fpu_xmm14:
831 case fpu_xmm15:
832 ::memcpy(fpu.xmm[reg - fpu_xmm0].bytes, value.GetBytes(),
833 value.GetByteSize());
834 return false;
835
836 case exc_trapno:
837 exc.trapno = value.GetAsUInt32();
838 break;
839
840 case exc_err:
841 exc.err = value.GetAsUInt32();
842 break;
843
844 case exc_faultvaddr:
845 exc.faultvaddr = value.GetAsUInt64();
846 break;
847
848 default:
849 return false;
850 }
851 return WriteRegisterSet(set) == 0;
852 }
853
ReadAllRegisterValues(lldb::WritableDataBufferSP & data_sp)854 bool RegisterContextDarwin_x86_64::ReadAllRegisterValues(
855 lldb::WritableDataBufferSP &data_sp) {
856 data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);
857 if (ReadGPR(false) == 0 && ReadFPU(false) == 0 && ReadEXC(false) == 0) {
858 uint8_t *dst = data_sp->GetBytes();
859 ::memcpy(dst, &gpr, sizeof(gpr));
860 dst += sizeof(gpr);
861
862 ::memcpy(dst, &fpu, sizeof(fpu));
863 dst += sizeof(gpr);
864
865 ::memcpy(dst, &exc, sizeof(exc));
866 return true;
867 }
868 return false;
869 }
870
WriteAllRegisterValues(const lldb::DataBufferSP & data_sp)871 bool RegisterContextDarwin_x86_64::WriteAllRegisterValues(
872 const lldb::DataBufferSP &data_sp) {
873 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {
874 const uint8_t *src = data_sp->GetBytes();
875 ::memcpy(&gpr, src, sizeof(gpr));
876 src += sizeof(gpr);
877
878 ::memcpy(&fpu, src, sizeof(fpu));
879 src += sizeof(gpr);
880
881 ::memcpy(&exc, src, sizeof(exc));
882 uint32_t success_count = 0;
883 if (WriteGPR() == 0)
884 ++success_count;
885 if (WriteFPU() == 0)
886 ++success_count;
887 if (WriteEXC() == 0)
888 ++success_count;
889 return success_count == 3;
890 }
891 return false;
892 }
893
ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,uint32_t reg)894 uint32_t RegisterContextDarwin_x86_64::ConvertRegisterKindToRegisterNumber(
895 lldb::RegisterKind kind, uint32_t reg) {
896 if (kind == eRegisterKindGeneric) {
897 switch (reg) {
898 case LLDB_REGNUM_GENERIC_PC:
899 return gpr_rip;
900 case LLDB_REGNUM_GENERIC_SP:
901 return gpr_rsp;
902 case LLDB_REGNUM_GENERIC_FP:
903 return gpr_rbp;
904 case LLDB_REGNUM_GENERIC_FLAGS:
905 return gpr_rflags;
906 case LLDB_REGNUM_GENERIC_RA:
907 default:
908 break;
909 }
910 } else if (kind == eRegisterKindEHFrame || kind == eRegisterKindDWARF) {
911 switch (reg) {
912 case ehframe_dwarf_gpr_rax:
913 return gpr_rax;
914 case ehframe_dwarf_gpr_rdx:
915 return gpr_rdx;
916 case ehframe_dwarf_gpr_rcx:
917 return gpr_rcx;
918 case ehframe_dwarf_gpr_rbx:
919 return gpr_rbx;
920 case ehframe_dwarf_gpr_rsi:
921 return gpr_rsi;
922 case ehframe_dwarf_gpr_rdi:
923 return gpr_rdi;
924 case ehframe_dwarf_gpr_rbp:
925 return gpr_rbp;
926 case ehframe_dwarf_gpr_rsp:
927 return gpr_rsp;
928 case ehframe_dwarf_gpr_r8:
929 return gpr_r8;
930 case ehframe_dwarf_gpr_r9:
931 return gpr_r9;
932 case ehframe_dwarf_gpr_r10:
933 return gpr_r10;
934 case ehframe_dwarf_gpr_r11:
935 return gpr_r11;
936 case ehframe_dwarf_gpr_r12:
937 return gpr_r12;
938 case ehframe_dwarf_gpr_r13:
939 return gpr_r13;
940 case ehframe_dwarf_gpr_r14:
941 return gpr_r14;
942 case ehframe_dwarf_gpr_r15:
943 return gpr_r15;
944 case ehframe_dwarf_gpr_rip:
945 return gpr_rip;
946 case ehframe_dwarf_fpu_xmm0:
947 return fpu_xmm0;
948 case ehframe_dwarf_fpu_xmm1:
949 return fpu_xmm1;
950 case ehframe_dwarf_fpu_xmm2:
951 return fpu_xmm2;
952 case ehframe_dwarf_fpu_xmm3:
953 return fpu_xmm3;
954 case ehframe_dwarf_fpu_xmm4:
955 return fpu_xmm4;
956 case ehframe_dwarf_fpu_xmm5:
957 return fpu_xmm5;
958 case ehframe_dwarf_fpu_xmm6:
959 return fpu_xmm6;
960 case ehframe_dwarf_fpu_xmm7:
961 return fpu_xmm7;
962 case ehframe_dwarf_fpu_xmm8:
963 return fpu_xmm8;
964 case ehframe_dwarf_fpu_xmm9:
965 return fpu_xmm9;
966 case ehframe_dwarf_fpu_xmm10:
967 return fpu_xmm10;
968 case ehframe_dwarf_fpu_xmm11:
969 return fpu_xmm11;
970 case ehframe_dwarf_fpu_xmm12:
971 return fpu_xmm12;
972 case ehframe_dwarf_fpu_xmm13:
973 return fpu_xmm13;
974 case ehframe_dwarf_fpu_xmm14:
975 return fpu_xmm14;
976 case ehframe_dwarf_fpu_xmm15:
977 return fpu_xmm15;
978 case ehframe_dwarf_fpu_stmm0:
979 return fpu_stmm0;
980 case ehframe_dwarf_fpu_stmm1:
981 return fpu_stmm1;
982 case ehframe_dwarf_fpu_stmm2:
983 return fpu_stmm2;
984 case ehframe_dwarf_fpu_stmm3:
985 return fpu_stmm3;
986 case ehframe_dwarf_fpu_stmm4:
987 return fpu_stmm4;
988 case ehframe_dwarf_fpu_stmm5:
989 return fpu_stmm5;
990 case ehframe_dwarf_fpu_stmm6:
991 return fpu_stmm6;
992 case ehframe_dwarf_fpu_stmm7:
993 return fpu_stmm7;
994 default:
995 break;
996 }
997 } else if (kind == eRegisterKindLLDB) {
998 return reg;
999 }
1000 return LLDB_INVALID_REGNUM;
1001 }
1002
HardwareSingleStep(bool enable)1003 bool RegisterContextDarwin_x86_64::HardwareSingleStep(bool enable) {
1004 if (ReadGPR(true) != 0)
1005 return false;
1006
1007 const uint64_t trace_bit = 0x100ull;
1008 if (enable) {
1009
1010 if (gpr.rflags & trace_bit)
1011 return true; // trace bit is already set, there is nothing to do
1012 else
1013 gpr.rflags |= trace_bit;
1014 } else {
1015 if (gpr.rflags & trace_bit)
1016 gpr.rflags &= ~trace_bit;
1017 else
1018 return true; // trace bit is clear, there is nothing to do
1019 }
1020
1021 return WriteGPR() == 0;
1022 }
1023