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