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