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