1 //===-- RegisterContextDarwin_x86_64.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_X86_64_H 10 #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H 11 12 #include "lldb/Target/RegisterContext.h" 13 #include "lldb/lldb-private.h" 14 15 class RegisterContextDarwin_x86_64 : public lldb_private::RegisterContext { 16 public: 17 RegisterContextDarwin_x86_64(lldb_private::Thread &thread, 18 uint32_t concrete_frame_idx); 19 20 ~RegisterContextDarwin_x86_64() 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::DataBufferSP &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 uint64_t rax; 49 uint64_t rbx; 50 uint64_t rcx; 51 uint64_t rdx; 52 uint64_t rdi; 53 uint64_t rsi; 54 uint64_t rbp; 55 uint64_t rsp; 56 uint64_t r8; 57 uint64_t r9; 58 uint64_t r10; 59 uint64_t r11; 60 uint64_t r12; 61 uint64_t r13; 62 uint64_t r14; 63 uint64_t r15; 64 uint64_t rip; 65 uint64_t rflags; 66 uint64_t cs; 67 uint64_t fs; 68 uint64_t gs; 69 }; 70 71 struct MMSReg { 72 uint8_t bytes[10]; 73 uint8_t pad[6]; 74 }; 75 76 struct XMMReg { 77 uint8_t bytes[16]; 78 }; 79 80 struct FPU { 81 uint32_t pad[2]; 82 uint16_t fcw; // "fctrl" 83 uint16_t fsw; // "fstat" 84 uint8_t ftw; // "ftag" 85 uint8_t pad1; 86 uint16_t fop; // "fop" 87 uint32_t ip; // "fioff" 88 uint16_t cs; // "fiseg" 89 uint16_t pad2; 90 uint32_t dp; // "fooff" 91 uint16_t ds; // "foseg" 92 uint16_t pad3; 93 uint32_t mxcsr; 94 uint32_t mxcsrmask; 95 MMSReg stmm[8]; 96 XMMReg xmm[16]; 97 uint8_t pad4[6 * 16]; 98 int pad5; 99 }; 100 101 struct EXC { 102 uint32_t trapno; 103 uint32_t err; 104 uint64_t faultvaddr; 105 }; 106 107 protected: 108 enum { GPRRegSet = 4, FPURegSet = 5, EXCRegSet = 6 }; 109 110 enum { 111 GPRWordCount = sizeof(GPR) / sizeof(uint32_t), 112 FPUWordCount = sizeof(FPU) / sizeof(uint32_t), 113 EXCWordCount = sizeof(EXC) / sizeof(uint32_t) 114 }; 115 116 enum { Read = 0, Write = 1, kNumErrors = 2 }; 117 118 GPR gpr; 119 FPU fpu; 120 EXC exc; 121 int gpr_errs[2]; // Read/Write errors 122 int fpu_errs[2]; // Read/Write errors 123 int exc_errs[2]; // Read/Write errors 124 InvalidateAllRegisterStates()125 void InvalidateAllRegisterStates() { 126 SetError(GPRRegSet, Read, -1); 127 SetError(FPURegSet, Read, -1); 128 SetError(EXCRegSet, Read, -1); 129 } 130 GetError(int flavor,uint32_t err_idx)131 int GetError(int flavor, uint32_t err_idx) const { 132 if (err_idx < kNumErrors) { 133 switch (flavor) { 134 // When getting all errors, just OR all values together to see if 135 // we got any kind of error. 136 case GPRRegSet: 137 return gpr_errs[err_idx]; 138 case FPURegSet: 139 return fpu_errs[err_idx]; 140 case EXCRegSet: 141 return exc_errs[err_idx]; 142 default: 143 break; 144 } 145 } 146 return -1; 147 } 148 SetError(int flavor,uint32_t err_idx,int err)149 bool SetError(int flavor, uint32_t err_idx, int err) { 150 if (err_idx < kNumErrors) { 151 switch (flavor) { 152 case GPRRegSet: 153 gpr_errs[err_idx] = err; 154 return true; 155 156 case FPURegSet: 157 fpu_errs[err_idx] = err; 158 return true; 159 160 case EXCRegSet: 161 exc_errs[err_idx] = err; 162 return true; 163 164 default: 165 break; 166 } 167 } 168 return false; 169 } 170 RegisterSetIsCached(int set)171 bool RegisterSetIsCached(int set) const { return GetError(set, Read) == 0; } 172 173 void LogGPR(lldb_private::Log *log, const char *format, ...); 174 175 int ReadGPR(bool force); 176 177 int ReadFPU(bool force); 178 179 int ReadEXC(bool force); 180 181 int WriteGPR(); 182 183 int WriteFPU(); 184 185 int WriteEXC(); 186 187 // Subclasses override these to do the actual reading. 188 virtual int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) = 0; 189 190 virtual int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) = 0; 191 192 virtual int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) = 0; 193 194 virtual int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) = 0; 195 196 virtual int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) = 0; 197 198 virtual int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) = 0; 199 200 int ReadRegisterSet(uint32_t set, bool force); 201 202 int WriteRegisterSet(uint32_t set); 203 204 static uint32_t GetRegisterNumber(uint32_t reg_kind, uint32_t reg_num); 205 206 static int GetSetForNativeRegNum(int reg_num); 207 208 static size_t GetRegisterInfosCount(); 209 210 static const lldb_private::RegisterInfo *GetRegisterInfos(); 211 }; 212 213 #endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H 214