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(GPRRegSet, Read, -1); 122 SetError(FPURegSet, Read, -1); 123 SetError(EXCRegSet, Read, -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(set, 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