1 //===-- DNBArchImpl.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 // Created by Greg Clayton on 6/25/07. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef __DebugNubArchMachPPC_h__ 14 #define __DebugNubArchMachPPC_h__ 15 16 #if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__) 17 18 #include "DNBArch.h" 19 20 class MachThread; 21 22 class DNBArchMachPPC : public DNBArchProtocol { 23 public: DNBArchMachPPC(MachThread * thread)24 DNBArchMachPPC(MachThread *thread) : m_thread(thread), m_state() {} 25 ~DNBArchMachPPC()26 virtual ~DNBArchMachPPC() {} 27 28 virtual const DNBRegisterSetInfo * 29 GetRegisterSetInfo(nub_size_t *num_reg_sets) const; 30 virtual bool GetRegisterValue(uint32_t set, uint32_t reg, 31 DNBRegisterValue *value) const; 32 virtual kern_return_t GetRegisterState(int set, bool force); 33 virtual kern_return_t SetRegisterState(int set); 34 virtual bool RegisterSetStateIsValid(int set) const; 35 36 virtual uint64_t GetPC(uint64_t failValue); // Get program counter 37 virtual kern_return_t SetPC(uint64_t value); 38 virtual uint64_t GetSP(uint64_t failValue); // Get stack pointer 39 virtual bool ThreadWillResume(); 40 virtual bool ThreadDidStop(); 41 42 static const uint8_t *SoftwareBreakpointOpcode(nub_size_t byte_size); 43 static uint32_t GetCPUType(); 44 45 protected: 46 kern_return_t EnableHardwareSingleStep(bool enable); 47 48 enum RegisterSet { 49 e_regSetALL = REGISTER_SET_ALL, 50 e_regSetGPR, 51 e_regSetFPR, 52 e_regSetEXC, 53 e_regSetVEC, 54 kNumRegisterSets 55 }; 56 57 typedef enum RegisterSetWordSizeTag { 58 e_regSetWordSizeGPR = PPC_THREAD_STATE_COUNT, 59 e_regSetWordSizeFPR = PPC_FLOAT_STATE_COUNT, 60 e_regSetWordSizeEXC = PPC_EXCEPTION_STATE_COUNT, 61 e_regSetWordSizeVEC = PPC_VECTOR_STATE_COUNT 62 } RegisterSetWordSize; 63 64 enum { Read = 0, Write = 1, kNumErrors = 2 }; 65 66 struct State { 67 ppc_thread_state_t gpr; 68 ppc_float_state_t fpr; 69 ppc_exception_state_t exc; 70 ppc_vector_state_t vec; 71 kern_return_t gpr_errs[2]; // Read/Write errors 72 kern_return_t fpr_errs[2]; // Read/Write errors 73 kern_return_t exc_errs[2]; // Read/Write errors 74 kern_return_t vec_errs[2]; // Read/Write errors 75 StateState76 State() { 77 uint32_t i; 78 for (i = 0; i < kNumErrors; i++) { 79 gpr_errs[i] = -1; 80 fpr_errs[i] = -1; 81 exc_errs[i] = -1; 82 vec_errs[i] = -1; 83 } 84 } InvalidateAllRegisterStatesState85 void InvalidateAllRegisterStates() { SetError(e_regSetALL, Read, -1); } GetErrorState86 kern_return_t GetError(int set, uint32_t err_idx) const { 87 if (err_idx < kNumErrors) { 88 switch (set) { 89 // When getting all errors, just OR all values together to see if 90 // we got any kind of error. 91 case e_regSetALL: 92 return gpr_errs[err_idx] | fpr_errs[err_idx] | exc_errs[err_idx] | 93 vec_errs[err_idx]; 94 case e_regSetGPR: 95 return gpr_errs[err_idx]; 96 case e_regSetFPR: 97 return fpr_errs[err_idx]; 98 case e_regSetEXC: 99 return exc_errs[err_idx]; 100 case e_regSetVEC: 101 return vec_errs[err_idx]; 102 default: 103 break; 104 } 105 } 106 return -1; 107 } SetErrorState108 bool SetError(int set, uint32_t err_idx, kern_return_t err) { 109 if (err_idx < kNumErrors) { 110 switch (set) { 111 case e_regSetALL: 112 gpr_errs[err_idx] = fpr_errs[err_idx] = exc_errs[err_idx] = 113 vec_errs[err_idx] = err; 114 return true; 115 116 case e_regSetGPR: 117 gpr_errs[err_idx] = err; 118 return true; 119 120 case e_regSetFPR: 121 fpr_errs[err_idx] = err; 122 return true; 123 124 case e_regSetEXC: 125 exc_errs[err_idx] = err; 126 return true; 127 128 case e_regSetVEC: 129 vec_errs[err_idx] = err; 130 return true; 131 132 default: 133 break; 134 } 135 } 136 return false; 137 } RegsAreValidState138 bool RegsAreValid(int set) const { 139 return GetError(set, Read) == KERN_SUCCESS; 140 } 141 }; 142 143 kern_return_t GetGPRState(bool force); 144 kern_return_t GetFPRState(bool force); 145 kern_return_t GetEXCState(bool force); 146 kern_return_t GetVECState(bool force); 147 148 kern_return_t SetGPRState(); 149 kern_return_t SetFPRState(); 150 kern_return_t SetEXCState(); 151 kern_return_t SetVECState(); 152 153 protected: 154 MachThread *m_thread; 155 State m_state; 156 }; 157 158 #endif // #if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__) 159 #endif // #ifndef __DebugNubArchMachPPC_h__ 160