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