253 lines · c
1//===-- DNBArchImplX86_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// Created by Greg Clayton on 6/25/07.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_DNBARCHIMPLX86_64_H14#define LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_DNBARCHIMPLX86_64_H15 16#if defined(__i386__) || defined(__x86_64__)17#include "DNBArch.h"18#include "MachRegisterStatesX86_64.h"19 20#include <map>21 22class MachThread;23 24class DNBArchImplX86_64 : public DNBArchProtocol {25public:26 DNBArchImplX86_64(MachThread *thread)27 : DNBArchProtocol(), m_thread(thread), m_state(), m_2pc_dbg_checkpoint(),28 m_2pc_trans_state(Trans_Done), m_saved_register_states() {}29 virtual ~DNBArchImplX86_64() {}30 31 static void Initialize();32 33 bool GetRegisterValue(uint32_t set, uint32_t reg,34 DNBRegisterValue *value) override;35 bool SetRegisterValue(uint32_t set, uint32_t reg,36 const DNBRegisterValue *value) override;37 nub_size_t GetRegisterContext(void *buf, nub_size_t buf_len) override;38 nub_size_t SetRegisterContext(const void *buf, nub_size_t buf_len) override;39 uint32_t SaveRegisterState() override;40 bool RestoreRegisterState(uint32_t save_id) override;41 42 kern_return_t GetRegisterState(int set, bool force) override;43 kern_return_t SetRegisterState(int set) override;44 bool RegisterSetStateIsValid(int set) const override;45 46 uint64_t GetPC(uint64_t failValue) override; // Get program counter47 kern_return_t SetPC(uint64_t value) override;48 uint64_t GetSP(uint64_t failValue) override; // Get stack pointer49 void ThreadWillResume() override;50 bool ThreadDidStop() override;51 bool NotifyException(MachException::Data &exc) override;52 53 uint32_t NumSupportedHardwareBreakpoints() override;54 uint32_t NumSupportedHardwareWatchpoints() override;55 56 uint32_t EnableHardwareBreakpoint(nub_addr_t addr, nub_size_t size,57 bool also_set_on_task) override;58 bool DisableHardwareBreakpoint(uint32_t hw_break_index,59 bool also_set_on_task) override;60 uint32_t EnableHardwareWatchpoint(nub_addr_t addr, nub_size_t size,61 bool read, bool write,62 bool also_set_on_task) override;63 bool DisableHardwareWatchpoint(uint32_t hw_break_index,64 bool also_set_on_task) override;65 uint32_t GetHardwareWatchpointHit(nub_addr_t &addr) override;66 67protected:68 kern_return_t EnableHardwareSingleStep(bool enable);69 70 typedef __x86_64_thread_state_t GPR;71 typedef __x86_64_float_state_t FPU;72 typedef __x86_64_exception_state_t EXC;73 typedef __x86_64_avx_state_t AVX;74 typedef __x86_64_debug_state_t DBG;75 76 static const DNBRegisterInfo g_gpr_registers[];77 static const DNBRegisterInfo g_fpu_registers_no_avx[];78 static const DNBRegisterInfo g_fpu_registers_avx[];79 static const DNBRegisterInfo g_exc_registers[];80 static const DNBRegisterSetInfo g_reg_sets_no_avx[];81 static const DNBRegisterSetInfo g_reg_sets_avx[];82 static const size_t k_num_gpr_registers;83 static const size_t k_num_fpu_registers_no_avx;84 static const size_t k_num_fpu_registers_avx;85 static const size_t k_num_exc_registers;86 static const size_t k_num_all_registers_no_avx;87 static const size_t k_num_all_registers_avx;88 static const size_t k_num_register_sets;89 90 typedef __x86_64_avx512f_state_t AVX512F;91 static const DNBRegisterInfo g_fpu_registers_avx512f[];92 static const DNBRegisterSetInfo g_reg_sets_avx512f[];93 static const size_t k_num_fpu_registers_avx512f;94 static const size_t k_num_all_registers_avx512f;95 96 enum RegisterSet {97 e_regSetALL = REGISTER_SET_ALL,98 e_regSetGPR,99 e_regSetFPU,100 e_regSetEXC,101 e_regSetDBG,102 kNumRegisterSets103 };104 105 enum RegisterSetWordSize {106 e_regSetWordSizeGPR = (sizeof(GPR) - 32) / sizeof(int),107 e_regSetWordSizeGPRFull = sizeof(GPR) / sizeof(int),108 e_regSetWordSizeFPU = sizeof(FPU) / sizeof(int),109 e_regSetWordSizeEXC = sizeof(EXC) / sizeof(int),110 e_regSetWordSizeAVX = sizeof(AVX) / sizeof(int),111 e_regSetWordSizeAVX512f = sizeof(AVX512F) / sizeof(int),112 e_regSetWordSizeDBG = sizeof(DBG) / sizeof(int)113 };114 115 enum { Read = 0, Write = 1, kNumErrors = 2 };116 117 struct Context {118 GPR gpr;119 union {120 FPU no_avx;121 AVX avx;122 AVX512F avx512f;123 } fpu;124 EXC exc;125 DBG dbg;126 };127 128 struct State {129 Context context;130 kern_return_t gpr_errs[2]; // Read/Write errors131 kern_return_t fpu_errs[2]; // Read/Write errors132 kern_return_t exc_errs[2]; // Read/Write errors133 kern_return_t dbg_errs[2]; // Read/Write errors134 bool hasFullGPRState;135 136 State() {137 uint32_t i;138 for (i = 0; i < kNumErrors; i++) {139 gpr_errs[i] = -1;140 fpu_errs[i] = -1;141 exc_errs[i] = -1;142 dbg_errs[i] = -1;143 }144 }145 146 void InvalidateAllRegisterStates() { SetError(e_regSetALL, Read, -1); }147 148 kern_return_t GetError(int flavor, uint32_t err_idx) const {149 if (err_idx < kNumErrors) {150 switch (flavor) {151 // When getting all errors, just OR all values together to see if152 // we got any kind of error.153 case e_regSetALL:154 return gpr_errs[err_idx] | fpu_errs[err_idx] | exc_errs[err_idx];155 case e_regSetGPR:156 return gpr_errs[err_idx];157 case e_regSetFPU:158 return fpu_errs[err_idx];159 case e_regSetEXC:160 return exc_errs[err_idx];161 case e_regSetDBG:162 return dbg_errs[err_idx];163 default:164 break;165 }166 }167 return -1;168 }169 170 bool SetError(int flavor, uint32_t err_idx, kern_return_t err) {171 if (err_idx < kNumErrors) {172 switch (flavor) {173 case e_regSetALL:174 gpr_errs[err_idx] = fpu_errs[err_idx] = exc_errs[err_idx] =175 dbg_errs[err_idx] = err;176 return true;177 178 case e_regSetGPR:179 gpr_errs[err_idx] = err;180 return true;181 182 case e_regSetFPU:183 fpu_errs[err_idx] = err;184 return true;185 186 case e_regSetEXC:187 exc_errs[err_idx] = err;188 return true;189 190 case e_regSetDBG:191 dbg_errs[err_idx] = err;192 return true;193 194 default:195 break;196 }197 }198 return false;199 }200 201 bool RegsAreValid(int flavor) const {202 return GetError(flavor, Read) == KERN_SUCCESS;203 }204 };205 206 kern_return_t GetGPRState(bool force);207 kern_return_t GetFPUState(bool force);208 kern_return_t GetEXCState(bool force);209 kern_return_t GetDBGState(bool force);210 211 kern_return_t SetGPRState();212 kern_return_t SetFPUState();213 kern_return_t SetEXCState();214 kern_return_t SetDBGState(bool also_set_on_task);215 216 static DNBArchProtocol *Create(MachThread *thread);217 218 static const uint8_t *SoftwareBreakpointOpcode(nub_size_t byte_size);219 220 static const DNBRegisterSetInfo *GetRegisterSetInfo(nub_size_t *num_reg_sets);221 222 static uint32_t GetRegisterContextSize();223 224 static void SetHardwareBreakpoint(DBG &debug_state, uint32_t hw_index,225 nub_addr_t addr, nub_size_t size);226 227 // Helper functions for watchpoint manipulations.228 static void SetWatchpoint(DBG &debug_state, uint32_t hw_index,229 nub_addr_t addr, nub_size_t size, bool read,230 bool write);231 static void ClearWatchpoint(DBG &debug_state, uint32_t hw_index);232 static bool IsWatchpointVacant(const DBG &debug_state, uint32_t hw_index);233 static void ClearWatchpointHits(DBG &debug_state);234 static bool IsWatchpointHit(const DBG &debug_state, uint32_t hw_index);235 static nub_addr_t GetWatchAddress(const DBG &debug_state, uint32_t hw_index);236 237 bool StartTransForHWP() override;238 bool RollbackTransForHWP() override;239 bool FinishTransForHWP() override;240 DBG GetDBGCheckpoint();241 242 MachThread *m_thread;243 State m_state;244 DBG m_2pc_dbg_checkpoint;245 uint32_t m_2pc_trans_state; // Is transaction of DBG state change: Pedning246 // (0), Done (1), or Rolled Back (2)?247 typedef std::map<uint32_t, Context> SaveRegisterStates;248 SaveRegisterStates m_saved_register_states;249};250 251#endif // #if defined (__i386__) || defined (__x86_64__)252#endif // LLDB_TOOLS_DEBUGSERVER_SOURCE_MACOSX_X86_64_DNBARCHIMPLX86_64_H253