214 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H10#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTDARWIN_X86_64_H11 12#include "lldb/Target/RegisterContext.h"13#include "lldb/lldb-private.h"14 15class RegisterContextDarwin_x86_64 : public lldb_private::RegisterContext {16public: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::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 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 107protected: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 errors122 int fpu_errs[2]; // Read/Write errors123 int exc_errs[2]; // Read/Write errors124 125 void InvalidateAllRegisterStates() {126 SetError(GPRRegSet, Read, -1);127 SetError(FPURegSet, Read, -1);128 SetError(EXCRegSet, Read, -1);129 }130 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 if135 // 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 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 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_H214