1 //===-- GDBRemoteRegisterContext.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 #include "GDBRemoteRegisterContext.h" 11 12 // C Includes 13 // C++ Includes 14 // Other libraries and framework includes 15 #include "lldb/Core/DataBufferHeap.h" 16 #include "lldb/Core/DataExtractor.h" 17 #include "lldb/Core/RegisterValue.h" 18 #include "lldb/Core/Scalar.h" 19 #include "lldb/Core/StreamString.h" 20 #include "lldb/Target/ExecutionContext.h" 21 #include "lldb/Target/Target.h" 22 #include "lldb/Utility/Utils.h" 23 // Project includes 24 #include "Utility/StringExtractorGDBRemote.h" 25 #include "ProcessGDBRemote.h" 26 #include "ProcessGDBRemoteLog.h" 27 #include "ThreadGDBRemote.h" 28 #include "Utility/ARM_DWARF_Registers.h" 29 #include "Utility/ARM_ehframe_Registers.h" 30 31 using namespace lldb; 32 using namespace lldb_private; 33 using namespace lldb_private::process_gdb_remote; 34 35 //---------------------------------------------------------------------- 36 // GDBRemoteRegisterContext constructor 37 //---------------------------------------------------------------------- 38 GDBRemoteRegisterContext::GDBRemoteRegisterContext 39 ( 40 ThreadGDBRemote &thread, 41 uint32_t concrete_frame_idx, 42 GDBRemoteDynamicRegisterInfo ®_info, 43 bool read_all_at_once 44 ) : 45 RegisterContext (thread, concrete_frame_idx), 46 m_reg_info (reg_info), 47 m_reg_valid (), 48 m_reg_data (), 49 m_read_all_at_once (read_all_at_once) 50 { 51 // Resize our vector of bools to contain one bool for every register. 52 // We will use these boolean values to know when a register value 53 // is valid in m_reg_data. 54 m_reg_valid.resize (reg_info.GetNumRegisters()); 55 56 // Make a heap based buffer that is big enough to store all registers 57 DataBufferSP reg_data_sp(new DataBufferHeap (reg_info.GetRegisterDataByteSize(), 0)); 58 m_reg_data.SetData (reg_data_sp); 59 m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder()); 60 } 61 62 //---------------------------------------------------------------------- 63 // Destructor 64 //---------------------------------------------------------------------- 65 GDBRemoteRegisterContext::~GDBRemoteRegisterContext() 66 { 67 } 68 69 void 70 GDBRemoteRegisterContext::InvalidateAllRegisters () 71 { 72 SetAllRegisterValid (false); 73 } 74 75 void 76 GDBRemoteRegisterContext::SetAllRegisterValid (bool b) 77 { 78 std::vector<bool>::iterator pos, end = m_reg_valid.end(); 79 for (pos = m_reg_valid.begin(); pos != end; ++pos) 80 *pos = b; 81 } 82 83 size_t 84 GDBRemoteRegisterContext::GetRegisterCount () 85 { 86 return m_reg_info.GetNumRegisters (); 87 } 88 89 const RegisterInfo * 90 GDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg) 91 { 92 RegisterInfo* reg_info = m_reg_info.GetRegisterInfoAtIndex (reg); 93 94 if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) 95 { 96 const ArchSpec &arch = m_thread.GetProcess ()->GetTarget ().GetArchitecture (); 97 uint8_t reg_size = UpdateDynamicRegisterSize (arch, reg_info); 98 reg_info->byte_size = reg_size; 99 } 100 return reg_info; 101 } 102 103 size_t 104 GDBRemoteRegisterContext::GetRegisterSetCount () 105 { 106 return m_reg_info.GetNumRegisterSets (); 107 } 108 109 110 111 const RegisterSet * 112 GDBRemoteRegisterContext::GetRegisterSet (size_t reg_set) 113 { 114 return m_reg_info.GetRegisterSet (reg_set); 115 } 116 117 118 119 bool 120 GDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) 121 { 122 ExecutionContext exe_ctx(CalculateThread()); 123 124 Process *process = exe_ctx.GetProcessPtr(); 125 Thread *thread = exe_ctx.GetThreadPtr(); 126 if (process == NULL || thread == NULL) 127 return false; 128 129 GDBRemoteCommunicationClient &gdb_comm(((ProcessGDBRemote *)process)->GetGDBRemote()); 130 131 GDBRemoteClientBase::Lock lock(gdb_comm, false); 132 if (!lock) 133 { 134 if (Log *log = ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD | GDBR_LOG_PACKETS)) 135 log->Printf("GDBRemoteRegisterContext::%s failed to get packet sequence mutex", __FUNCTION__); 136 return false; 137 } 138 139 // Read the register 140 if (ReadRegisterBytes(reg_info, m_reg_data, gdb_comm, lock)) 141 { 142 const bool partial_data_ok = false; 143 Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok)); 144 return error.Success(); 145 } 146 return false; 147 } 148 149 bool 150 GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data) 151 { 152 const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); 153 if (reg_info == NULL) 154 return false; 155 156 // Invalidate if needed 157 InvalidateIfNeeded(false); 158 159 const size_t reg_byte_size = reg_info->byte_size; 160 memcpy(const_cast<uint8_t *>(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), data.data(), 161 std::min(data.size(), reg_byte_size)); 162 bool success = data.size() >= reg_byte_size; 163 if (success) 164 { 165 SetRegisterIsValid(reg, true); 166 } 167 else if (data.size() > 0) 168 { 169 // Only set register is valid to false if we copied some bytes, else 170 // leave it as it was. 171 SetRegisterIsValid(reg, false); 172 } 173 return success; 174 } 175 176 bool 177 GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, uint64_t new_reg_val) 178 { 179 const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); 180 if (reg_info == NULL) 181 return false; 182 183 // Early in process startup, we can get a thread that has an invalid byte order 184 // because the process hasn't been completely set up yet (see the ctor where the 185 // byte order is setfrom the process). If that's the case, we can't set the 186 // value here. 187 if (m_reg_data.GetByteOrder() == eByteOrderInvalid) 188 { 189 return false; 190 } 191 192 // Invalidate if needed 193 InvalidateIfNeeded (false); 194 195 DataBufferSP buffer_sp (new DataBufferHeap (&new_reg_val, sizeof (new_reg_val))); 196 DataExtractor data (buffer_sp, endian::InlHostByteOrder(), sizeof (void*)); 197 198 // If our register context and our register info disagree, which should never happen, don't 199 // overwrite past the end of the buffer. 200 if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) 201 return false; 202 203 // Grab a pointer to where we are going to put this register 204 uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); 205 206 if (dst == NULL) 207 return false; 208 209 210 if (data.CopyByteOrderedData (0, // src offset 211 reg_info->byte_size, // src length 212 dst, // dst 213 reg_info->byte_size, // dst length 214 m_reg_data.GetByteOrder())) // dst byte order 215 { 216 SetRegisterIsValid (reg, true); 217 return true; 218 } 219 return false; 220 } 221 222 // Helper function for GDBRemoteRegisterContext::ReadRegisterBytes(). 223 bool 224 GDBRemoteRegisterContext::GetPrimordialRegister(const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm, 225 const GDBRemoteCommunicationClient::Lock &lock) 226 { 227 const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB]; 228 const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin]; 229 StringExtractorGDBRemote response; 230 if (DataBufferSP buffer_sp = gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg, lock)) 231 return PrivateSetRegisterValue(lldb_reg, 232 llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(), buffer_sp->GetByteSize())); 233 return false; 234 } 235 236 bool 237 GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, DataExtractor &data, 238 GDBRemoteCommunicationClient &gdb_comm, 239 const GDBRemoteCommunicationClient::Lock &lock) 240 { 241 InvalidateIfNeeded(false); 242 243 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 244 245 if (!GetRegisterIsValid(reg)) 246 { 247 if (m_read_all_at_once) 248 { 249 if (DataBufferSP buffer_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID(), lock)) 250 { 251 memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()), buffer_sp->GetBytes(), 252 std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize())); 253 if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) 254 { 255 SetAllRegisterValid(true); 256 return true; 257 } 258 } 259 return false; 260 } 261 if (reg_info->value_regs) 262 { 263 // Process this composite register request by delegating to the constituent 264 // primordial registers. 265 266 // Index of the primordial register. 267 bool success = true; 268 for (uint32_t idx = 0; success; ++idx) 269 { 270 const uint32_t prim_reg = reg_info->value_regs[idx]; 271 if (prim_reg == LLDB_INVALID_REGNUM) 272 break; 273 // We have a valid primordial register as our constituent. 274 // Grab the corresponding register info. 275 const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg); 276 if (prim_reg_info == NULL) 277 success = false; 278 else 279 { 280 // Read the containing register if it hasn't already been read 281 if (!GetRegisterIsValid(prim_reg)) 282 success = GetPrimordialRegister(prim_reg_info, gdb_comm, lock); 283 } 284 } 285 286 if (success) 287 { 288 // If we reach this point, all primordial register requests have succeeded. 289 // Validate this composite register. 290 SetRegisterIsValid (reg_info, true); 291 } 292 } 293 else 294 { 295 // Get each register individually 296 GetPrimordialRegister(reg_info, gdb_comm, lock); 297 } 298 299 // Make sure we got a valid register value after reading it 300 if (!GetRegisterIsValid(reg)) 301 return false; 302 } 303 304 if (&data != &m_reg_data) 305 { 306 #if defined (LLDB_CONFIGURATION_DEBUG) 307 assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size); 308 #endif 309 // If our register context and our register info disagree, which should never happen, don't 310 // read past the end of the buffer. 311 if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) 312 return false; 313 314 // If we aren't extracting into our own buffer (which 315 // only happens when this function is called from 316 // ReadRegisterValue(uint32_t, Scalar&)) then 317 // we transfer bytes from our buffer into the data 318 // buffer that was passed in 319 320 data.SetByteOrder (m_reg_data.GetByteOrder()); 321 data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size); 322 } 323 return true; 324 } 325 326 bool 327 GDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info, 328 const RegisterValue &value) 329 { 330 DataExtractor data; 331 if (value.GetData (data)) 332 return WriteRegisterBytes (reg_info, data, 0); 333 return false; 334 } 335 336 // Helper function for GDBRemoteRegisterContext::WriteRegisterBytes(). 337 bool 338 GDBRemoteRegisterContext::SetPrimordialRegister(const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm, 339 const GDBRemoteCommunicationClient::Lock &lock) 340 { 341 StreamString packet; 342 StringExtractorGDBRemote response; 343 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 344 // Invalidate just this register 345 SetRegisterIsValid(reg, false); 346 347 return gdb_comm.WriteRegister( 348 m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], 349 {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size), reg_info->byte_size}, lock); 350 } 351 352 bool 353 GDBRemoteRegisterContext::WriteRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset) 354 { 355 ExecutionContext exe_ctx (CalculateThread()); 356 357 Process *process = exe_ctx.GetProcessPtr(); 358 Thread *thread = exe_ctx.GetThreadPtr(); 359 if (process == NULL || thread == NULL) 360 return false; 361 362 GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 363 364 #if defined (LLDB_CONFIGURATION_DEBUG) 365 assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size); 366 #endif 367 368 // If our register context and our register info disagree, which should never happen, don't 369 // overwrite past the end of the buffer. 370 if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) 371 return false; 372 373 // Grab a pointer to where we are going to put this register 374 uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); 375 376 if (dst == NULL) 377 return false; 378 379 380 if (data.CopyByteOrderedData (data_offset, // src offset 381 reg_info->byte_size, // src length 382 dst, // dst 383 reg_info->byte_size, // dst length 384 m_reg_data.GetByteOrder())) // dst byte order 385 { 386 GDBRemoteClientBase::Lock lock(gdb_comm, false); 387 if (lock) 388 { 389 if (m_read_all_at_once) 390 { 391 // Invalidate all register values 392 InvalidateIfNeeded (true); 393 394 // Set all registers in one packet 395 if (gdb_comm.WriteAllRegisters(m_thread.GetProtocolID(), 396 {m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())}, lock)) 397 398 { 399 SetAllRegisterValid (false); 400 return true; 401 } 402 } 403 else 404 { 405 bool success = true; 406 407 if (reg_info->value_regs) 408 { 409 // This register is part of another register. In this case we read the actual 410 // register data for any "value_regs", and once all that data is read, we will 411 // have enough data in our register context bytes for the value of this register 412 413 // Invalidate this composite register first. 414 415 for (uint32_t idx = 0; success; ++idx) 416 { 417 const uint32_t reg = reg_info->value_regs[idx]; 418 if (reg == LLDB_INVALID_REGNUM) 419 break; 420 // We have a valid primordial register as our constituent. 421 // Grab the corresponding register info. 422 const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg); 423 if (value_reg_info == NULL) 424 success = false; 425 else 426 success = SetPrimordialRegister(value_reg_info, gdb_comm, lock); 427 } 428 } 429 else 430 { 431 // This is an actual register, write it 432 success = SetPrimordialRegister(reg_info, gdb_comm, lock); 433 } 434 435 // Check if writing this register will invalidate any other register values? 436 // If so, invalidate them 437 if (reg_info->invalidate_regs) 438 { 439 for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0]; 440 reg != LLDB_INVALID_REGNUM; 441 reg = reg_info->invalidate_regs[++idx]) 442 { 443 SetRegisterIsValid(reg, false); 444 } 445 } 446 447 return success; 448 } 449 } 450 else 451 { 452 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); 453 if (log) 454 { 455 if (log->GetVerbose()) 456 { 457 StreamString strm; 458 gdb_comm.DumpHistory(strm); 459 log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\":\n%s", reg_info->name, strm.GetData()); 460 } 461 else 462 log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\"", reg_info->name); 463 } 464 } 465 } 466 return false; 467 } 468 469 bool 470 GDBRemoteRegisterContext::ReadAllRegisterValues (RegisterCheckpoint ®_checkpoint) 471 { 472 ExecutionContext exe_ctx (CalculateThread()); 473 474 Process *process = exe_ctx.GetProcessPtr(); 475 Thread *thread = exe_ctx.GetThreadPtr(); 476 if (process == NULL || thread == NULL) 477 return false; 478 479 GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 480 481 uint32_t save_id = 0; 482 if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) 483 { 484 reg_checkpoint.SetID(save_id); 485 reg_checkpoint.GetData().reset(); 486 return true; 487 } 488 else 489 { 490 reg_checkpoint.SetID(0); // Invalid save ID is zero 491 return ReadAllRegisterValues(reg_checkpoint.GetData()); 492 } 493 } 494 495 bool 496 GDBRemoteRegisterContext::WriteAllRegisterValues (const RegisterCheckpoint ®_checkpoint) 497 { 498 uint32_t save_id = reg_checkpoint.GetID(); 499 if (save_id != 0) 500 { 501 ExecutionContext exe_ctx (CalculateThread()); 502 503 Process *process = exe_ctx.GetProcessPtr(); 504 Thread *thread = exe_ctx.GetThreadPtr(); 505 if (process == NULL || thread == NULL) 506 return false; 507 508 GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 509 510 return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id); 511 } 512 else 513 { 514 return WriteAllRegisterValues(reg_checkpoint.GetData()); 515 } 516 } 517 518 bool 519 GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) 520 { 521 ExecutionContext exe_ctx (CalculateThread()); 522 523 Process *process = exe_ctx.GetProcessPtr(); 524 Thread *thread = exe_ctx.GetThreadPtr(); 525 if (process == NULL || thread == NULL) 526 return false; 527 528 GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 529 530 const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false; 531 532 GDBRemoteClientBase::Lock lock(gdb_comm, false); 533 if (lock) 534 { 535 if (gdb_comm.SyncThreadState(m_thread.GetProtocolID())) 536 InvalidateAllRegisters(); 537 538 if (use_g_packet && (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID(), lock))) 539 return true; 540 541 // We're going to read each register 542 // individually and store them as binary data in a buffer. 543 const RegisterInfo *reg_info; 544 545 for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) 546 { 547 if (reg_info->value_regs) // skip registers that are slices of real registers 548 continue; 549 ReadRegisterBytes(reg_info, m_reg_data, gdb_comm, lock); 550 // ReadRegisterBytes saves the contents of the register in to the m_reg_data buffer 551 } 552 data_sp.reset(new DataBufferHeap(m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize())); 553 return true; 554 } 555 else 556 { 557 558 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); 559 if (log) 560 { 561 if (log->GetVerbose()) 562 { 563 StreamString strm; 564 gdb_comm.DumpHistory(strm); 565 log->Printf("error: failed to get packet sequence mutex, not sending read all registers:\n%s", strm.GetData()); 566 } 567 else 568 log->Printf("error: failed to get packet sequence mutex, not sending read all registers"); 569 } 570 } 571 572 data_sp.reset(); 573 return false; 574 } 575 576 bool 577 GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) 578 { 579 if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0) 580 return false; 581 582 ExecutionContext exe_ctx (CalculateThread()); 583 584 Process *process = exe_ctx.GetProcessPtr(); 585 Thread *thread = exe_ctx.GetThreadPtr(); 586 if (process == NULL || thread == NULL) 587 return false; 588 589 GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 590 591 const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false; 592 593 GDBRemoteClientBase::Lock lock(gdb_comm, false); 594 if (lock) 595 { 596 // The data_sp contains the G response packet. 597 if (use_g_packet) 598 { 599 if (gdb_comm.WriteAllRegisters(m_thread.GetProtocolID(), 600 {data_sp->GetBytes(), size_t(data_sp->GetByteSize())}, lock)) 601 return true; 602 603 uint32_t num_restored = 0; 604 // We need to manually go through all of the registers and 605 // restore them manually 606 DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(), m_reg_data.GetAddressByteSize()); 607 608 const RegisterInfo *reg_info; 609 610 // The g packet contents may either include the slice registers (registers defined in 611 // terms of other registers, e.g. eax is a subset of rax) or not. The slice registers 612 // should NOT be in the g packet, but some implementations may incorrectly include them. 613 // 614 // If the slice registers are included in the packet, we must step over the slice registers 615 // when parsing the packet -- relying on the RegisterInfo byte_offset field would be incorrect. 616 // If the slice registers are not included, then using the byte_offset values into the 617 // data buffer is the best way to find individual register values. 618 619 uint64_t size_including_slice_registers = 0; 620 uint64_t size_not_including_slice_registers = 0; 621 uint64_t size_by_highest_offset = 0; 622 623 for (uint32_t reg_idx = 0; (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; ++reg_idx) 624 { 625 size_including_slice_registers += reg_info->byte_size; 626 if (reg_info->value_regs == NULL) 627 size_not_including_slice_registers += reg_info->byte_size; 628 if (reg_info->byte_offset >= size_by_highest_offset) 629 size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size; 630 } 631 632 bool use_byte_offset_into_buffer; 633 if (size_by_highest_offset == restore_data.GetByteSize()) 634 { 635 // The size of the packet agrees with the highest offset: + size in the register file 636 use_byte_offset_into_buffer = true; 637 } 638 else if (size_not_including_slice_registers == restore_data.GetByteSize()) 639 { 640 // The size of the packet is the same as concatenating all of the registers sequentially, 641 // skipping the slice registers 642 use_byte_offset_into_buffer = true; 643 } 644 else if (size_including_slice_registers == restore_data.GetByteSize()) 645 { 646 // The slice registers are present in the packet (when they shouldn't be). 647 // Don't try to use the RegisterInfo byte_offset into the restore_data, it will 648 // point to the wrong place. 649 use_byte_offset_into_buffer = false; 650 } 651 else 652 { 653 // None of our expected sizes match the actual g packet data we're looking at. 654 // The most conservative approach here is to use the running total byte offset. 655 use_byte_offset_into_buffer = false; 656 } 657 658 // In case our register definitions don't include the correct offsets, 659 // keep track of the size of each reg & compute offset based on that. 660 uint32_t running_byte_offset = 0; 661 for (uint32_t reg_idx = 0; (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; 662 ++reg_idx, running_byte_offset += reg_info->byte_size) 663 { 664 // Skip composite aka slice registers (e.g. eax is a slice of rax). 665 if (reg_info->value_regs) 666 continue; 667 668 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 669 670 uint32_t register_offset; 671 if (use_byte_offset_into_buffer) 672 { 673 register_offset = reg_info->byte_offset; 674 } 675 else 676 { 677 register_offset = running_byte_offset; 678 } 679 680 const uint32_t reg_byte_size = reg_info->byte_size; 681 682 const uint8_t *restore_src = restore_data.PeekData(register_offset, reg_byte_size); 683 if (restore_src) 684 { 685 SetRegisterIsValid(reg, false); 686 if (gdb_comm.WriteRegister(m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], 687 {restore_src, reg_byte_size}, lock)) 688 ++num_restored; 689 } 690 } 691 return num_restored > 0; 692 } 693 else 694 { 695 // For the use_g_packet == false case, we're going to write each register 696 // individually. The data buffer is binary data in this case, instead of 697 // ascii characters. 698 699 bool arm64_debugserver = false; 700 if (m_thread.GetProcess().get()) 701 { 702 const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture(); 703 if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 && 704 arch.GetTriple().getVendor() == llvm::Triple::Apple && 705 arch.GetTriple().getOS() == llvm::Triple::IOS) 706 { 707 arm64_debugserver = true; 708 } 709 } 710 uint32_t num_restored = 0; 711 const RegisterInfo *reg_info; 712 for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) 713 { 714 if (reg_info->value_regs) // skip registers that are slices of real registers 715 continue; 716 // Skip the fpsr and fpcr floating point status/control register writing to 717 // work around a bug in an older version of debugserver that would lead to 718 // register context corruption when writing fpsr/fpcr. 719 if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 || strcmp(reg_info->name, "fpcr") == 0)) 720 { 721 continue; 722 } 723 724 SetRegisterIsValid(reg_info, false); 725 if (gdb_comm.WriteRegister(m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], 726 {data_sp->GetBytes() + reg_info->byte_offset, reg_info->byte_size}, lock)) 727 ++num_restored; 728 } 729 return num_restored > 0; 730 } 731 } 732 else 733 { 734 Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); 735 if (log) 736 { 737 if (log->GetVerbose()) 738 { 739 StreamString strm; 740 gdb_comm.DumpHistory(strm); 741 log->Printf("error: failed to get packet sequence mutex, not sending write all registers:\n%s", strm.GetData()); 742 } 743 else 744 log->Printf("error: failed to get packet sequence mutex, not sending write all registers"); 745 } 746 } 747 return false; 748 } 749 750 751 uint32_t 752 GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) 753 { 754 return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num); 755 } 756 757 758 void 759 GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) 760 { 761 // For Advanced SIMD and VFP register mapping. 762 static uint32_t g_d0_regs[] = { 26, 27, LLDB_INVALID_REGNUM }; // (s0, s1) 763 static uint32_t g_d1_regs[] = { 28, 29, LLDB_INVALID_REGNUM }; // (s2, s3) 764 static uint32_t g_d2_regs[] = { 30, 31, LLDB_INVALID_REGNUM }; // (s4, s5) 765 static uint32_t g_d3_regs[] = { 32, 33, LLDB_INVALID_REGNUM }; // (s6, s7) 766 static uint32_t g_d4_regs[] = { 34, 35, LLDB_INVALID_REGNUM }; // (s8, s9) 767 static uint32_t g_d5_regs[] = { 36, 37, LLDB_INVALID_REGNUM }; // (s10, s11) 768 static uint32_t g_d6_regs[] = { 38, 39, LLDB_INVALID_REGNUM }; // (s12, s13) 769 static uint32_t g_d7_regs[] = { 40, 41, LLDB_INVALID_REGNUM }; // (s14, s15) 770 static uint32_t g_d8_regs[] = { 42, 43, LLDB_INVALID_REGNUM }; // (s16, s17) 771 static uint32_t g_d9_regs[] = { 44, 45, LLDB_INVALID_REGNUM }; // (s18, s19) 772 static uint32_t g_d10_regs[] = { 46, 47, LLDB_INVALID_REGNUM }; // (s20, s21) 773 static uint32_t g_d11_regs[] = { 48, 49, LLDB_INVALID_REGNUM }; // (s22, s23) 774 static uint32_t g_d12_regs[] = { 50, 51, LLDB_INVALID_REGNUM }; // (s24, s25) 775 static uint32_t g_d13_regs[] = { 52, 53, LLDB_INVALID_REGNUM }; // (s26, s27) 776 static uint32_t g_d14_regs[] = { 54, 55, LLDB_INVALID_REGNUM }; // (s28, s29) 777 static uint32_t g_d15_regs[] = { 56, 57, LLDB_INVALID_REGNUM }; // (s30, s31) 778 static uint32_t g_q0_regs[] = { 26, 27, 28, 29, LLDB_INVALID_REGNUM }; // (d0, d1) -> (s0, s1, s2, s3) 779 static uint32_t g_q1_regs[] = { 30, 31, 32, 33, LLDB_INVALID_REGNUM }; // (d2, d3) -> (s4, s5, s6, s7) 780 static uint32_t g_q2_regs[] = { 34, 35, 36, 37, LLDB_INVALID_REGNUM }; // (d4, d5) -> (s8, s9, s10, s11) 781 static uint32_t g_q3_regs[] = { 38, 39, 40, 41, LLDB_INVALID_REGNUM }; // (d6, d7) -> (s12, s13, s14, s15) 782 static uint32_t g_q4_regs[] = { 42, 43, 44, 45, LLDB_INVALID_REGNUM }; // (d8, d9) -> (s16, s17, s18, s19) 783 static uint32_t g_q5_regs[] = { 46, 47, 48, 49, LLDB_INVALID_REGNUM }; // (d10, d11) -> (s20, s21, s22, s23) 784 static uint32_t g_q6_regs[] = { 50, 51, 52, 53, LLDB_INVALID_REGNUM }; // (d12, d13) -> (s24, s25, s26, s27) 785 static uint32_t g_q7_regs[] = { 54, 55, 56, 57, LLDB_INVALID_REGNUM }; // (d14, d15) -> (s28, s29, s30, s31) 786 static uint32_t g_q8_regs[] = { 59, 60, LLDB_INVALID_REGNUM }; // (d16, d17) 787 static uint32_t g_q9_regs[] = { 61, 62, LLDB_INVALID_REGNUM }; // (d18, d19) 788 static uint32_t g_q10_regs[] = { 63, 64, LLDB_INVALID_REGNUM }; // (d20, d21) 789 static uint32_t g_q11_regs[] = { 65, 66, LLDB_INVALID_REGNUM }; // (d22, d23) 790 static uint32_t g_q12_regs[] = { 67, 68, LLDB_INVALID_REGNUM }; // (d24, d25) 791 static uint32_t g_q13_regs[] = { 69, 70, LLDB_INVALID_REGNUM }; // (d26, d27) 792 static uint32_t g_q14_regs[] = { 71, 72, LLDB_INVALID_REGNUM }; // (d28, d29) 793 static uint32_t g_q15_regs[] = { 73, 74, LLDB_INVALID_REGNUM }; // (d30, d31) 794 795 // This is our array of composite registers, with each element coming from the above register mappings. 796 static uint32_t *g_composites[] = { 797 g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs, g_d6_regs, g_d7_regs, 798 g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs, g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs, 799 g_q0_regs, g_q1_regs, g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs, 800 g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs, g_q14_regs, g_q15_regs 801 }; 802 803 // clang-format off 804 static RegisterInfo g_register_infos[] = { 805 // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS SIZE EXPR SIZE LEN 806 // ====== ====== === === ============= ========== =================== =================== ====================== ============= ==== ========== =============== ========= ======== 807 { "r0", "arg1", 4, 0, eEncodingUint, eFormatHex, { ehframe_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1,0, 0 }, nullptr, nullptr, nullptr, 0 }, 808 { "r1", "arg2", 4, 0, eEncodingUint, eFormatHex, { ehframe_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2,1, 1 }, nullptr, nullptr, nullptr, 0 }, 809 { "r2", "arg3", 4, 0, eEncodingUint, eFormatHex, { ehframe_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3,2, 2 }, nullptr, nullptr, nullptr, 0 }, 810 { "r3", "arg4", 4, 0, eEncodingUint, eFormatHex, { ehframe_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4,3, 3 }, nullptr, nullptr, nullptr, 0 }, 811 { "r4", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }, nullptr, nullptr, nullptr, 0 }, 812 { "r5", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }, nullptr, nullptr, nullptr, 0 }, 813 { "r6", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }, nullptr, nullptr, nullptr, 0 }, 814 { "r7", "fp", 4, 0, eEncodingUint, eFormatHex, { ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }, nullptr, nullptr, nullptr, 0 }, 815 { "r8", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }, nullptr, nullptr, nullptr, 0 }, 816 { "r9", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }, nullptr, nullptr, nullptr, 0 }, 817 { "r10", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }, nullptr, nullptr, nullptr, 0 }, 818 { "r11", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }, nullptr, nullptr, nullptr, 0 }, 819 { "r12", nullptr, 4, 0, eEncodingUint, eFormatHex, { ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }, nullptr, nullptr, nullptr, 0 }, 820 { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }, nullptr, nullptr, nullptr, 0 }, 821 { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }, nullptr, nullptr, nullptr, 0 }, 822 { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }, nullptr, nullptr, nullptr, 0 }, 823 { "f0", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }, nullptr, nullptr, nullptr, 0 }, 824 { "f1", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }, nullptr, nullptr, nullptr, 0 }, 825 { "f2", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }, nullptr, nullptr, nullptr, 0 }, 826 { "f3", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }, nullptr, nullptr, nullptr, 0 }, 827 { "f4", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }, nullptr, nullptr, nullptr, 0 }, 828 { "f5", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }, nullptr, nullptr, nullptr, 0 }, 829 { "f6", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }, nullptr, nullptr, nullptr, 0 }, 830 { "f7", nullptr, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }, nullptr, nullptr, nullptr, 0 }, 831 { "fps", nullptr, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }, nullptr, nullptr, nullptr, 0 }, 832 { "cpsr","flags", 4, 0, eEncodingUint, eFormatHex, { ehframe_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }, nullptr, nullptr, nullptr, 0 }, 833 { "s0", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }, nullptr, nullptr, nullptr, 0 }, 834 { "s1", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }, nullptr, nullptr, nullptr, 0 }, 835 { "s2", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }, nullptr, nullptr, nullptr, 0 }, 836 { "s3", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }, nullptr, nullptr, nullptr, 0 }, 837 { "s4", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }, nullptr, nullptr, nullptr, 0 }, 838 { "s5", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }, nullptr, nullptr, nullptr, 0 }, 839 { "s6", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }, nullptr, nullptr, nullptr, 0 }, 840 { "s7", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }, nullptr, nullptr, nullptr, 0 }, 841 { "s8", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }, nullptr, nullptr, nullptr, 0 }, 842 { "s9", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }, nullptr, nullptr, nullptr, 0 }, 843 { "s10", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }, nullptr, nullptr, nullptr, 0 }, 844 { "s11", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }, nullptr, nullptr, nullptr, 0 }, 845 { "s12", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }, nullptr, nullptr, nullptr, 0 }, 846 { "s13", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }, nullptr, nullptr, nullptr, 0 }, 847 { "s14", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }, nullptr, nullptr, nullptr, 0 }, 848 { "s15", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }, nullptr, nullptr, nullptr, 0 }, 849 { "s16", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }, nullptr, nullptr, nullptr, 0 }, 850 { "s17", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }, nullptr, nullptr, nullptr, 0 }, 851 { "s18", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }, nullptr, nullptr, nullptr, 0 }, 852 { "s19", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }, nullptr, nullptr, nullptr, 0 }, 853 { "s20", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }, nullptr, nullptr, nullptr, 0 }, 854 { "s21", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }, nullptr, nullptr, nullptr, 0 }, 855 { "s22", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }, nullptr, nullptr, nullptr, 0 }, 856 { "s23", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }, nullptr, nullptr, nullptr, 0 }, 857 { "s24", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }, nullptr, nullptr, nullptr, 0 }, 858 { "s25", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }, nullptr, nullptr, nullptr, 0 }, 859 { "s26", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }, nullptr, nullptr, nullptr, 0 }, 860 { "s27", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }, nullptr, nullptr, nullptr, 0 }, 861 { "s28", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }, nullptr, nullptr, nullptr, 0 }, 862 { "s29", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }, nullptr, nullptr, nullptr, 0 }, 863 { "s30", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }, nullptr, nullptr, nullptr, 0 }, 864 { "s31", nullptr, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }, nullptr, nullptr, nullptr, 0 }, 865 { "fpscr",nullptr, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }, nullptr, nullptr, nullptr, 0 }, 866 { "d16", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }, nullptr, nullptr, nullptr, 0 }, 867 { "d17", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }, nullptr, nullptr, nullptr, 0 }, 868 { "d18", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }, nullptr, nullptr, nullptr, 0 }, 869 { "d19", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }, nullptr, nullptr, nullptr, 0 }, 870 { "d20", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }, nullptr, nullptr, nullptr, 0 }, 871 { "d21", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }, nullptr, nullptr, nullptr, 0 }, 872 { "d22", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }, nullptr, nullptr, nullptr, 0 }, 873 { "d23", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }, nullptr, nullptr, nullptr, 0 }, 874 { "d24", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }, nullptr, nullptr, nullptr, 0 }, 875 { "d25", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }, nullptr, nullptr, nullptr, 0 }, 876 { "d26", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }, nullptr, nullptr, nullptr, 0 }, 877 { "d27", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }, nullptr, nullptr, nullptr, 0 }, 878 { "d28", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }, nullptr, nullptr, nullptr, 0 }, 879 { "d29", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }, nullptr, nullptr, nullptr, 0 }, 880 { "d30", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }, nullptr, nullptr, nullptr, 0 }, 881 { "d31", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }, nullptr, nullptr, nullptr, 0 }, 882 { "d0", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, 75, 75 }, g_d0_regs, nullptr, nullptr, 0 }, 883 { "d1", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, 76, 76 }, g_d1_regs, nullptr, nullptr, 0 }, 884 { "d2", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, 77, 77 }, g_d2_regs, nullptr, nullptr, 0 }, 885 { "d3", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, 78, 78 }, g_d3_regs, nullptr, nullptr, 0 }, 886 { "d4", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, 79, 79 }, g_d4_regs, nullptr, nullptr, 0 }, 887 { "d5", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, 80, 80 }, g_d5_regs, nullptr, nullptr, 0 }, 888 { "d6", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, 81, 81 }, g_d6_regs, nullptr, nullptr, 0 }, 889 { "d7", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, 82, 82 }, g_d7_regs, nullptr, nullptr, 0 }, 890 { "d8", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, 83, 83 }, g_d8_regs, nullptr, nullptr, 0 }, 891 { "d9", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, 84, 84 }, g_d9_regs, nullptr, nullptr, 0 }, 892 { "d10", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, 85, 85 }, g_d10_regs, nullptr, nullptr, 0 }, 893 { "d11", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, 86, 86 }, g_d11_regs, nullptr, nullptr, 0 }, 894 { "d12", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, 87, 87 }, g_d12_regs, nullptr, nullptr, 0 }, 895 { "d13", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, 88, 88 }, g_d13_regs, nullptr, nullptr, 0 }, 896 { "d14", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, 89, 89 }, g_d14_regs, nullptr, nullptr, 0 }, 897 { "d15", nullptr, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, 90, 90 }, g_d15_regs, nullptr, nullptr, 0 }, 898 { "q0", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, 91, 91 }, g_q0_regs, nullptr, nullptr, 0 }, 899 { "q1", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, 92, 92 }, g_q1_regs, nullptr, nullptr, 0 }, 900 { "q2", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, 93, 93 }, g_q2_regs, nullptr, nullptr, 0 }, 901 { "q3", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, 94, 94 }, g_q3_regs, nullptr, nullptr, 0 }, 902 { "q4", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, 95, 95 }, g_q4_regs, nullptr, nullptr, 0 }, 903 { "q5", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, 96, 96 }, g_q5_regs, nullptr, nullptr, 0 }, 904 { "q6", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, 97, 97 }, g_q6_regs, nullptr, nullptr, 0 }, 905 { "q7", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, 98, 98 }, g_q7_regs, nullptr, nullptr, 0 }, 906 { "q8", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, 99, 99 }, g_q8_regs, nullptr, nullptr, 0 }, 907 { "q9", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, 100, 100 }, g_q9_regs, nullptr, nullptr, 0 }, 908 { "q10", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, 101, 101 }, g_q10_regs, nullptr, nullptr, 0 }, 909 { "q11", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, 102, 102 }, g_q11_regs, nullptr, nullptr, 0 }, 910 { "q12", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, 103, 103 }, g_q12_regs, nullptr, nullptr, 0 }, 911 { "q13", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, 104, 104 }, g_q13_regs, nullptr, nullptr, 0 }, 912 { "q14", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, nullptr, nullptr, 0 }, 913 { "q15", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, nullptr, nullptr, 0 } 914 }; 915 // clang-format on 916 917 static const uint32_t num_registers = llvm::array_lengthof(g_register_infos); 918 static ConstString gpr_reg_set ("General Purpose Registers"); 919 static ConstString sfp_reg_set ("Software Floating Point Registers"); 920 static ConstString vfp_reg_set ("Floating Point Registers"); 921 size_t i; 922 if (from_scratch) 923 { 924 // Calculate the offsets of the registers 925 // Note that the layout of the "composite" registers (d0-d15 and q0-q15) which comes after the 926 // "primordial" registers is important. This enables us to calculate the offset of the composite 927 // register by using the offset of its first primordial register. For example, to calculate the 928 // offset of q0, use s0's offset. 929 if (g_register_infos[2].byte_offset == 0) 930 { 931 uint32_t byte_offset = 0; 932 for (i=0; i<num_registers; ++i) 933 { 934 // For primordial registers, increment the byte_offset by the byte_size to arrive at the 935 // byte_offset for the next register. Otherwise, we have a composite register whose 936 // offset can be calculated by consulting the offset of its first primordial register. 937 if (!g_register_infos[i].value_regs) 938 { 939 g_register_infos[i].byte_offset = byte_offset; 940 byte_offset += g_register_infos[i].byte_size; 941 } 942 else 943 { 944 const uint32_t first_primordial_reg = g_register_infos[i].value_regs[0]; 945 g_register_infos[i].byte_offset = g_register_infos[first_primordial_reg].byte_offset; 946 } 947 } 948 } 949 for (i=0; i<num_registers; ++i) 950 { 951 ConstString name; 952 ConstString alt_name; 953 if (g_register_infos[i].name && g_register_infos[i].name[0]) 954 name.SetCString(g_register_infos[i].name); 955 if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0]) 956 alt_name.SetCString(g_register_infos[i].alt_name); 957 958 if (i <= 15 || i == 25) 959 AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set); 960 else if (i <= 24) 961 AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set); 962 else 963 AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set); 964 } 965 } 966 else 967 { 968 // Add composite registers to our primordial registers, then. 969 const size_t num_composites = llvm::array_lengthof(g_composites); 970 const size_t num_dynamic_regs = GetNumRegisters(); 971 const size_t num_common_regs = num_registers - num_composites; 972 RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs; 973 974 // First we need to validate that all registers that we already have match the non composite regs. 975 // If so, then we can add the registers, else we need to bail 976 bool match = true; 977 if (num_dynamic_regs == num_common_regs) 978 { 979 for (i=0; match && i<num_dynamic_regs; ++i) 980 { 981 // Make sure all register names match 982 if (m_regs[i].name && g_register_infos[i].name) 983 { 984 if (strcmp(m_regs[i].name, g_register_infos[i].name)) 985 { 986 match = false; 987 break; 988 } 989 } 990 991 // Make sure all register byte sizes match 992 if (m_regs[i].byte_size != g_register_infos[i].byte_size) 993 { 994 match = false; 995 break; 996 } 997 } 998 } 999 else 1000 { 1001 // Wrong number of registers. 1002 match = false; 1003 } 1004 // If "match" is true, then we can add extra registers. 1005 if (match) 1006 { 1007 for (i=0; i<num_composites; ++i) 1008 { 1009 ConstString name; 1010 ConstString alt_name; 1011 const uint32_t first_primordial_reg = g_comp_register_infos[i].value_regs[0]; 1012 const char *reg_name = g_register_infos[first_primordial_reg].name; 1013 if (reg_name && reg_name[0]) 1014 { 1015 for (uint32_t j = 0; j < num_dynamic_regs; ++j) 1016 { 1017 const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j); 1018 // Find a matching primordial register info entry. 1019 if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, reg_name) == 0) 1020 { 1021 // The name matches the existing primordial entry. 1022 // Find and assign the offset, and then add this composite register entry. 1023 g_comp_register_infos[i].byte_offset = reg_info->byte_offset; 1024 name.SetCString(g_comp_register_infos[i].name); 1025 AddRegister(g_comp_register_infos[i], name, alt_name, vfp_reg_set); 1026 } 1027 } 1028 } 1029 } 1030 } 1031 } 1032 } 1033