1 //===-- RegisterContext.cpp -------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // C Includes 11 // C++ Includes 12 // Other libraries and framework includes 13 // Project includes 14 #include "lldb/Target/RegisterContext.h" 15 #include "lldb/Core/Scalar.h" 16 #include "lldb/Target/ExecutionContext.h" 17 #include "lldb/Target/StackFrame.h" 18 #include "lldb/Target/Thread.h" 19 20 using namespace lldb; 21 using namespace lldb_private; 22 23 //---------------------------------------------------------------------- 24 // RegisterContext constructor 25 //---------------------------------------------------------------------- 26 RegisterContext::RegisterContext (Thread &thread, StackFrame *frame) : 27 m_thread (thread), 28 m_frame (frame) 29 { 30 } 31 32 //---------------------------------------------------------------------- 33 // Destructor 34 //---------------------------------------------------------------------- 35 RegisterContext::~RegisterContext() 36 { 37 } 38 39 const RegisterInfo * 40 RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx) 41 { 42 if (reg_name && reg_name[0]) 43 { 44 const uint32_t num_registers = GetRegisterCount(); 45 for (uint32_t reg = start_idx; reg < num_registers; ++reg) 46 { 47 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg); 48 49 if ((reg_info->name != NULL && ::strcasecmp (reg_info->name, reg_name) == 0) || 50 (reg_info->alt_name != NULL && ::strcasecmp (reg_info->alt_name, reg_name) == 0)) 51 { 52 return reg_info; 53 } 54 } 55 } 56 return NULL; 57 } 58 59 const char * 60 RegisterContext::GetRegisterName (uint32_t reg) 61 { 62 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg); 63 if (reg_info) 64 return reg_info->name; 65 return NULL; 66 } 67 68 uint64_t 69 RegisterContext::GetPC(uint64_t fail_value) 70 { 71 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 72 return ReadRegisterAsUnsigned (reg, fail_value); 73 } 74 75 bool 76 RegisterContext::SetPC(uint64_t pc) 77 { 78 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 79 bool success = WriteRegisterFromUnsigned (reg, pc); 80 if (success) 81 { 82 if (m_frame) 83 m_frame->ChangePC(pc); 84 else 85 m_thread.ClearStackFrames (); 86 } 87 return success; 88 } 89 90 uint64_t 91 RegisterContext::GetSP(uint64_t fail_value) 92 { 93 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 94 return ReadRegisterAsUnsigned (reg, fail_value); 95 } 96 97 bool 98 RegisterContext::SetSP(uint64_t sp) 99 { 100 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 101 return WriteRegisterFromUnsigned (reg, sp); 102 } 103 104 uint64_t 105 RegisterContext::GetFP(uint64_t fail_value) 106 { 107 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP); 108 return ReadRegisterAsUnsigned (reg, fail_value); 109 } 110 111 bool 112 RegisterContext::SetFP(uint64_t fp) 113 { 114 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP); 115 return WriteRegisterFromUnsigned (reg, fp); 116 } 117 118 uint64_t 119 RegisterContext::GetReturnAddress (uint64_t fail_value) 120 { 121 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); 122 return ReadRegisterAsUnsigned (reg, fail_value); 123 } 124 125 uint64_t 126 RegisterContext::GetFlags (uint64_t fail_value) 127 { 128 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); 129 return ReadRegisterAsUnsigned (reg, fail_value); 130 } 131 132 133 uint64_t 134 RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value) 135 { 136 if (reg != LLDB_INVALID_REGNUM) 137 { 138 Scalar value; 139 if (ReadRegisterValue (reg, value)) 140 return value.GetRawBits64(fail_value); 141 } 142 return fail_value; 143 } 144 145 bool 146 RegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval) 147 { 148 if (reg == LLDB_INVALID_REGNUM) 149 return false; 150 Scalar value(uval); 151 return WriteRegisterValue (reg, value); 152 } 153 154 lldb::tid_t 155 RegisterContext::GetThreadID() const 156 { 157 return m_thread.GetID(); 158 } 159 160 uint32_t 161 RegisterContext::NumSupportedHardwareBreakpoints () 162 { 163 return 0; 164 } 165 166 uint32_t 167 RegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size) 168 { 169 return LLDB_INVALID_INDEX32; 170 } 171 172 bool 173 RegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx) 174 { 175 return false; 176 } 177 178 179 uint32_t 180 RegisterContext::NumSupportedHardwareWatchpoints () 181 { 182 return 0; 183 } 184 185 uint32_t 186 RegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write) 187 { 188 return LLDB_INVALID_INDEX32; 189 } 190 191 bool 192 RegisterContext::ClearHardwareWatchpoint (uint32_t hw_index) 193 { 194 return false; 195 } 196 197 bool 198 RegisterContext::HardwareSingleStep (bool enable) 199 { 200 return false; 201 } 202 203 Target * 204 RegisterContext::CalculateTarget () 205 { 206 return m_thread.CalculateTarget(); 207 } 208 209 210 Process * 211 RegisterContext::CalculateProcess () 212 { 213 return m_thread.CalculateProcess (); 214 } 215 216 Thread * 217 RegisterContext::CalculateThread () 218 { 219 return &m_thread; 220 } 221 222 StackFrame * 223 RegisterContext::CalculateStackFrame () 224 { 225 return m_frame; 226 } 227 228 void 229 RegisterContext::Calculate (ExecutionContext &exe_ctx) 230 { 231 if (m_frame) 232 m_frame->Calculate (exe_ctx); 233 else 234 m_thread.Calculate (exe_ctx); 235 } 236 237 238 239