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/DataExtractor.h" 16 #include "lldb/Core/Scalar.h" 17 #include "lldb/Host/Endian.h" 18 #include "lldb/Target/ExecutionContext.h" 19 #include "lldb/Target/StackFrame.h" 20 #include "lldb/Target/Process.h" 21 #include "lldb/Target/Thread.h" 22 23 using namespace lldb; 24 using namespace lldb_private; 25 26 RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) : 27 m_thread (thread), 28 m_concrete_frame_idx (concrete_frame_idx), 29 m_stop_id (thread.GetProcess().GetStopID()) 30 { 31 } 32 33 //---------------------------------------------------------------------- 34 // Destructor 35 //---------------------------------------------------------------------- 36 RegisterContext::~RegisterContext() 37 { 38 } 39 40 void 41 RegisterContext::InvalidateIfNeeded (bool force) 42 { 43 const uint32_t this_stop_id = GetStopID(); 44 const uint32_t process_stop_id = m_thread.GetProcess().GetStopID(); 45 if (force || process_stop_id != this_stop_id) 46 { 47 InvalidateAllRegisters (); 48 SetStopID (process_stop_id); 49 } 50 } 51 52 53 const RegisterInfo * 54 RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx) 55 { 56 if (reg_name && reg_name[0]) 57 { 58 const uint32_t num_registers = GetRegisterCount(); 59 for (uint32_t reg = start_idx; reg < num_registers; ++reg) 60 { 61 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg); 62 63 if ((reg_info->name != NULL && ::strcasecmp (reg_info->name, reg_name) == 0) || 64 (reg_info->alt_name != NULL && ::strcasecmp (reg_info->alt_name, reg_name) == 0)) 65 { 66 return reg_info; 67 } 68 } 69 } 70 return NULL; 71 } 72 73 const char * 74 RegisterContext::GetRegisterName (uint32_t reg) 75 { 76 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg); 77 if (reg_info) 78 return reg_info->name; 79 return NULL; 80 } 81 82 uint64_t 83 RegisterContext::GetPC(uint64_t fail_value) 84 { 85 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 86 return ReadRegisterAsUnsigned (reg, fail_value); 87 } 88 89 bool 90 RegisterContext::SetPC(uint64_t pc) 91 { 92 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 93 bool success = WriteRegisterFromUnsigned (reg, pc); 94 if (success) 95 { 96 StackFrameSP frame_sp(m_thread.GetFrameWithConcreteFrameIndex (m_concrete_frame_idx)); 97 if (frame_sp) 98 frame_sp->ChangePC(pc); 99 else 100 m_thread.ClearStackFrames (); 101 } 102 return success; 103 } 104 105 uint64_t 106 RegisterContext::GetSP(uint64_t fail_value) 107 { 108 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 109 return ReadRegisterAsUnsigned (reg, fail_value); 110 } 111 112 bool 113 RegisterContext::SetSP(uint64_t sp) 114 { 115 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 116 return WriteRegisterFromUnsigned (reg, sp); 117 } 118 119 uint64_t 120 RegisterContext::GetFP(uint64_t fail_value) 121 { 122 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP); 123 return ReadRegisterAsUnsigned (reg, fail_value); 124 } 125 126 bool 127 RegisterContext::SetFP(uint64_t fp) 128 { 129 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP); 130 return WriteRegisterFromUnsigned (reg, fp); 131 } 132 133 uint64_t 134 RegisterContext::GetReturnAddress (uint64_t fail_value) 135 { 136 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); 137 return ReadRegisterAsUnsigned (reg, fail_value); 138 } 139 140 uint64_t 141 RegisterContext::GetFlags (uint64_t fail_value) 142 { 143 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); 144 return ReadRegisterAsUnsigned (reg, fail_value); 145 } 146 147 148 uint64_t 149 RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value) 150 { 151 if (reg != LLDB_INVALID_REGNUM) 152 { 153 Scalar value; 154 if (ReadRegisterValue (reg, value)) 155 return value.GetRawBits64(fail_value); 156 } 157 return fail_value; 158 } 159 160 bool 161 RegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval) 162 { 163 if (reg == LLDB_INVALID_REGNUM) 164 return false; 165 Scalar value(uval); 166 return WriteRegisterValue (reg, value); 167 } 168 169 lldb::tid_t 170 RegisterContext::GetThreadID() const 171 { 172 return m_thread.GetID(); 173 } 174 175 uint32_t 176 RegisterContext::NumSupportedHardwareBreakpoints () 177 { 178 return 0; 179 } 180 181 uint32_t 182 RegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size) 183 { 184 return LLDB_INVALID_INDEX32; 185 } 186 187 bool 188 RegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx) 189 { 190 return false; 191 } 192 193 194 uint32_t 195 RegisterContext::NumSupportedHardwareWatchpoints () 196 { 197 return 0; 198 } 199 200 uint32_t 201 RegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write) 202 { 203 return LLDB_INVALID_INDEX32; 204 } 205 206 bool 207 RegisterContext::ClearHardwareWatchpoint (uint32_t hw_index) 208 { 209 return false; 210 } 211 212 bool 213 RegisterContext::HardwareSingleStep (bool enable) 214 { 215 return false; 216 } 217 218 Target * 219 RegisterContext::CalculateTarget () 220 { 221 return m_thread.CalculateTarget(); 222 } 223 224 225 Process * 226 RegisterContext::CalculateProcess () 227 { 228 return m_thread.CalculateProcess (); 229 } 230 231 Thread * 232 RegisterContext::CalculateThread () 233 { 234 return &m_thread; 235 } 236 237 StackFrame * 238 RegisterContext::CalculateStackFrame () 239 { 240 // Register contexts might belong to many frames if we have inlined 241 // functions inside a frame since all inlined functions share the 242 // same registers, so we can't definitively say which frame we come from... 243 return NULL; 244 } 245 246 void 247 RegisterContext::CalculateExecutionContext (ExecutionContext &exe_ctx) 248 { 249 m_thread.CalculateExecutionContext (exe_ctx); 250 } 251 252 253 bool 254 RegisterContext::ConvertBetweenRegisterKinds (int source_rk, uint32_t source_regnum, int target_rk, uint32_t& target_regnum) 255 { 256 const uint32_t num_registers = GetRegisterCount(); 257 for (uint32_t reg = 0; reg < num_registers; ++reg) 258 { 259 const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg); 260 261 if (reg_info->kinds[source_rk] == source_regnum) 262 { 263 target_regnum = reg_info->kinds[target_rk]; 264 if (target_regnum == LLDB_INVALID_REGNUM) 265 { 266 return false; 267 } 268 else 269 { 270 return true; 271 } 272 } 273 } 274 return false; 275 } 276 277 bool 278 RegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value) 279 { 280 DataExtractor data; 281 if (!ReadRegisterBytes (reg, data)) 282 return false; 283 284 const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); 285 uint32_t offset = 0; 286 switch (reg_info->encoding) 287 { 288 case eEncodingInvalid: 289 case eEncodingVector: 290 break; 291 292 case eEncodingUint: 293 switch (reg_info->byte_size) 294 { 295 case 1: 296 { 297 value = data.GetU8 (&offset); 298 return true; 299 } 300 case 2: 301 { 302 value = data.GetU16 (&offset); 303 return true; 304 } 305 case 4: 306 { 307 value = data.GetU32 (&offset); 308 return true; 309 } 310 case 8: 311 { 312 value = data.GetU64 (&offset); 313 return true; 314 } 315 } 316 break; 317 case eEncodingSint: 318 switch (reg_info->byte_size) 319 { 320 case 1: 321 { 322 int8_t v; 323 if (data.ExtractBytes (0, sizeof (int8_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int8_t)) 324 return false; 325 value = v; 326 return true; 327 } 328 case 2: 329 { 330 int16_t v; 331 if (data.ExtractBytes (0, sizeof (int16_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int16_t)) 332 return false; 333 value = v; 334 return true; 335 } 336 case 4: 337 { 338 int32_t v; 339 if (data.ExtractBytes (0, sizeof (int32_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int32_t)) 340 return false; 341 value = v; 342 return true; 343 } 344 case 8: 345 { 346 int64_t v; 347 if (data.ExtractBytes (0, sizeof (int64_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int64_t)) 348 return false; 349 value = v; 350 return true; 351 } 352 } 353 break; 354 case eEncodingIEEE754: 355 switch (reg_info->byte_size) 356 { 357 case sizeof (float): 358 { 359 float v; 360 if (data.ExtractBytes (0, sizeof (float), lldb::endian::InlHostByteOrder(), &v) != sizeof (float)) 361 return false; 362 value = v; 363 return true; 364 } 365 case sizeof (double): 366 { 367 double v; 368 if (data.ExtractBytes (0, sizeof (double), lldb::endian::InlHostByteOrder(), &v) != sizeof (double)) 369 return false; 370 value = v; 371 return true; 372 } 373 case sizeof (long double): 374 { 375 double v; 376 if (data.ExtractBytes (0, sizeof (long double), lldb::endian::InlHostByteOrder(), &v) != sizeof (long double)) 377 return false; 378 value = v; 379 return true; 380 } 381 } 382 break; 383 } 384 return false; 385 } 386 387 bool 388 RegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value) 389 { 390 DataExtractor data; 391 if (!value.IsValid()) 392 return false; 393 if (!value.GetData (data)) 394 return false; 395 396 return WriteRegisterBytes (reg, data); 397 } 398