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/RegisterValue.h" 17 #include "lldb/Core/Scalar.h" 18 #include "lldb/Host/Endian.h" 19 #include "lldb/Target/ExecutionContext.h" 20 #include "lldb/Target/StackFrame.h" 21 #include "lldb/Target/Process.h" 22 #include "lldb/Target/Thread.h" 23 24 using namespace lldb; 25 using namespace lldb_private; 26 27 RegisterContext::RegisterContext (Thread &thread, uint32_t concrete_frame_idx) : 28 m_thread (thread), 29 m_concrete_frame_idx (concrete_frame_idx), 30 m_stop_id (thread.GetProcess().GetStopID()) 31 { 32 } 33 34 //---------------------------------------------------------------------- 35 // Destructor 36 //---------------------------------------------------------------------- 37 RegisterContext::~RegisterContext() 38 { 39 } 40 41 void 42 RegisterContext::InvalidateIfNeeded (bool force) 43 { 44 const uint32_t this_stop_id = GetStopID(); 45 const uint32_t process_stop_id = m_thread.GetProcess().GetStopID(); 46 if (force || process_stop_id != this_stop_id) 47 { 48 InvalidateAllRegisters (); 49 SetStopID (process_stop_id); 50 } 51 } 52 53 54 const RegisterInfo * 55 RegisterContext::GetRegisterInfoByName (const char *reg_name, uint32_t start_idx) 56 { 57 if (reg_name && reg_name[0]) 58 { 59 const uint32_t num_registers = GetRegisterCount(); 60 for (uint32_t reg = start_idx; reg < num_registers; ++reg) 61 { 62 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg); 63 64 if ((reg_info->name != NULL && ::strcasecmp (reg_info->name, reg_name) == 0) || 65 (reg_info->alt_name != NULL && ::strcasecmp (reg_info->alt_name, reg_name) == 0)) 66 { 67 return reg_info; 68 } 69 } 70 } 71 return NULL; 72 } 73 74 const char * 75 RegisterContext::GetRegisterName (uint32_t reg) 76 { 77 const RegisterInfo * reg_info = GetRegisterInfoAtIndex(reg); 78 if (reg_info) 79 return reg_info->name; 80 return NULL; 81 } 82 83 uint64_t 84 RegisterContext::GetPC(uint64_t fail_value) 85 { 86 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 87 return ReadRegisterAsUnsigned (reg, fail_value); 88 } 89 90 bool 91 RegisterContext::SetPC(uint64_t pc) 92 { 93 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC); 94 bool success = WriteRegisterFromUnsigned (reg, pc); 95 if (success) 96 { 97 StackFrameSP frame_sp(m_thread.GetFrameWithConcreteFrameIndex (m_concrete_frame_idx)); 98 if (frame_sp) 99 frame_sp->ChangePC(pc); 100 else 101 m_thread.ClearStackFrames (); 102 } 103 return success; 104 } 105 106 uint64_t 107 RegisterContext::GetSP(uint64_t fail_value) 108 { 109 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 110 return ReadRegisterAsUnsigned (reg, fail_value); 111 } 112 113 bool 114 RegisterContext::SetSP(uint64_t sp) 115 { 116 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_SP); 117 return WriteRegisterFromUnsigned (reg, sp); 118 } 119 120 uint64_t 121 RegisterContext::GetFP(uint64_t fail_value) 122 { 123 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP); 124 return ReadRegisterAsUnsigned (reg, fail_value); 125 } 126 127 bool 128 RegisterContext::SetFP(uint64_t fp) 129 { 130 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FP); 131 return WriteRegisterFromUnsigned (reg, fp); 132 } 133 134 uint64_t 135 RegisterContext::GetReturnAddress (uint64_t fail_value) 136 { 137 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_RA); 138 return ReadRegisterAsUnsigned (reg, fail_value); 139 } 140 141 uint64_t 142 RegisterContext::GetFlags (uint64_t fail_value) 143 { 144 uint32_t reg = ConvertRegisterKindToRegisterNumber (eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS); 145 return ReadRegisterAsUnsigned (reg, fail_value); 146 } 147 148 149 uint64_t 150 RegisterContext::ReadRegisterAsUnsigned (uint32_t reg, uint64_t fail_value) 151 { 152 if (reg != LLDB_INVALID_REGNUM) 153 return ReadRegisterAsUnsigned (GetRegisterInfoAtIndex (reg), fail_value); 154 return fail_value; 155 } 156 157 uint64_t 158 RegisterContext::ReadRegisterAsUnsigned (const RegisterInfo *reg_info, uint64_t fail_value) 159 { 160 if (reg_info) 161 { 162 RegisterValue value; 163 if (ReadRegister (reg_info, value)) 164 return value.GetAsUInt64(); 165 } 166 return fail_value; 167 } 168 169 bool 170 RegisterContext::WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval) 171 { 172 if (reg == LLDB_INVALID_REGNUM) 173 return false; 174 return WriteRegisterFromUnsigned (GetRegisterInfoAtIndex (reg), uval); 175 } 176 177 bool 178 RegisterContext::WriteRegisterFromUnsigned (const RegisterInfo *reg_info, uint64_t uval) 179 { 180 if (reg_info) 181 { 182 RegisterValue value; 183 if (value.SetUInt(uval, reg_info->byte_size)) 184 return WriteRegister (reg_info, value); 185 } 186 return false; 187 } 188 189 lldb::tid_t 190 RegisterContext::GetThreadID() const 191 { 192 return m_thread.GetID(); 193 } 194 195 uint32_t 196 RegisterContext::NumSupportedHardwareBreakpoints () 197 { 198 return 0; 199 } 200 201 uint32_t 202 RegisterContext::SetHardwareBreakpoint (lldb::addr_t addr, size_t size) 203 { 204 return LLDB_INVALID_INDEX32; 205 } 206 207 bool 208 RegisterContext::ClearHardwareBreakpoint (uint32_t hw_idx) 209 { 210 return false; 211 } 212 213 214 uint32_t 215 RegisterContext::NumSupportedHardwareWatchpoints () 216 { 217 return 0; 218 } 219 220 uint32_t 221 RegisterContext::SetHardwareWatchpoint (lldb::addr_t addr, size_t size, bool read, bool write) 222 { 223 return LLDB_INVALID_INDEX32; 224 } 225 226 bool 227 RegisterContext::ClearHardwareWatchpoint (uint32_t hw_index) 228 { 229 return false; 230 } 231 232 bool 233 RegisterContext::HardwareSingleStep (bool enable) 234 { 235 return false; 236 } 237 238 Error 239 RegisterContext::ReadRegisterValueFromMemory (const RegisterInfo *reg_info, 240 lldb::addr_t src_addr, 241 uint32_t src_len, 242 RegisterValue ®_value) 243 { 244 Error error; 245 if (reg_info == NULL) 246 { 247 error.SetErrorString ("invalid register info argument."); 248 return error; 249 } 250 251 252 // Moving from addr into a register 253 // 254 // Case 1: src_len == dst_len 255 // 256 // |AABBCCDD| Address contents 257 // |AABBCCDD| Register contents 258 // 259 // Case 2: src_len > dst_len 260 // 261 // Error! (The register should always be big enough to hold the data) 262 // 263 // Case 3: src_len < dst_len 264 // 265 // |AABB| Address contents 266 // |AABB0000| Register contents [on little-endian hardware] 267 // |0000AABB| Register contents [on big-endian hardware] 268 if (src_len > RegisterValue::kMaxRegisterByteSize) 269 { 270 error.SetErrorString ("register too small to receive memory data"); 271 return error; 272 } 273 274 const uint32_t dst_len = reg_info->byte_size; 275 276 if (src_len > dst_len) 277 { 278 error.SetErrorStringWithFormat("%u bytes is too big to store in register %s (%u bytes)", src_len, reg_info->name, dst_len); 279 return error; 280 } 281 282 Process &process = m_thread.GetProcess(); 283 uint8_t src[RegisterValue::kMaxRegisterByteSize]; 284 285 // Read the memory 286 const uint32_t bytes_read = process.ReadMemory (src_addr, src, src_len, error); 287 288 // Make sure the memory read succeeded... 289 if (bytes_read != src_len) 290 { 291 if (error.Success()) 292 { 293 // This might happen if we read _some_ bytes but not all 294 error.SetErrorStringWithFormat("read %u of %u bytes", bytes_read, src_len); 295 } 296 return error; 297 } 298 299 // We now have a memory buffer that contains the part or all of the register 300 // value. Set the register value using this memory data. 301 // TODO: we might need to add a parameter to this function in case the byte 302 // order of the memory data doesn't match the process. For now we are assuming 303 // they are the same. 304 reg_value.SetFromMemoryData (reg_info, 305 src, 306 src_len, 307 process.GetByteOrder(), 308 error); 309 return error; 310 } 311 312 Error 313 RegisterContext::WriteRegisterValueToMemory (const RegisterInfo *reg_info, 314 lldb::addr_t dst_addr, 315 uint32_t dst_len, 316 const RegisterValue ®_value) 317 { 318 319 uint8_t dst[RegisterValue::kMaxRegisterByteSize]; 320 321 Error error; 322 323 Process &process = m_thread.GetProcess(); 324 325 // TODO: we might need to add a parameter to this function in case the byte 326 // order of the memory data doesn't match the process. For now we are assuming 327 // they are the same. 328 329 const uint32_t bytes_copied = reg_value.GetAsMemoryData (reg_info, 330 dst, 331 dst_len, 332 process.GetByteOrder(), 333 error); 334 335 if (error.Success()) 336 { 337 if (bytes_copied == 0) 338 { 339 error.SetErrorString("byte copy failed."); 340 } 341 else 342 { 343 const uint32_t bytes_written = process.WriteMemory (dst_addr, dst, bytes_copied, error); 344 if (bytes_written != bytes_copied) 345 { 346 if (error.Success()) 347 { 348 // This might happen if we read _some_ bytes but not all 349 error.SetErrorStringWithFormat("only wrote %u of %u bytes", bytes_written, bytes_copied); 350 } 351 } 352 } 353 } 354 355 return error; 356 357 } 358 359 Target * 360 RegisterContext::CalculateTarget () 361 { 362 return m_thread.CalculateTarget(); 363 } 364 365 366 Process * 367 RegisterContext::CalculateProcess () 368 { 369 return m_thread.CalculateProcess (); 370 } 371 372 Thread * 373 RegisterContext::CalculateThread () 374 { 375 return &m_thread; 376 } 377 378 StackFrame * 379 RegisterContext::CalculateStackFrame () 380 { 381 // Register contexts might belong to many frames if we have inlined 382 // functions inside a frame since all inlined functions share the 383 // same registers, so we can't definitively say which frame we come from... 384 return NULL; 385 } 386 387 void 388 RegisterContext::CalculateExecutionContext (ExecutionContext &exe_ctx) 389 { 390 m_thread.CalculateExecutionContext (exe_ctx); 391 } 392 393 394 bool 395 RegisterContext::ConvertBetweenRegisterKinds (int source_rk, uint32_t source_regnum, int target_rk, uint32_t& target_regnum) 396 { 397 const uint32_t num_registers = GetRegisterCount(); 398 for (uint32_t reg = 0; reg < num_registers; ++reg) 399 { 400 const RegisterInfo * reg_info = GetRegisterInfoAtIndex (reg); 401 402 if (reg_info->kinds[source_rk] == source_regnum) 403 { 404 target_regnum = reg_info->kinds[target_rk]; 405 if (target_regnum == LLDB_INVALID_REGNUM) 406 { 407 return false; 408 } 409 else 410 { 411 return true; 412 } 413 } 414 } 415 return false; 416 } 417 418 //bool 419 //RegisterContext::ReadRegisterValue (uint32_t reg, Scalar &value) 420 //{ 421 // DataExtractor data; 422 // if (!ReadRegisterBytes (reg, data)) 423 // return false; 424 // 425 // const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); 426 // uint32_t offset = 0; 427 // switch (reg_info->encoding) 428 // { 429 // case eEncodingInvalid: 430 // case eEncodingVector: 431 // break; 432 // 433 // case eEncodingUint: 434 // switch (reg_info->byte_size) 435 // { 436 // case 1: 437 // { 438 // value = data.GetU8 (&offset); 439 // return true; 440 // } 441 // case 2: 442 // { 443 // value = data.GetU16 (&offset); 444 // return true; 445 // } 446 // case 4: 447 // { 448 // value = data.GetU32 (&offset); 449 // return true; 450 // } 451 // case 8: 452 // { 453 // value = data.GetU64 (&offset); 454 // return true; 455 // } 456 // } 457 // break; 458 // case eEncodingSint: 459 // switch (reg_info->byte_size) 460 // { 461 // case 1: 462 // { 463 // int8_t v; 464 // if (data.ExtractBytes (0, sizeof (int8_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int8_t)) 465 // return false; 466 // value = v; 467 // return true; 468 // } 469 // case 2: 470 // { 471 // int16_t v; 472 // if (data.ExtractBytes (0, sizeof (int16_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int16_t)) 473 // return false; 474 // value = v; 475 // return true; 476 // } 477 // case 4: 478 // { 479 // int32_t v; 480 // if (data.ExtractBytes (0, sizeof (int32_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int32_t)) 481 // return false; 482 // value = v; 483 // return true; 484 // } 485 // case 8: 486 // { 487 // int64_t v; 488 // if (data.ExtractBytes (0, sizeof (int64_t), lldb::endian::InlHostByteOrder(), &v) != sizeof (int64_t)) 489 // return false; 490 // value = v; 491 // return true; 492 // } 493 // } 494 // break; 495 // case eEncodingIEEE754: 496 // switch (reg_info->byte_size) 497 // { 498 // case sizeof (float): 499 // { 500 // float v; 501 // if (data.ExtractBytes (0, sizeof (float), lldb::endian::InlHostByteOrder(), &v) != sizeof (float)) 502 // return false; 503 // value = v; 504 // return true; 505 // } 506 // case sizeof (double): 507 // { 508 // double v; 509 // if (data.ExtractBytes (0, sizeof (double), lldb::endian::InlHostByteOrder(), &v) != sizeof (double)) 510 // return false; 511 // value = v; 512 // return true; 513 // } 514 // case sizeof (long double): 515 // { 516 // double v; 517 // if (data.ExtractBytes (0, sizeof (long double), lldb::endian::InlHostByteOrder(), &v) != sizeof (long double)) 518 // return false; 519 // value = v; 520 // return true; 521 // } 522 // } 523 // break; 524 // } 525 // return false; 526 //} 527 // 528 //bool 529 //RegisterContext::WriteRegisterValue (uint32_t reg, const Scalar &value) 530 //{ 531 // DataExtractor data; 532 // if (!value.IsValid()) 533 // return false; 534 // if (!value.GetData (data)) 535 // return false; 536 // 537 // return WriteRegisterBytes (reg, data); 538 //} 539