GDBRemoteRegisterContext.cpp revision 254721
1254721Semaste//===-- GDBRemoteRegisterContext.cpp ----------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "GDBRemoteRegisterContext.h" 11254721Semaste 12254721Semaste// C Includes 13254721Semaste// C++ Includes 14254721Semaste// Other libraries and framework includes 15254721Semaste#include "lldb/Core/DataBufferHeap.h" 16254721Semaste#include "lldb/Core/DataExtractor.h" 17254721Semaste#include "lldb/Core/RegisterValue.h" 18254721Semaste#include "lldb/Core/Scalar.h" 19254721Semaste#include "lldb/Core/StreamString.h" 20254721Semaste#include "lldb/Target/ExecutionContext.h" 21254721Semaste#include "lldb/Utility/Utils.h" 22254721Semaste// Project includes 23254721Semaste#include "Utility/StringExtractorGDBRemote.h" 24254721Semaste#include "ProcessGDBRemote.h" 25254721Semaste#include "ProcessGDBRemoteLog.h" 26254721Semaste#include "ThreadGDBRemote.h" 27254721Semaste#include "Utility/ARM_GCC_Registers.h" 28254721Semaste#include "Utility/ARM_DWARF_Registers.h" 29254721Semaste 30254721Semasteusing namespace lldb; 31254721Semasteusing namespace lldb_private; 32254721Semaste 33254721Semaste//---------------------------------------------------------------------- 34254721Semaste// GDBRemoteRegisterContext constructor 35254721Semaste//---------------------------------------------------------------------- 36254721SemasteGDBRemoteRegisterContext::GDBRemoteRegisterContext 37254721Semaste( 38254721Semaste ThreadGDBRemote &thread, 39254721Semaste uint32_t concrete_frame_idx, 40254721Semaste GDBRemoteDynamicRegisterInfo ®_info, 41254721Semaste bool read_all_at_once 42254721Semaste) : 43254721Semaste RegisterContext (thread, concrete_frame_idx), 44254721Semaste m_reg_info (reg_info), 45254721Semaste m_reg_valid (), 46254721Semaste m_reg_data (), 47254721Semaste m_read_all_at_once (read_all_at_once) 48254721Semaste{ 49254721Semaste // Resize our vector of bools to contain one bool for every register. 50254721Semaste // We will use these boolean values to know when a register value 51254721Semaste // is valid in m_reg_data. 52254721Semaste m_reg_valid.resize (reg_info.GetNumRegisters()); 53254721Semaste 54254721Semaste // Make a heap based buffer that is big enough to store all registers 55254721Semaste DataBufferSP reg_data_sp(new DataBufferHeap (reg_info.GetRegisterDataByteSize(), 0)); 56254721Semaste m_reg_data.SetData (reg_data_sp); 57254721Semaste 58254721Semaste} 59254721Semaste 60254721Semaste//---------------------------------------------------------------------- 61254721Semaste// Destructor 62254721Semaste//---------------------------------------------------------------------- 63254721SemasteGDBRemoteRegisterContext::~GDBRemoteRegisterContext() 64254721Semaste{ 65254721Semaste} 66254721Semaste 67254721Semastevoid 68254721SemasteGDBRemoteRegisterContext::InvalidateAllRegisters () 69254721Semaste{ 70254721Semaste SetAllRegisterValid (false); 71254721Semaste} 72254721Semaste 73254721Semastevoid 74254721SemasteGDBRemoteRegisterContext::SetAllRegisterValid (bool b) 75254721Semaste{ 76254721Semaste std::vector<bool>::iterator pos, end = m_reg_valid.end(); 77254721Semaste for (pos = m_reg_valid.begin(); pos != end; ++pos) 78254721Semaste *pos = b; 79254721Semaste} 80254721Semaste 81254721Semastesize_t 82254721SemasteGDBRemoteRegisterContext::GetRegisterCount () 83254721Semaste{ 84254721Semaste return m_reg_info.GetNumRegisters (); 85254721Semaste} 86254721Semaste 87254721Semasteconst RegisterInfo * 88254721SemasteGDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg) 89254721Semaste{ 90254721Semaste return m_reg_info.GetRegisterInfoAtIndex (reg); 91254721Semaste} 92254721Semaste 93254721Semastesize_t 94254721SemasteGDBRemoteRegisterContext::GetRegisterSetCount () 95254721Semaste{ 96254721Semaste return m_reg_info.GetNumRegisterSets (); 97254721Semaste} 98254721Semaste 99254721Semaste 100254721Semaste 101254721Semasteconst RegisterSet * 102254721SemasteGDBRemoteRegisterContext::GetRegisterSet (size_t reg_set) 103254721Semaste{ 104254721Semaste return m_reg_info.GetRegisterSet (reg_set); 105254721Semaste} 106254721Semaste 107254721Semaste 108254721Semaste 109254721Semastebool 110254721SemasteGDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) 111254721Semaste{ 112254721Semaste // Read the register 113254721Semaste if (ReadRegisterBytes (reg_info, m_reg_data)) 114254721Semaste { 115254721Semaste const bool partial_data_ok = false; 116254721Semaste Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok)); 117254721Semaste return error.Success(); 118254721Semaste } 119254721Semaste return false; 120254721Semaste} 121254721Semaste 122254721Semastebool 123254721SemasteGDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) 124254721Semaste{ 125254721Semaste const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); 126254721Semaste if (reg_info == NULL) 127254721Semaste return false; 128254721Semaste 129254721Semaste // Invalidate if needed 130254721Semaste InvalidateIfNeeded(false); 131254721Semaste 132254721Semaste const uint32_t reg_byte_size = reg_info->byte_size; 133254721Semaste 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'); 134254721Semaste bool success = bytes_copied == reg_byte_size; 135254721Semaste if (success) 136254721Semaste { 137254721Semaste SetRegisterIsValid(reg, true); 138254721Semaste } 139254721Semaste else if (bytes_copied > 0) 140254721Semaste { 141254721Semaste // Only set register is valid to false if we copied some bytes, else 142254721Semaste // leave it as it was. 143254721Semaste SetRegisterIsValid(reg, false); 144254721Semaste } 145254721Semaste return success; 146254721Semaste} 147254721Semaste 148254721Semaste// Helper function for GDBRemoteRegisterContext::ReadRegisterBytes(). 149254721Semastebool 150254721SemasteGDBRemoteRegisterContext::GetPrimordialRegister(const lldb_private::RegisterInfo *reg_info, 151254721Semaste GDBRemoteCommunicationClient &gdb_comm) 152254721Semaste{ 153254721Semaste char packet[64]; 154254721Semaste StringExtractorGDBRemote response; 155254721Semaste int packet_len = 0; 156254721Semaste const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 157254721Semaste if (gdb_comm.GetThreadSuffixSupported()) 158254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "p%x;thread:%4.4" PRIx64 ";", reg, m_thread.GetProtocolID()); 159254721Semaste else 160254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "p%x", reg); 161254721Semaste assert (packet_len < ((int)sizeof(packet) - 1)); 162254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet, response, false)) 163254721Semaste return PrivateSetRegisterValue (reg, response); 164254721Semaste 165254721Semaste return false; 166254721Semaste} 167254721Semastebool 168254721SemasteGDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data) 169254721Semaste{ 170254721Semaste ExecutionContext exe_ctx (CalculateThread()); 171254721Semaste 172254721Semaste Process *process = exe_ctx.GetProcessPtr(); 173254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 174254721Semaste if (process == NULL || thread == NULL) 175254721Semaste return false; 176254721Semaste 177254721Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 178254721Semaste 179254721Semaste InvalidateIfNeeded(false); 180254721Semaste 181254721Semaste const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 182254721Semaste 183254721Semaste if (!GetRegisterIsValid(reg)) 184254721Semaste { 185254721Semaste Mutex::Locker locker; 186254721Semaste if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for read register.")) 187254721Semaste { 188254721Semaste const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); 189254721Semaste ProcessSP process_sp (m_thread.GetProcess()); 190254721Semaste if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID())) 191254721Semaste { 192254721Semaste char packet[64]; 193254721Semaste StringExtractorGDBRemote response; 194254721Semaste int packet_len = 0; 195254721Semaste if (m_read_all_at_once) 196254721Semaste { 197254721Semaste // Get all registers in one packet 198254721Semaste if (thread_suffix_supported) 199254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 200254721Semaste else 201254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "g"); 202254721Semaste assert (packet_len < ((int)sizeof(packet) - 1)); 203254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet, response, false)) 204254721Semaste { 205254721Semaste if (response.IsNormalResponse()) 206254721Semaste if (response.GetHexBytes ((void *)m_reg_data.GetDataStart(), m_reg_data.GetByteSize(), '\xcc') == m_reg_data.GetByteSize()) 207254721Semaste SetAllRegisterValid (true); 208254721Semaste } 209254721Semaste } 210254721Semaste else if (reg_info->value_regs) 211254721Semaste { 212254721Semaste // Process this composite register request by delegating to the constituent 213254721Semaste // primordial registers. 214254721Semaste 215254721Semaste // Index of the primordial register. 216254721Semaste bool success = true; 217254721Semaste for (uint32_t idx = 0; success; ++idx) 218254721Semaste { 219254721Semaste const uint32_t prim_reg = reg_info->value_regs[idx]; 220254721Semaste if (prim_reg == LLDB_INVALID_REGNUM) 221254721Semaste break; 222254721Semaste // We have a valid primordial regsiter as our constituent. 223254721Semaste // Grab the corresponding register info. 224254721Semaste const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg); 225254721Semaste if (prim_reg_info == NULL) 226254721Semaste success = false; 227254721Semaste else 228254721Semaste { 229254721Semaste // Read the containing register if it hasn't already been read 230254721Semaste if (!GetRegisterIsValid(prim_reg)) 231254721Semaste success = GetPrimordialRegister(prim_reg_info, gdb_comm); 232254721Semaste } 233254721Semaste } 234254721Semaste 235254721Semaste if (success) 236254721Semaste { 237254721Semaste // If we reach this point, all primordial register requests have succeeded. 238254721Semaste // Validate this composite register. 239254721Semaste SetRegisterIsValid (reg_info, true); 240254721Semaste } 241254721Semaste } 242254721Semaste else 243254721Semaste { 244254721Semaste // Get each register individually 245254721Semaste GetPrimordialRegister(reg_info, gdb_comm); 246254721Semaste } 247254721Semaste } 248254721Semaste } 249254721Semaste else 250254721Semaste { 251254721Semaste#if LLDB_CONFIGURATION_DEBUG 252254721Semaste StreamString strm; 253254721Semaste gdb_comm.DumpHistory(strm); 254254721Semaste Host::SetCrashDescription (strm.GetData()); 255254721Semaste assert (!"Didn't get sequence mutex for read register."); 256254721Semaste#else 257254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); 258254721Semaste if (log) 259254721Semaste { 260254721Semaste if (log->GetVerbose()) 261254721Semaste { 262254721Semaste StreamString strm; 263254721Semaste gdb_comm.DumpHistory(strm); 264254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending read register for \"%s\":\n%s", reg_info->name, strm.GetData()); 265254721Semaste } 266254721Semaste else 267254721Semaste { 268254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending read register for \"%s\"", reg_info->name); 269254721Semaste } 270254721Semaste } 271254721Semaste#endif 272254721Semaste } 273254721Semaste 274254721Semaste // Make sure we got a valid register value after reading it 275254721Semaste if (!GetRegisterIsValid(reg)) 276254721Semaste return false; 277254721Semaste } 278254721Semaste 279254721Semaste if (&data != &m_reg_data) 280254721Semaste { 281254721Semaste // If we aren't extracting into our own buffer (which 282254721Semaste // only happens when this function is called from 283254721Semaste // ReadRegisterValue(uint32_t, Scalar&)) then 284254721Semaste // we transfer bytes from our buffer into the data 285254721Semaste // buffer that was passed in 286254721Semaste data.SetByteOrder (m_reg_data.GetByteOrder()); 287254721Semaste data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size); 288254721Semaste } 289254721Semaste return true; 290254721Semaste} 291254721Semaste 292254721Semastebool 293254721SemasteGDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info, 294254721Semaste const RegisterValue &value) 295254721Semaste{ 296254721Semaste DataExtractor data; 297254721Semaste if (value.GetData (data)) 298254721Semaste return WriteRegisterBytes (reg_info, data, 0); 299254721Semaste return false; 300254721Semaste} 301254721Semaste 302254721Semaste// Helper function for GDBRemoteRegisterContext::WriteRegisterBytes(). 303254721Semastebool 304254721SemasteGDBRemoteRegisterContext::SetPrimordialRegister(const lldb_private::RegisterInfo *reg_info, 305254721Semaste GDBRemoteCommunicationClient &gdb_comm) 306254721Semaste{ 307254721Semaste StreamString packet; 308254721Semaste StringExtractorGDBRemote response; 309254721Semaste const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 310254721Semaste packet.Printf ("P%x=", reg); 311254721Semaste packet.PutBytesAsRawHex8 (m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size), 312254721Semaste reg_info->byte_size, 313254721Semaste lldb::endian::InlHostByteOrder(), 314254721Semaste lldb::endian::InlHostByteOrder()); 315254721Semaste 316254721Semaste if (gdb_comm.GetThreadSuffixSupported()) 317254721Semaste packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 318254721Semaste 319254721Semaste // Invalidate just this register 320254721Semaste SetRegisterIsValid(reg, false); 321254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), 322254721Semaste packet.GetString().size(), 323254721Semaste response, 324254721Semaste false)) 325254721Semaste { 326254721Semaste if (response.IsOKResponse()) 327254721Semaste return true; 328254721Semaste } 329254721Semaste return false; 330254721Semaste} 331254721Semaste 332254721Semastevoid 333254721SemasteGDBRemoteRegisterContext::SyncThreadState(Process *process) 334254721Semaste{ 335254721Semaste // NB. We assume our caller has locked the sequence mutex. 336254721Semaste 337254721Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *) process)->GetGDBRemote()); 338254721Semaste if (!gdb_comm.GetSyncThreadStateSupported()) 339254721Semaste return; 340254721Semaste 341254721Semaste StreamString packet; 342254721Semaste StringExtractorGDBRemote response; 343254721Semaste packet.Printf ("QSyncThreadState:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 344254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), 345254721Semaste packet.GetString().size(), 346254721Semaste response, 347254721Semaste false)) 348254721Semaste { 349254721Semaste if (response.IsOKResponse()) 350254721Semaste InvalidateAllRegisters(); 351254721Semaste } 352254721Semaste} 353254721Semaste 354254721Semastebool 355254721SemasteGDBRemoteRegisterContext::WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset) 356254721Semaste{ 357254721Semaste ExecutionContext exe_ctx (CalculateThread()); 358254721Semaste 359254721Semaste Process *process = exe_ctx.GetProcessPtr(); 360254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 361254721Semaste if (process == NULL || thread == NULL) 362254721Semaste return false; 363254721Semaste 364254721Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 365254721Semaste// FIXME: This check isn't right because IsRunning checks the Public state, but this 366254721Semaste// is work you need to do - for instance in ShouldStop & friends - before the public 367254721Semaste// state has been changed. 368254721Semaste// if (gdb_comm.IsRunning()) 369254721Semaste// return false; 370254721Semaste 371254721Semaste // Grab a pointer to where we are going to put this register 372254721Semaste uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); 373254721Semaste 374254721Semaste if (dst == NULL) 375254721Semaste return false; 376254721Semaste 377254721Semaste 378254721Semaste if (data.CopyByteOrderedData (data_offset, // src offset 379254721Semaste reg_info->byte_size, // src length 380254721Semaste dst, // dst 381254721Semaste reg_info->byte_size, // dst length 382254721Semaste m_reg_data.GetByteOrder())) // dst byte order 383254721Semaste { 384254721Semaste Mutex::Locker locker; 385254721Semaste if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write register.")) 386254721Semaste { 387254721Semaste const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); 388254721Semaste ProcessSP process_sp (m_thread.GetProcess()); 389254721Semaste if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID())) 390254721Semaste { 391254721Semaste StreamString packet; 392254721Semaste StringExtractorGDBRemote response; 393254721Semaste 394254721Semaste if (m_read_all_at_once) 395254721Semaste { 396254721Semaste // Set all registers in one packet 397254721Semaste packet.PutChar ('G'); 398254721Semaste packet.PutBytesAsRawHex8 (m_reg_data.GetDataStart(), 399254721Semaste m_reg_data.GetByteSize(), 400254721Semaste lldb::endian::InlHostByteOrder(), 401254721Semaste lldb::endian::InlHostByteOrder()); 402254721Semaste 403254721Semaste if (thread_suffix_supported) 404254721Semaste packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 405254721Semaste 406254721Semaste // Invalidate all register values 407254721Semaste InvalidateIfNeeded (true); 408254721Semaste 409254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), 410254721Semaste packet.GetString().size(), 411254721Semaste response, 412254721Semaste false)) 413254721Semaste { 414254721Semaste SetAllRegisterValid (false); 415254721Semaste if (response.IsOKResponse()) 416254721Semaste { 417254721Semaste return true; 418254721Semaste } 419254721Semaste } 420254721Semaste } 421254721Semaste else 422254721Semaste { 423254721Semaste bool success = true; 424254721Semaste 425254721Semaste if (reg_info->value_regs) 426254721Semaste { 427254721Semaste // This register is part of another register. In this case we read the actual 428254721Semaste // register data for any "value_regs", and once all that data is read, we will 429254721Semaste // have enough data in our register context bytes for the value of this register 430254721Semaste 431254721Semaste // Invalidate this composite register first. 432254721Semaste 433254721Semaste for (uint32_t idx = 0; success; ++idx) 434254721Semaste { 435254721Semaste const uint32_t reg = reg_info->value_regs[idx]; 436254721Semaste if (reg == LLDB_INVALID_REGNUM) 437254721Semaste break; 438254721Semaste // We have a valid primordial regsiter as our constituent. 439254721Semaste // Grab the corresponding register info. 440254721Semaste const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg); 441254721Semaste if (value_reg_info == NULL) 442254721Semaste success = false; 443254721Semaste else 444254721Semaste success = SetPrimordialRegister(value_reg_info, gdb_comm); 445254721Semaste } 446254721Semaste } 447254721Semaste else 448254721Semaste { 449254721Semaste // This is an actual register, write it 450254721Semaste success = SetPrimordialRegister(reg_info, gdb_comm); 451254721Semaste } 452254721Semaste 453254721Semaste // Check if writing this register will invalidate any other register values? 454254721Semaste // If so, invalidate them 455254721Semaste if (reg_info->invalidate_regs) 456254721Semaste { 457254721Semaste for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0]; 458254721Semaste reg != LLDB_INVALID_REGNUM; 459254721Semaste reg = reg_info->invalidate_regs[++idx]) 460254721Semaste { 461254721Semaste SetRegisterIsValid(reg, false); 462254721Semaste } 463254721Semaste } 464254721Semaste 465254721Semaste return success; 466254721Semaste } 467254721Semaste } 468254721Semaste } 469254721Semaste else 470254721Semaste { 471254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); 472254721Semaste if (log) 473254721Semaste { 474254721Semaste if (log->GetVerbose()) 475254721Semaste { 476254721Semaste StreamString strm; 477254721Semaste gdb_comm.DumpHistory(strm); 478254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\":\n%s", reg_info->name, strm.GetData()); 479254721Semaste } 480254721Semaste else 481254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\"", reg_info->name); 482254721Semaste } 483254721Semaste } 484254721Semaste } 485254721Semaste return false; 486254721Semaste} 487254721Semaste 488254721Semaste 489254721Semastebool 490254721SemasteGDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) 491254721Semaste{ 492254721Semaste ExecutionContext exe_ctx (CalculateThread()); 493254721Semaste 494254721Semaste Process *process = exe_ctx.GetProcessPtr(); 495254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 496254721Semaste if (process == NULL || thread == NULL) 497254721Semaste return false; 498254721Semaste 499254721Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 500254721Semaste 501254721Semaste StringExtractorGDBRemote response; 502254721Semaste 503254721Semaste Mutex::Locker locker; 504254721Semaste if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for read all registers.")) 505254721Semaste { 506254721Semaste SyncThreadState(process); 507254721Semaste 508254721Semaste char packet[32]; 509254721Semaste const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); 510254721Semaste ProcessSP process_sp (m_thread.GetProcess()); 511254721Semaste if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID())) 512254721Semaste { 513254721Semaste int packet_len = 0; 514254721Semaste if (thread_suffix_supported) 515254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetProtocolID()); 516254721Semaste else 517254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "g"); 518254721Semaste assert (packet_len < ((int)sizeof(packet) - 1)); 519254721Semaste 520254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false)) 521254721Semaste { 522254721Semaste if (response.IsErrorResponse()) 523254721Semaste return false; 524254721Semaste 525254721Semaste std::string &response_str = response.GetStringRef(); 526254721Semaste if (isxdigit(response_str[0])) 527254721Semaste { 528254721Semaste response_str.insert(0, 1, 'G'); 529254721Semaste if (thread_suffix_supported) 530254721Semaste { 531254721Semaste char thread_id_cstr[64]; 532254721Semaste ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 533254721Semaste response_str.append (thread_id_cstr); 534254721Semaste } 535254721Semaste data_sp.reset (new DataBufferHeap (response_str.c_str(), response_str.size())); 536254721Semaste return true; 537254721Semaste } 538254721Semaste } 539254721Semaste } 540254721Semaste } 541254721Semaste else 542254721Semaste { 543254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); 544254721Semaste if (log) 545254721Semaste { 546254721Semaste if (log->GetVerbose()) 547254721Semaste { 548254721Semaste StreamString strm; 549254721Semaste gdb_comm.DumpHistory(strm); 550254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending read all registers:\n%s", strm.GetData()); 551254721Semaste } 552254721Semaste else 553254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending read all registers"); 554254721Semaste } 555254721Semaste } 556254721Semaste 557254721Semaste data_sp.reset(); 558254721Semaste return false; 559254721Semaste} 560254721Semaste 561254721Semastebool 562254721SemasteGDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) 563254721Semaste{ 564254721Semaste if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0) 565254721Semaste return false; 566254721Semaste 567254721Semaste ExecutionContext exe_ctx (CalculateThread()); 568254721Semaste 569254721Semaste Process *process = exe_ctx.GetProcessPtr(); 570254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 571254721Semaste if (process == NULL || thread == NULL) 572254721Semaste return false; 573254721Semaste 574254721Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 575254721Semaste 576254721Semaste StringExtractorGDBRemote response; 577254721Semaste Mutex::Locker locker; 578254721Semaste if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write all registers.")) 579254721Semaste { 580254721Semaste const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); 581254721Semaste ProcessSP process_sp (m_thread.GetProcess()); 582254721Semaste if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID())) 583254721Semaste { 584254721Semaste // The data_sp contains the entire G response packet including the 585254721Semaste // G, and if the thread suffix is supported, it has the thread suffix 586254721Semaste // as well. 587254721Semaste const char *G_packet = (const char *)data_sp->GetBytes(); 588254721Semaste size_t G_packet_len = data_sp->GetByteSize(); 589254721Semaste if (gdb_comm.SendPacketAndWaitForResponse (G_packet, 590254721Semaste G_packet_len, 591254721Semaste response, 592254721Semaste false)) 593254721Semaste { 594254721Semaste if (response.IsOKResponse()) 595254721Semaste return true; 596254721Semaste else if (response.IsErrorResponse()) 597254721Semaste { 598254721Semaste uint32_t num_restored = 0; 599254721Semaste // We need to manually go through all of the registers and 600254721Semaste // restore them manually 601254721Semaste 602254721Semaste response.GetStringRef().assign (G_packet, G_packet_len); 603254721Semaste response.SetFilePos(1); // Skip the leading 'G' 604254721Semaste DataBufferHeap buffer (m_reg_data.GetByteSize(), 0); 605254721Semaste DataExtractor restore_data (buffer.GetBytes(), 606254721Semaste buffer.GetByteSize(), 607254721Semaste m_reg_data.GetByteOrder(), 608254721Semaste m_reg_data.GetAddressByteSize()); 609254721Semaste 610254721Semaste const uint32_t bytes_extracted = response.GetHexBytes ((void *)restore_data.GetDataStart(), 611254721Semaste restore_data.GetByteSize(), 612254721Semaste '\xcc'); 613254721Semaste 614254721Semaste if (bytes_extracted < restore_data.GetByteSize()) 615254721Semaste restore_data.SetData(restore_data.GetDataStart(), bytes_extracted, m_reg_data.GetByteOrder()); 616254721Semaste 617254721Semaste //ReadRegisterBytes (const RegisterInfo *reg_info, RegisterValue &value, DataExtractor &data) 618254721Semaste const RegisterInfo *reg_info; 619254721Semaste // We have to march the offset of each register along in the 620254721Semaste // buffer to make sure we get the right offset. 621254721Semaste uint32_t reg_byte_offset = 0; 622254721Semaste for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx, reg_byte_offset += reg_info->byte_size) 623254721Semaste { 624254721Semaste const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 625254721Semaste 626254721Semaste // Skip composite registers. 627254721Semaste if (reg_info->value_regs) 628254721Semaste continue; 629254721Semaste 630254721Semaste // Only write down the registers that need to be written 631254721Semaste // if we are going to be doing registers individually. 632254721Semaste bool write_reg = true; 633254721Semaste const uint32_t reg_byte_size = reg_info->byte_size; 634254721Semaste 635254721Semaste const char *restore_src = (const char *)restore_data.PeekData(reg_byte_offset, reg_byte_size); 636254721Semaste if (restore_src) 637254721Semaste { 638254721Semaste if (GetRegisterIsValid(reg)) 639254721Semaste { 640254721Semaste const char *current_src = (const char *)m_reg_data.PeekData(reg_byte_offset, reg_byte_size); 641254721Semaste if (current_src) 642254721Semaste write_reg = memcmp (current_src, restore_src, reg_byte_size) != 0; 643254721Semaste } 644254721Semaste 645254721Semaste if (write_reg) 646254721Semaste { 647254721Semaste StreamString packet; 648254721Semaste packet.Printf ("P%x=", reg); 649254721Semaste packet.PutBytesAsRawHex8 (restore_src, 650254721Semaste reg_byte_size, 651254721Semaste lldb::endian::InlHostByteOrder(), 652254721Semaste lldb::endian::InlHostByteOrder()); 653254721Semaste 654254721Semaste if (thread_suffix_supported) 655254721Semaste packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 656254721Semaste 657254721Semaste SetRegisterIsValid(reg, false); 658254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), 659254721Semaste packet.GetString().size(), 660254721Semaste response, 661254721Semaste false)) 662254721Semaste { 663254721Semaste if (response.IsOKResponse()) 664254721Semaste ++num_restored; 665254721Semaste } 666254721Semaste } 667254721Semaste } 668254721Semaste } 669254721Semaste return num_restored > 0; 670254721Semaste } 671254721Semaste } 672254721Semaste } 673254721Semaste } 674254721Semaste else 675254721Semaste { 676254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); 677254721Semaste if (log) 678254721Semaste { 679254721Semaste if (log->GetVerbose()) 680254721Semaste { 681254721Semaste StreamString strm; 682254721Semaste gdb_comm.DumpHistory(strm); 683254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending write all registers:\n%s", strm.GetData()); 684254721Semaste } 685254721Semaste else 686254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending write all registers"); 687254721Semaste } 688254721Semaste } 689254721Semaste return false; 690254721Semaste} 691254721Semaste 692254721Semaste 693254721Semasteuint32_t 694254721SemasteGDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num) 695254721Semaste{ 696254721Semaste return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num); 697254721Semaste} 698254721Semaste 699254721Semastevoid 700254721SemasteGDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) 701254721Semaste{ 702254721Semaste // For Advanced SIMD and VFP register mapping. 703254721Semaste static uint32_t g_d0_regs[] = { 26, 27, LLDB_INVALID_REGNUM }; // (s0, s1) 704254721Semaste static uint32_t g_d1_regs[] = { 28, 29, LLDB_INVALID_REGNUM }; // (s2, s3) 705254721Semaste static uint32_t g_d2_regs[] = { 30, 31, LLDB_INVALID_REGNUM }; // (s4, s5) 706254721Semaste static uint32_t g_d3_regs[] = { 32, 33, LLDB_INVALID_REGNUM }; // (s6, s7) 707254721Semaste static uint32_t g_d4_regs[] = { 34, 35, LLDB_INVALID_REGNUM }; // (s8, s9) 708254721Semaste static uint32_t g_d5_regs[] = { 36, 37, LLDB_INVALID_REGNUM }; // (s10, s11) 709254721Semaste static uint32_t g_d6_regs[] = { 38, 39, LLDB_INVALID_REGNUM }; // (s12, s13) 710254721Semaste static uint32_t g_d7_regs[] = { 40, 41, LLDB_INVALID_REGNUM }; // (s14, s15) 711254721Semaste static uint32_t g_d8_regs[] = { 42, 43, LLDB_INVALID_REGNUM }; // (s16, s17) 712254721Semaste static uint32_t g_d9_regs[] = { 44, 45, LLDB_INVALID_REGNUM }; // (s18, s19) 713254721Semaste static uint32_t g_d10_regs[] = { 46, 47, LLDB_INVALID_REGNUM }; // (s20, s21) 714254721Semaste static uint32_t g_d11_regs[] = { 48, 49, LLDB_INVALID_REGNUM }; // (s22, s23) 715254721Semaste static uint32_t g_d12_regs[] = { 50, 51, LLDB_INVALID_REGNUM }; // (s24, s25) 716254721Semaste static uint32_t g_d13_regs[] = { 52, 53, LLDB_INVALID_REGNUM }; // (s26, s27) 717254721Semaste static uint32_t g_d14_regs[] = { 54, 55, LLDB_INVALID_REGNUM }; // (s28, s29) 718254721Semaste static uint32_t g_d15_regs[] = { 56, 57, LLDB_INVALID_REGNUM }; // (s30, s31) 719254721Semaste static uint32_t g_q0_regs[] = { 26, 27, 28, 29, LLDB_INVALID_REGNUM }; // (d0, d1) -> (s0, s1, s2, s3) 720254721Semaste static uint32_t g_q1_regs[] = { 30, 31, 32, 33, LLDB_INVALID_REGNUM }; // (d2, d3) -> (s4, s5, s6, s7) 721254721Semaste static uint32_t g_q2_regs[] = { 34, 35, 36, 37, LLDB_INVALID_REGNUM }; // (d4, d5) -> (s8, s9, s10, s11) 722254721Semaste static uint32_t g_q3_regs[] = { 38, 39, 40, 41, LLDB_INVALID_REGNUM }; // (d6, d7) -> (s12, s13, s14, s15) 723254721Semaste static uint32_t g_q4_regs[] = { 42, 43, 44, 45, LLDB_INVALID_REGNUM }; // (d8, d9) -> (s16, s17, s18, s19) 724254721Semaste static uint32_t g_q5_regs[] = { 46, 47, 48, 49, LLDB_INVALID_REGNUM }; // (d10, d11) -> (s20, s21, s22, s23) 725254721Semaste static uint32_t g_q6_regs[] = { 50, 51, 52, 53, LLDB_INVALID_REGNUM }; // (d12, d13) -> (s24, s25, s26, s27) 726254721Semaste static uint32_t g_q7_regs[] = { 54, 55, 56, 57, LLDB_INVALID_REGNUM }; // (d14, d15) -> (s28, s29, s30, s31) 727254721Semaste static uint32_t g_q8_regs[] = { 59, 60, LLDB_INVALID_REGNUM }; // (d16, d17) 728254721Semaste static uint32_t g_q9_regs[] = { 61, 62, LLDB_INVALID_REGNUM }; // (d18, d19) 729254721Semaste static uint32_t g_q10_regs[] = { 63, 64, LLDB_INVALID_REGNUM }; // (d20, d21) 730254721Semaste static uint32_t g_q11_regs[] = { 65, 66, LLDB_INVALID_REGNUM }; // (d22, d23) 731254721Semaste static uint32_t g_q12_regs[] = { 67, 68, LLDB_INVALID_REGNUM }; // (d24, d25) 732254721Semaste static uint32_t g_q13_regs[] = { 69, 70, LLDB_INVALID_REGNUM }; // (d26, d27) 733254721Semaste static uint32_t g_q14_regs[] = { 71, 72, LLDB_INVALID_REGNUM }; // (d28, d29) 734254721Semaste static uint32_t g_q15_regs[] = { 73, 74, LLDB_INVALID_REGNUM }; // (d30, d31) 735254721Semaste 736254721Semaste // This is our array of composite registers, with each element coming from the above register mappings. 737254721Semaste static uint32_t *g_composites[] = { 738254721Semaste g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs, g_d6_regs, g_d7_regs, 739254721Semaste g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs, g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs, 740254721Semaste g_q0_regs, g_q1_regs, g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs, 741254721Semaste g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs, g_q14_regs, g_q15_regs 742254721Semaste }; 743254721Semaste 744254721Semaste static RegisterInfo g_register_infos[] = { 745254721Semaste// NAME ALT SZ OFF ENCODING FORMAT COMPILER DWARF GENERIC GDB LLDB VALUE REGS INVALIDATE REGS 746254721Semaste// ====== ====== === === ============= ============ =================== =================== ====================== === ==== ========== =============== 747254721Semaste { "r0", "arg1", 4, 0, eEncodingUint, eFormatHex, { gcc_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1,0, 0 }, NULL, NULL}, 748254721Semaste { "r1", "arg2", 4, 0, eEncodingUint, eFormatHex, { gcc_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2,1, 1 }, NULL, NULL}, 749254721Semaste { "r2", "arg3", 4, 0, eEncodingUint, eFormatHex, { gcc_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3,2, 2 }, NULL, NULL}, 750254721Semaste { "r3", "arg4", 4, 0, eEncodingUint, eFormatHex, { gcc_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4,3, 3 }, NULL, NULL}, 751254721Semaste { "r4", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }, NULL, NULL}, 752254721Semaste { "r5", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }, NULL, NULL}, 753254721Semaste { "r6", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }, NULL, NULL}, 754254721Semaste { "r7", "fp", 4, 0, eEncodingUint, eFormatHex, { gcc_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }, NULL, NULL}, 755254721Semaste { "r8", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }, NULL, NULL}, 756254721Semaste { "r9", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }, NULL, NULL}, 757254721Semaste { "r10", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }, NULL, NULL}, 758254721Semaste { "r11", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }, NULL, NULL}, 759254721Semaste { "r12", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }, NULL, NULL}, 760254721Semaste { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { gcc_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }, NULL, NULL}, 761254721Semaste { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { gcc_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }, NULL, NULL}, 762254721Semaste { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { gcc_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }, NULL, NULL}, 763254721Semaste { "f0", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }, NULL, NULL}, 764254721Semaste { "f1", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }, NULL, NULL}, 765254721Semaste { "f2", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }, NULL, NULL}, 766254721Semaste { "f3", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }, NULL, NULL}, 767254721Semaste { "f4", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }, NULL, NULL}, 768254721Semaste { "f5", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }, NULL, NULL}, 769254721Semaste { "f6", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }, NULL, NULL}, 770254721Semaste { "f7", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }, NULL, NULL}, 771254721Semaste { "fps", NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }, NULL, NULL}, 772254721Semaste { "cpsr","flags", 4, 0, eEncodingUint, eFormatHex, { gcc_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }, NULL, NULL}, 773254721Semaste { "s0", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }, NULL, NULL}, 774254721Semaste { "s1", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }, NULL, NULL}, 775254721Semaste { "s2", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }, NULL, NULL}, 776254721Semaste { "s3", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }, NULL, NULL}, 777254721Semaste { "s4", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }, NULL, NULL}, 778254721Semaste { "s5", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }, NULL, NULL}, 779254721Semaste { "s6", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }, NULL, NULL}, 780254721Semaste { "s7", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }, NULL, NULL}, 781254721Semaste { "s8", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }, NULL, NULL}, 782254721Semaste { "s9", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }, NULL, NULL}, 783254721Semaste { "s10", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }, NULL, NULL}, 784254721Semaste { "s11", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }, NULL, NULL}, 785254721Semaste { "s12", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }, NULL, NULL}, 786254721Semaste { "s13", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }, NULL, NULL}, 787254721Semaste { "s14", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }, NULL, NULL}, 788254721Semaste { "s15", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }, NULL, NULL}, 789254721Semaste { "s16", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }, NULL, NULL}, 790254721Semaste { "s17", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }, NULL, NULL}, 791254721Semaste { "s18", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }, NULL, NULL}, 792254721Semaste { "s19", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }, NULL, NULL}, 793254721Semaste { "s20", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }, NULL, NULL}, 794254721Semaste { "s21", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }, NULL, NULL}, 795254721Semaste { "s22", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }, NULL, NULL}, 796254721Semaste { "s23", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }, NULL, NULL}, 797254721Semaste { "s24", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }, NULL, NULL}, 798254721Semaste { "s25", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }, NULL, NULL}, 799254721Semaste { "s26", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }, NULL, NULL}, 800254721Semaste { "s27", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }, NULL, NULL}, 801254721Semaste { "s28", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }, NULL, NULL}, 802254721Semaste { "s29", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }, NULL, NULL}, 803254721Semaste { "s30", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }, NULL, NULL}, 804254721Semaste { "s31", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }, NULL, NULL}, 805254721Semaste { "fpscr",NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }, NULL, NULL}, 806254721Semaste { "d16", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }, NULL, NULL}, 807254721Semaste { "d17", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }, NULL, NULL}, 808254721Semaste { "d18", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }, NULL, NULL}, 809254721Semaste { "d19", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }, NULL, NULL}, 810254721Semaste { "d20", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }, NULL, NULL}, 811254721Semaste { "d21", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }, NULL, NULL}, 812254721Semaste { "d22", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }, NULL, NULL}, 813254721Semaste { "d23", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }, NULL, NULL}, 814254721Semaste { "d24", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }, NULL, NULL}, 815254721Semaste { "d25", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }, NULL, NULL}, 816254721Semaste { "d26", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }, NULL, NULL}, 817254721Semaste { "d27", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }, NULL, NULL}, 818254721Semaste { "d28", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }, NULL, NULL}, 819254721Semaste { "d29", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }, NULL, NULL}, 820254721Semaste { "d30", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }, NULL, NULL}, 821254721Semaste { "d31", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }, NULL, NULL}, 822254721Semaste { "d0", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, 75, 75 }, g_d0_regs, NULL}, 823254721Semaste { "d1", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, 76, 76 }, g_d1_regs, NULL}, 824254721Semaste { "d2", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, 77, 77 }, g_d2_regs, NULL}, 825254721Semaste { "d3", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, 78, 78 }, g_d3_regs, NULL}, 826254721Semaste { "d4", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, 79, 79 }, g_d4_regs, NULL}, 827254721Semaste { "d5", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, 80, 80 }, g_d5_regs, NULL}, 828254721Semaste { "d6", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, 81, 81 }, g_d6_regs, NULL}, 829254721Semaste { "d7", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, 82, 82 }, g_d7_regs, NULL}, 830254721Semaste { "d8", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, 83, 83 }, g_d8_regs, NULL}, 831254721Semaste { "d9", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, 84, 84 }, g_d9_regs, NULL}, 832254721Semaste { "d10", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, 85, 85 }, g_d10_regs, NULL}, 833254721Semaste { "d11", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, 86, 86 }, g_d11_regs, NULL}, 834254721Semaste { "d12", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, 87, 87 }, g_d12_regs, NULL}, 835254721Semaste { "d13", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, 88, 88 }, g_d13_regs, NULL}, 836254721Semaste { "d14", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, 89, 89 }, g_d14_regs, NULL}, 837254721Semaste { "d15", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, 90, 90 }, g_d15_regs, NULL}, 838254721Semaste { "q0", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, 91, 91 }, g_q0_regs, NULL}, 839254721Semaste { "q1", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, 92, 92 }, g_q1_regs, NULL}, 840254721Semaste { "q2", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, 93, 93 }, g_q2_regs, NULL}, 841254721Semaste { "q3", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, 94, 94 }, g_q3_regs, NULL}, 842254721Semaste { "q4", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, 95, 95 }, g_q4_regs, NULL}, 843254721Semaste { "q5", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, 96, 96 }, g_q5_regs, NULL}, 844254721Semaste { "q6", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, 97, 97 }, g_q6_regs, NULL}, 845254721Semaste { "q7", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, 98, 98 }, g_q7_regs, NULL}, 846254721Semaste { "q8", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, 99, 99 }, g_q8_regs, NULL}, 847254721Semaste { "q9", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, 100, 100 }, g_q9_regs, NULL}, 848254721Semaste { "q10", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, 101, 101 }, g_q10_regs, NULL}, 849254721Semaste { "q11", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, 102, 102 }, g_q11_regs, NULL}, 850254721Semaste { "q12", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, 103, 103 }, g_q12_regs, NULL}, 851254721Semaste { "q13", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, 104, 104 }, g_q13_regs, NULL}, 852254721Semaste { "q14", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, NULL}, 853254721Semaste { "q15", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, NULL} 854254721Semaste }; 855254721Semaste 856254721Semaste static const uint32_t num_registers = llvm::array_lengthof(g_register_infos); 857254721Semaste static ConstString gpr_reg_set ("General Purpose Registers"); 858254721Semaste static ConstString sfp_reg_set ("Software Floating Point Registers"); 859254721Semaste static ConstString vfp_reg_set ("Floating Point Registers"); 860254721Semaste size_t i; 861254721Semaste if (from_scratch) 862254721Semaste { 863254721Semaste // Calculate the offsets of the registers 864254721Semaste // Note that the layout of the "composite" registers (d0-d15 and q0-q15) which comes after the 865254721Semaste // "primordial" registers is important. This enables us to calculate the offset of the composite 866254721Semaste // register by using the offset of its first primordial register. For example, to calculate the 867254721Semaste // offset of q0, use s0's offset. 868254721Semaste if (g_register_infos[2].byte_offset == 0) 869254721Semaste { 870254721Semaste uint32_t byte_offset = 0; 871254721Semaste for (i=0; i<num_registers; ++i) 872254721Semaste { 873254721Semaste // For primordial registers, increment the byte_offset by the byte_size to arrive at the 874254721Semaste // byte_offset for the next register. Otherwise, we have a composite register whose 875254721Semaste // offset can be calculated by consulting the offset of its first primordial register. 876254721Semaste if (!g_register_infos[i].value_regs) 877254721Semaste { 878254721Semaste g_register_infos[i].byte_offset = byte_offset; 879254721Semaste byte_offset += g_register_infos[i].byte_size; 880254721Semaste } 881254721Semaste else 882254721Semaste { 883254721Semaste const uint32_t first_primordial_reg = g_register_infos[i].value_regs[0]; 884254721Semaste g_register_infos[i].byte_offset = g_register_infos[first_primordial_reg].byte_offset; 885254721Semaste } 886254721Semaste } 887254721Semaste } 888254721Semaste for (i=0; i<num_registers; ++i) 889254721Semaste { 890254721Semaste ConstString name; 891254721Semaste ConstString alt_name; 892254721Semaste if (g_register_infos[i].name && g_register_infos[i].name[0]) 893254721Semaste name.SetCString(g_register_infos[i].name); 894254721Semaste if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0]) 895254721Semaste alt_name.SetCString(g_register_infos[i].alt_name); 896254721Semaste 897254721Semaste if (i <= 15 || i == 25) 898254721Semaste AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set); 899254721Semaste else if (i <= 24) 900254721Semaste AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set); 901254721Semaste else 902254721Semaste AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set); 903254721Semaste } 904254721Semaste } 905254721Semaste else 906254721Semaste { 907254721Semaste // Add composite registers to our primordial registers, then. 908254721Semaste const size_t num_composites = llvm::array_lengthof(g_composites); 909254721Semaste const size_t num_dynamic_regs = GetNumRegisters(); 910254721Semaste const size_t num_common_regs = num_registers - num_composites; 911254721Semaste RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs; 912254721Semaste 913254721Semaste // First we need to validate that all registers that we already have match the non composite regs. 914254721Semaste // If so, then we can add the registers, else we need to bail 915254721Semaste bool match = true; 916254721Semaste if (num_dynamic_regs == num_common_regs) 917254721Semaste { 918254721Semaste for (i=0; match && i<num_dynamic_regs; ++i) 919254721Semaste { 920254721Semaste // Make sure all register names match 921254721Semaste if (m_regs[i].name && g_register_infos[i].name) 922254721Semaste { 923254721Semaste if (strcmp(m_regs[i].name, g_register_infos[i].name)) 924254721Semaste { 925254721Semaste match = false; 926254721Semaste break; 927254721Semaste } 928254721Semaste } 929254721Semaste 930254721Semaste // Make sure all register byte sizes match 931254721Semaste if (m_regs[i].byte_size != g_register_infos[i].byte_size) 932254721Semaste { 933254721Semaste match = false; 934254721Semaste break; 935254721Semaste } 936254721Semaste } 937254721Semaste } 938254721Semaste else 939254721Semaste { 940254721Semaste // Wrong number of registers. 941254721Semaste match = false; 942254721Semaste } 943254721Semaste // If "match" is true, then we can add extra registers. 944254721Semaste if (match) 945254721Semaste { 946254721Semaste for (i=0; i<num_composites; ++i) 947254721Semaste { 948254721Semaste ConstString name; 949254721Semaste ConstString alt_name; 950254721Semaste const uint32_t first_primordial_reg = g_comp_register_infos[i].value_regs[0]; 951254721Semaste const char *reg_name = g_register_infos[first_primordial_reg].name; 952254721Semaste if (reg_name && reg_name[0]) 953254721Semaste { 954254721Semaste for (uint32_t j = 0; j < num_dynamic_regs; ++j) 955254721Semaste { 956254721Semaste const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j); 957254721Semaste // Find a matching primordial register info entry. 958254721Semaste if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, reg_name) == 0) 959254721Semaste { 960254721Semaste // The name matches the existing primordial entry. 961254721Semaste // Find and assign the offset, and then add this composite register entry. 962254721Semaste g_comp_register_infos[i].byte_offset = reg_info->byte_offset; 963254721Semaste name.SetCString(g_comp_register_infos[i].name); 964254721Semaste AddRegister(g_comp_register_infos[i], name, alt_name, vfp_reg_set); 965254721Semaste } 966254721Semaste } 967254721Semaste } 968254721Semaste } 969254721Semaste } 970254721Semaste } 971254721Semaste} 972