GDBRemoteRegisterContext.cpp revision 276479
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" 20258054Semaste#ifndef LLDB_DISABLE_PYTHON 21258054Semaste#include "lldb/Interpreter/PythonDataObjects.h" 22258054Semaste#endif 23254721Semaste#include "lldb/Target/ExecutionContext.h" 24276479Sdim#include "lldb/Target/Target.h" 25254721Semaste#include "lldb/Utility/Utils.h" 26254721Semaste// Project includes 27254721Semaste#include "Utility/StringExtractorGDBRemote.h" 28254721Semaste#include "ProcessGDBRemote.h" 29254721Semaste#include "ProcessGDBRemoteLog.h" 30254721Semaste#include "ThreadGDBRemote.h" 31254721Semaste#include "Utility/ARM_GCC_Registers.h" 32254721Semaste#include "Utility/ARM_DWARF_Registers.h" 33254721Semaste 34254721Semasteusing namespace lldb; 35254721Semasteusing namespace lldb_private; 36254721Semaste 37254721Semaste//---------------------------------------------------------------------- 38254721Semaste// GDBRemoteRegisterContext constructor 39254721Semaste//---------------------------------------------------------------------- 40254721SemasteGDBRemoteRegisterContext::GDBRemoteRegisterContext 41254721Semaste( 42254721Semaste ThreadGDBRemote &thread, 43254721Semaste uint32_t concrete_frame_idx, 44254721Semaste GDBRemoteDynamicRegisterInfo ®_info, 45254721Semaste bool read_all_at_once 46254721Semaste) : 47254721Semaste RegisterContext (thread, concrete_frame_idx), 48254721Semaste m_reg_info (reg_info), 49254721Semaste m_reg_valid (), 50254721Semaste m_reg_data (), 51254721Semaste m_read_all_at_once (read_all_at_once) 52254721Semaste{ 53254721Semaste // Resize our vector of bools to contain one bool for every register. 54254721Semaste // We will use these boolean values to know when a register value 55254721Semaste // is valid in m_reg_data. 56254721Semaste m_reg_valid.resize (reg_info.GetNumRegisters()); 57254721Semaste 58254721Semaste // Make a heap based buffer that is big enough to store all registers 59254721Semaste DataBufferSP reg_data_sp(new DataBufferHeap (reg_info.GetRegisterDataByteSize(), 0)); 60254721Semaste m_reg_data.SetData (reg_data_sp); 61258054Semaste m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder()); 62254721Semaste} 63254721Semaste 64254721Semaste//---------------------------------------------------------------------- 65254721Semaste// Destructor 66254721Semaste//---------------------------------------------------------------------- 67254721SemasteGDBRemoteRegisterContext::~GDBRemoteRegisterContext() 68254721Semaste{ 69254721Semaste} 70254721Semaste 71254721Semastevoid 72254721SemasteGDBRemoteRegisterContext::InvalidateAllRegisters () 73254721Semaste{ 74254721Semaste SetAllRegisterValid (false); 75254721Semaste} 76254721Semaste 77254721Semastevoid 78254721SemasteGDBRemoteRegisterContext::SetAllRegisterValid (bool b) 79254721Semaste{ 80254721Semaste std::vector<bool>::iterator pos, end = m_reg_valid.end(); 81254721Semaste for (pos = m_reg_valid.begin(); pos != end; ++pos) 82254721Semaste *pos = b; 83254721Semaste} 84254721Semaste 85254721Semastesize_t 86254721SemasteGDBRemoteRegisterContext::GetRegisterCount () 87254721Semaste{ 88254721Semaste return m_reg_info.GetNumRegisters (); 89254721Semaste} 90254721Semaste 91254721Semasteconst RegisterInfo * 92254721SemasteGDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg) 93254721Semaste{ 94254721Semaste return m_reg_info.GetRegisterInfoAtIndex (reg); 95254721Semaste} 96254721Semaste 97254721Semastesize_t 98254721SemasteGDBRemoteRegisterContext::GetRegisterSetCount () 99254721Semaste{ 100254721Semaste return m_reg_info.GetNumRegisterSets (); 101254721Semaste} 102254721Semaste 103254721Semaste 104254721Semaste 105254721Semasteconst RegisterSet * 106254721SemasteGDBRemoteRegisterContext::GetRegisterSet (size_t reg_set) 107254721Semaste{ 108254721Semaste return m_reg_info.GetRegisterSet (reg_set); 109254721Semaste} 110254721Semaste 111254721Semaste 112254721Semaste 113254721Semastebool 114254721SemasteGDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) 115254721Semaste{ 116254721Semaste // Read the register 117254721Semaste if (ReadRegisterBytes (reg_info, m_reg_data)) 118254721Semaste { 119254721Semaste const bool partial_data_ok = false; 120254721Semaste Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok)); 121254721Semaste return error.Success(); 122254721Semaste } 123254721Semaste return false; 124254721Semaste} 125254721Semaste 126254721Semastebool 127254721SemasteGDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor &response) 128254721Semaste{ 129254721Semaste const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); 130254721Semaste if (reg_info == NULL) 131254721Semaste return false; 132254721Semaste 133254721Semaste // Invalidate if needed 134254721Semaste InvalidateIfNeeded(false); 135254721Semaste 136254721Semaste const uint32_t reg_byte_size = reg_info->byte_size; 137254721Semaste 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'); 138254721Semaste bool success = bytes_copied == reg_byte_size; 139254721Semaste if (success) 140254721Semaste { 141254721Semaste SetRegisterIsValid(reg, true); 142254721Semaste } 143254721Semaste else if (bytes_copied > 0) 144254721Semaste { 145254721Semaste // Only set register is valid to false if we copied some bytes, else 146254721Semaste // leave it as it was. 147254721Semaste SetRegisterIsValid(reg, false); 148254721Semaste } 149254721Semaste return success; 150254721Semaste} 151254721Semaste 152254721Semaste// Helper function for GDBRemoteRegisterContext::ReadRegisterBytes(). 153254721Semastebool 154254721SemasteGDBRemoteRegisterContext::GetPrimordialRegister(const lldb_private::RegisterInfo *reg_info, 155254721Semaste GDBRemoteCommunicationClient &gdb_comm) 156254721Semaste{ 157258884Semaste const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 158254721Semaste StringExtractorGDBRemote response; 159258884Semaste if (gdb_comm.ReadRegister(m_thread.GetProtocolID(), reg, response)) 160254721Semaste return PrivateSetRegisterValue (reg, response); 161254721Semaste return false; 162254721Semaste} 163258884Semaste 164254721Semastebool 165254721SemasteGDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data) 166254721Semaste{ 167254721Semaste ExecutionContext exe_ctx (CalculateThread()); 168254721Semaste 169254721Semaste Process *process = exe_ctx.GetProcessPtr(); 170254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 171254721Semaste if (process == NULL || thread == NULL) 172254721Semaste return false; 173254721Semaste 174254721Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 175254721Semaste 176254721Semaste InvalidateIfNeeded(false); 177254721Semaste 178254721Semaste const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 179254721Semaste 180254721Semaste if (!GetRegisterIsValid(reg)) 181254721Semaste { 182258884Semaste if (m_read_all_at_once) 183254721Semaste { 184258884Semaste StringExtractorGDBRemote response; 185258884Semaste if (!gdb_comm.ReadAllRegisters(m_thread.GetProtocolID(), response)) 186258884Semaste return false; 187258884Semaste if (response.IsNormalResponse()) 188258884Semaste if (response.GetHexBytes ((void *)m_reg_data.GetDataStart(), m_reg_data.GetByteSize(), '\xcc') == m_reg_data.GetByteSize()) 189258884Semaste SetAllRegisterValid (true); 190258884Semaste } 191258884Semaste else if (reg_info->value_regs) 192258884Semaste { 193258884Semaste // Process this composite register request by delegating to the constituent 194258884Semaste // primordial registers. 195258884Semaste 196258884Semaste // Index of the primordial register. 197258884Semaste bool success = true; 198258884Semaste for (uint32_t idx = 0; success; ++idx) 199254721Semaste { 200258884Semaste const uint32_t prim_reg = reg_info->value_regs[idx]; 201258884Semaste if (prim_reg == LLDB_INVALID_REGNUM) 202258884Semaste break; 203276479Sdim // We have a valid primordial register as our constituent. 204258884Semaste // Grab the corresponding register info. 205258884Semaste const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg); 206258884Semaste if (prim_reg_info == NULL) 207258884Semaste success = false; 208254721Semaste else 209254721Semaste { 210258884Semaste // Read the containing register if it hasn't already been read 211258884Semaste if (!GetRegisterIsValid(prim_reg)) 212258884Semaste success = GetPrimordialRegister(prim_reg_info, gdb_comm); 213254721Semaste } 214254721Semaste } 215258884Semaste 216258884Semaste if (success) 217258884Semaste { 218258884Semaste // If we reach this point, all primordial register requests have succeeded. 219258884Semaste // Validate this composite register. 220258884Semaste SetRegisterIsValid (reg_info, true); 221258884Semaste } 222254721Semaste } 223254721Semaste else 224254721Semaste { 225258884Semaste // Get each register individually 226258884Semaste GetPrimordialRegister(reg_info, gdb_comm); 227254721Semaste } 228254721Semaste 229254721Semaste // Make sure we got a valid register value after reading it 230254721Semaste if (!GetRegisterIsValid(reg)) 231254721Semaste return false; 232254721Semaste } 233254721Semaste 234254721Semaste if (&data != &m_reg_data) 235254721Semaste { 236276479Sdim#if defined (LLDB_CONFIGURATION_DEBUG) 237276479Sdim assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size); 238276479Sdim#endif 239276479Sdim // If our register context and our register info disagree, which should never happen, don't 240276479Sdim // read past the end of the buffer. 241276479Sdim if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) 242276479Sdim return false; 243276479Sdim 244254721Semaste // If we aren't extracting into our own buffer (which 245254721Semaste // only happens when this function is called from 246254721Semaste // ReadRegisterValue(uint32_t, Scalar&)) then 247254721Semaste // we transfer bytes from our buffer into the data 248254721Semaste // buffer that was passed in 249276479Sdim 250254721Semaste data.SetByteOrder (m_reg_data.GetByteOrder()); 251254721Semaste data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size); 252254721Semaste } 253254721Semaste return true; 254254721Semaste} 255254721Semaste 256254721Semastebool 257254721SemasteGDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info, 258254721Semaste const RegisterValue &value) 259254721Semaste{ 260254721Semaste DataExtractor data; 261254721Semaste if (value.GetData (data)) 262254721Semaste return WriteRegisterBytes (reg_info, data, 0); 263254721Semaste return false; 264254721Semaste} 265254721Semaste 266254721Semaste// Helper function for GDBRemoteRegisterContext::WriteRegisterBytes(). 267254721Semastebool 268254721SemasteGDBRemoteRegisterContext::SetPrimordialRegister(const lldb_private::RegisterInfo *reg_info, 269254721Semaste GDBRemoteCommunicationClient &gdb_comm) 270254721Semaste{ 271254721Semaste StreamString packet; 272254721Semaste StringExtractorGDBRemote response; 273254721Semaste const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 274254721Semaste packet.Printf ("P%x=", reg); 275254721Semaste packet.PutBytesAsRawHex8 (m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size), 276254721Semaste reg_info->byte_size, 277254721Semaste lldb::endian::InlHostByteOrder(), 278254721Semaste lldb::endian::InlHostByteOrder()); 279254721Semaste 280254721Semaste if (gdb_comm.GetThreadSuffixSupported()) 281254721Semaste packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 282254721Semaste 283254721Semaste // Invalidate just this register 284254721Semaste SetRegisterIsValid(reg, false); 285254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), 286254721Semaste packet.GetString().size(), 287254721Semaste response, 288262528Semaste false) == GDBRemoteCommunication::PacketResult::Success) 289254721Semaste { 290254721Semaste if (response.IsOKResponse()) 291254721Semaste return true; 292254721Semaste } 293254721Semaste return false; 294254721Semaste} 295254721Semaste 296254721Semastevoid 297254721SemasteGDBRemoteRegisterContext::SyncThreadState(Process *process) 298254721Semaste{ 299254721Semaste // NB. We assume our caller has locked the sequence mutex. 300254721Semaste 301254721Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *) process)->GetGDBRemote()); 302254721Semaste if (!gdb_comm.GetSyncThreadStateSupported()) 303254721Semaste return; 304254721Semaste 305254721Semaste StreamString packet; 306254721Semaste StringExtractorGDBRemote response; 307254721Semaste packet.Printf ("QSyncThreadState:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 308254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), 309254721Semaste packet.GetString().size(), 310254721Semaste response, 311262528Semaste false) == GDBRemoteCommunication::PacketResult::Success) 312254721Semaste { 313254721Semaste if (response.IsOKResponse()) 314254721Semaste InvalidateAllRegisters(); 315254721Semaste } 316254721Semaste} 317254721Semaste 318254721Semastebool 319254721SemasteGDBRemoteRegisterContext::WriteRegisterBytes (const lldb_private::RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset) 320254721Semaste{ 321254721Semaste ExecutionContext exe_ctx (CalculateThread()); 322254721Semaste 323254721Semaste Process *process = exe_ctx.GetProcessPtr(); 324254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 325254721Semaste if (process == NULL || thread == NULL) 326254721Semaste return false; 327254721Semaste 328254721Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 329254721Semaste// FIXME: This check isn't right because IsRunning checks the Public state, but this 330254721Semaste// is work you need to do - for instance in ShouldStop & friends - before the public 331254721Semaste// state has been changed. 332254721Semaste// if (gdb_comm.IsRunning()) 333254721Semaste// return false; 334254721Semaste 335276479Sdim 336276479Sdim#if defined (LLDB_CONFIGURATION_DEBUG) 337276479Sdim assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size); 338276479Sdim#endif 339276479Sdim 340276479Sdim // If our register context and our register info disagree, which should never happen, don't 341276479Sdim // overwrite past the end of the buffer. 342276479Sdim if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) 343276479Sdim return false; 344276479Sdim 345254721Semaste // Grab a pointer to where we are going to put this register 346254721Semaste uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); 347254721Semaste 348254721Semaste if (dst == NULL) 349254721Semaste return false; 350254721Semaste 351254721Semaste 352254721Semaste if (data.CopyByteOrderedData (data_offset, // src offset 353254721Semaste reg_info->byte_size, // src length 354254721Semaste dst, // dst 355254721Semaste reg_info->byte_size, // dst length 356254721Semaste m_reg_data.GetByteOrder())) // dst byte order 357254721Semaste { 358254721Semaste Mutex::Locker locker; 359254721Semaste if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write register.")) 360254721Semaste { 361254721Semaste const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); 362254721Semaste ProcessSP process_sp (m_thread.GetProcess()); 363254721Semaste if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID())) 364254721Semaste { 365254721Semaste StreamString packet; 366254721Semaste StringExtractorGDBRemote response; 367254721Semaste 368254721Semaste if (m_read_all_at_once) 369254721Semaste { 370254721Semaste // Set all registers in one packet 371254721Semaste packet.PutChar ('G'); 372254721Semaste packet.PutBytesAsRawHex8 (m_reg_data.GetDataStart(), 373254721Semaste m_reg_data.GetByteSize(), 374254721Semaste lldb::endian::InlHostByteOrder(), 375254721Semaste lldb::endian::InlHostByteOrder()); 376254721Semaste 377254721Semaste if (thread_suffix_supported) 378254721Semaste packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 379254721Semaste 380254721Semaste // Invalidate all register values 381254721Semaste InvalidateIfNeeded (true); 382254721Semaste 383254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), 384254721Semaste packet.GetString().size(), 385254721Semaste response, 386262528Semaste false) == GDBRemoteCommunication::PacketResult::Success) 387254721Semaste { 388254721Semaste SetAllRegisterValid (false); 389254721Semaste if (response.IsOKResponse()) 390254721Semaste { 391254721Semaste return true; 392254721Semaste } 393254721Semaste } 394254721Semaste } 395254721Semaste else 396254721Semaste { 397254721Semaste bool success = true; 398254721Semaste 399254721Semaste if (reg_info->value_regs) 400254721Semaste { 401254721Semaste // This register is part of another register. In this case we read the actual 402254721Semaste // register data for any "value_regs", and once all that data is read, we will 403254721Semaste // have enough data in our register context bytes for the value of this register 404254721Semaste 405254721Semaste // Invalidate this composite register first. 406254721Semaste 407254721Semaste for (uint32_t idx = 0; success; ++idx) 408254721Semaste { 409254721Semaste const uint32_t reg = reg_info->value_regs[idx]; 410254721Semaste if (reg == LLDB_INVALID_REGNUM) 411254721Semaste break; 412276479Sdim // We have a valid primordial register as our constituent. 413254721Semaste // Grab the corresponding register info. 414254721Semaste const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg); 415254721Semaste if (value_reg_info == NULL) 416254721Semaste success = false; 417254721Semaste else 418254721Semaste success = SetPrimordialRegister(value_reg_info, gdb_comm); 419254721Semaste } 420254721Semaste } 421254721Semaste else 422254721Semaste { 423254721Semaste // This is an actual register, write it 424254721Semaste success = SetPrimordialRegister(reg_info, gdb_comm); 425254721Semaste } 426254721Semaste 427254721Semaste // Check if writing this register will invalidate any other register values? 428254721Semaste // If so, invalidate them 429254721Semaste if (reg_info->invalidate_regs) 430254721Semaste { 431254721Semaste for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0]; 432254721Semaste reg != LLDB_INVALID_REGNUM; 433254721Semaste reg = reg_info->invalidate_regs[++idx]) 434254721Semaste { 435254721Semaste SetRegisterIsValid(reg, false); 436254721Semaste } 437254721Semaste } 438254721Semaste 439254721Semaste return success; 440254721Semaste } 441254721Semaste } 442254721Semaste } 443254721Semaste else 444254721Semaste { 445254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); 446254721Semaste if (log) 447254721Semaste { 448254721Semaste if (log->GetVerbose()) 449254721Semaste { 450254721Semaste StreamString strm; 451254721Semaste gdb_comm.DumpHistory(strm); 452254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\":\n%s", reg_info->name, strm.GetData()); 453254721Semaste } 454254721Semaste else 455254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\"", reg_info->name); 456254721Semaste } 457254721Semaste } 458254721Semaste } 459254721Semaste return false; 460254721Semaste} 461254721Semaste 462258884Semastebool 463258884SemasteGDBRemoteRegisterContext::ReadAllRegisterValues (lldb_private::RegisterCheckpoint ®_checkpoint) 464258884Semaste{ 465258884Semaste ExecutionContext exe_ctx (CalculateThread()); 466258884Semaste 467258884Semaste Process *process = exe_ctx.GetProcessPtr(); 468258884Semaste Thread *thread = exe_ctx.GetThreadPtr(); 469258884Semaste if (process == NULL || thread == NULL) 470258884Semaste return false; 471258884Semaste 472258884Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 473254721Semaste 474258884Semaste uint32_t save_id = 0; 475258884Semaste if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) 476258884Semaste { 477258884Semaste reg_checkpoint.SetID(save_id); 478258884Semaste reg_checkpoint.GetData().reset(); 479258884Semaste return true; 480258884Semaste } 481258884Semaste else 482258884Semaste { 483258884Semaste reg_checkpoint.SetID(0); // Invalid save ID is zero 484258884Semaste return ReadAllRegisterValues(reg_checkpoint.GetData()); 485258884Semaste } 486258884Semaste} 487258884Semaste 488254721Semastebool 489258884SemasteGDBRemoteRegisterContext::WriteAllRegisterValues (const lldb_private::RegisterCheckpoint ®_checkpoint) 490258884Semaste{ 491258884Semaste uint32_t save_id = reg_checkpoint.GetID(); 492258884Semaste if (save_id != 0) 493258884Semaste { 494258884Semaste ExecutionContext exe_ctx (CalculateThread()); 495258884Semaste 496258884Semaste Process *process = exe_ctx.GetProcessPtr(); 497258884Semaste Thread *thread = exe_ctx.GetThreadPtr(); 498258884Semaste if (process == NULL || thread == NULL) 499258884Semaste return false; 500258884Semaste 501258884Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 502258884Semaste 503258884Semaste return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id); 504258884Semaste } 505258884Semaste else 506258884Semaste { 507258884Semaste return WriteAllRegisterValues(reg_checkpoint.GetData()); 508258884Semaste } 509258884Semaste} 510258884Semaste 511258884Semastebool 512254721SemasteGDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) 513254721Semaste{ 514254721Semaste ExecutionContext exe_ctx (CalculateThread()); 515254721Semaste 516254721Semaste Process *process = exe_ctx.GetProcessPtr(); 517254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 518254721Semaste if (process == NULL || thread == NULL) 519254721Semaste return false; 520254721Semaste 521254721Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 522254721Semaste 523254721Semaste StringExtractorGDBRemote response; 524254721Semaste 525276479Sdim const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false; 526276479Sdim 527254721Semaste Mutex::Locker locker; 528254721Semaste if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for read all registers.")) 529254721Semaste { 530254721Semaste SyncThreadState(process); 531254721Semaste 532254721Semaste char packet[32]; 533254721Semaste const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); 534254721Semaste ProcessSP process_sp (m_thread.GetProcess()); 535254721Semaste if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID())) 536254721Semaste { 537254721Semaste int packet_len = 0; 538254721Semaste if (thread_suffix_supported) 539254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetProtocolID()); 540254721Semaste else 541254721Semaste packet_len = ::snprintf (packet, sizeof(packet), "g"); 542254721Semaste assert (packet_len < ((int)sizeof(packet) - 1)); 543254721Semaste 544276479Sdim if (use_g_packet && gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success) 545254721Semaste { 546276479Sdim int packet_len = 0; 547276479Sdim if (thread_suffix_supported) 548276479Sdim packet_len = ::snprintf (packet, sizeof(packet), "g;thread:%4.4" PRIx64, m_thread.GetProtocolID()); 549276479Sdim else 550276479Sdim packet_len = ::snprintf (packet, sizeof(packet), "g"); 551276479Sdim assert (packet_len < ((int)sizeof(packet) - 1)); 552276479Sdim 553276479Sdim if (gdb_comm.SendPacketAndWaitForResponse(packet, packet_len, response, false) == GDBRemoteCommunication::PacketResult::Success) 554254721Semaste { 555276479Sdim if (response.IsErrorResponse()) 556276479Sdim return false; 557276479Sdim 558276479Sdim std::string &response_str = response.GetStringRef(); 559276479Sdim if (isxdigit(response_str[0])) 560254721Semaste { 561276479Sdim response_str.insert(0, 1, 'G'); 562276479Sdim if (thread_suffix_supported) 563276479Sdim { 564276479Sdim char thread_id_cstr[64]; 565276479Sdim ::snprintf (thread_id_cstr, sizeof(thread_id_cstr), ";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 566276479Sdim response_str.append (thread_id_cstr); 567276479Sdim } 568276479Sdim data_sp.reset (new DataBufferHeap (response_str.c_str(), response_str.size())); 569276479Sdim return true; 570254721Semaste } 571254721Semaste } 572254721Semaste } 573276479Sdim else 574276479Sdim { 575276479Sdim // For the use_g_packet == false case, we're going to read each register 576276479Sdim // individually and store them as binary data in a buffer instead of as ascii 577276479Sdim // characters. 578276479Sdim const RegisterInfo *reg_info; 579276479Sdim 580276479Sdim // data_sp will take ownership of this DataBufferHeap pointer soon. 581276479Sdim DataBufferSP reg_ctx(new DataBufferHeap(m_reg_info.GetRegisterDataByteSize(), 0)); 582276479Sdim 583276479Sdim for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex (i)) != NULL; i++) 584276479Sdim { 585276479Sdim if (reg_info->value_regs) // skip registers that are slices of real registers 586276479Sdim continue; 587276479Sdim ReadRegisterBytes (reg_info, m_reg_data); 588276479Sdim // ReadRegisterBytes saves the contents of the register in to the m_reg_data buffer 589276479Sdim } 590276479Sdim memcpy (reg_ctx->GetBytes(), m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize()); 591276479Sdim 592276479Sdim data_sp = reg_ctx; 593276479Sdim return true; 594276479Sdim } 595254721Semaste } 596254721Semaste } 597254721Semaste else 598254721Semaste { 599276479Sdim 600254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); 601254721Semaste if (log) 602254721Semaste { 603254721Semaste if (log->GetVerbose()) 604254721Semaste { 605254721Semaste StreamString strm; 606254721Semaste gdb_comm.DumpHistory(strm); 607254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending read all registers:\n%s", strm.GetData()); 608254721Semaste } 609254721Semaste else 610254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending read all registers"); 611254721Semaste } 612254721Semaste } 613254721Semaste 614254721Semaste data_sp.reset(); 615254721Semaste return false; 616254721Semaste} 617254721Semaste 618254721Semastebool 619254721SemasteGDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) 620254721Semaste{ 621254721Semaste if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0) 622254721Semaste return false; 623254721Semaste 624254721Semaste ExecutionContext exe_ctx (CalculateThread()); 625254721Semaste 626254721Semaste Process *process = exe_ctx.GetProcessPtr(); 627254721Semaste Thread *thread = exe_ctx.GetThreadPtr(); 628254721Semaste if (process == NULL || thread == NULL) 629254721Semaste return false; 630254721Semaste 631254721Semaste GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); 632254721Semaste 633276479Sdim const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false; 634276479Sdim 635254721Semaste StringExtractorGDBRemote response; 636254721Semaste Mutex::Locker locker; 637254721Semaste if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for write all registers.")) 638254721Semaste { 639254721Semaste const bool thread_suffix_supported = gdb_comm.GetThreadSuffixSupported(); 640254721Semaste ProcessSP process_sp (m_thread.GetProcess()); 641254721Semaste if (thread_suffix_supported || static_cast<ProcessGDBRemote *>(process_sp.get())->GetGDBRemote().SetCurrentThread(m_thread.GetProtocolID())) 642254721Semaste { 643254721Semaste // The data_sp contains the entire G response packet including the 644254721Semaste // G, and if the thread suffix is supported, it has the thread suffix 645254721Semaste // as well. 646254721Semaste const char *G_packet = (const char *)data_sp->GetBytes(); 647254721Semaste size_t G_packet_len = data_sp->GetByteSize(); 648276479Sdim if (use_g_packet 649276479Sdim && gdb_comm.SendPacketAndWaitForResponse (G_packet, 650276479Sdim G_packet_len, 651276479Sdim response, 652276479Sdim false) == GDBRemoteCommunication::PacketResult::Success) 653254721Semaste { 654276479Sdim // The data_sp contains the entire G response packet including the 655276479Sdim // G, and if the thread suffix is supported, it has the thread suffix 656276479Sdim // as well. 657276479Sdim const char *G_packet = (const char *)data_sp->GetBytes(); 658276479Sdim size_t G_packet_len = data_sp->GetByteSize(); 659276479Sdim if (gdb_comm.SendPacketAndWaitForResponse (G_packet, 660276479Sdim G_packet_len, 661276479Sdim response, 662276479Sdim false) == GDBRemoteCommunication::PacketResult::Success) 663254721Semaste { 664276479Sdim if (response.IsOKResponse()) 665276479Sdim return true; 666276479Sdim else if (response.IsErrorResponse()) 667276479Sdim { 668276479Sdim uint32_t num_restored = 0; 669276479Sdim // We need to manually go through all of the registers and 670276479Sdim // restore them manually 671276479Sdim 672276479Sdim response.GetStringRef().assign (G_packet, G_packet_len); 673276479Sdim response.SetFilePos(1); // Skip the leading 'G' 674254721Semaste 675276479Sdim // G_packet_len is hex-ascii characters plus prefix 'G' plus suffix thread specifier. 676276479Sdim // This means buffer will be a little more than 2x larger than necessary but we resize 677276479Sdim // it down once we've extracted all hex ascii chars from the packet. 678276479Sdim DataBufferHeap buffer (G_packet_len, 0); 679276479Sdim DataExtractor restore_data (buffer.GetBytes(), 680276479Sdim buffer.GetByteSize(), 681276479Sdim m_reg_data.GetByteOrder(), 682276479Sdim m_reg_data.GetAddressByteSize()); 683276479Sdim 684276479Sdim const uint32_t bytes_extracted = response.GetHexBytes ((void *)restore_data.GetDataStart(), 685276479Sdim restore_data.GetByteSize(), 686276479Sdim '\xcc'); 687276479Sdim 688276479Sdim if (bytes_extracted < restore_data.GetByteSize()) 689276479Sdim restore_data.SetData(restore_data.GetDataStart(), bytes_extracted, m_reg_data.GetByteOrder()); 690276479Sdim 691276479Sdim const RegisterInfo *reg_info; 692254721Semaste 693276479Sdim // The g packet contents may either include the slice registers (registers defined in 694276479Sdim // terms of other registers, e.g. eax is a subset of rax) or not. The slice registers 695276479Sdim // should NOT be in the g packet, but some implementations may incorrectly include them. 696276479Sdim // 697276479Sdim // If the slice registers are included in the packet, we must step over the slice registers 698276479Sdim // when parsing the packet -- relying on the RegisterInfo byte_offset field would be incorrect. 699276479Sdim // If the slice registers are not included, then using the byte_offset values into the 700276479Sdim // data buffer is the best way to find individual register values. 701254721Semaste 702276479Sdim uint64_t size_including_slice_registers = 0; 703276479Sdim uint64_t size_not_including_slice_registers = 0; 704276479Sdim uint64_t size_by_highest_offset = 0; 705254721Semaste 706276479Sdim for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx) 707276479Sdim { 708276479Sdim size_including_slice_registers += reg_info->byte_size; 709276479Sdim if (reg_info->value_regs == NULL) 710276479Sdim size_not_including_slice_registers += reg_info->byte_size; 711276479Sdim if (reg_info->byte_offset >= size_by_highest_offset) 712276479Sdim size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size; 713276479Sdim } 714254721Semaste 715276479Sdim bool use_byte_offset_into_buffer; 716276479Sdim if (size_by_highest_offset == restore_data.GetByteSize()) 717276479Sdim { 718276479Sdim // The size of the packet agrees with the highest offset: + size in the register file 719276479Sdim use_byte_offset_into_buffer = true; 720276479Sdim } 721276479Sdim else if (size_not_including_slice_registers == restore_data.GetByteSize()) 722276479Sdim { 723276479Sdim // The size of the packet is the same as concatenating all of the registers sequentially, 724276479Sdim // skipping the slice registers 725276479Sdim use_byte_offset_into_buffer = true; 726276479Sdim } 727276479Sdim else if (size_including_slice_registers == restore_data.GetByteSize()) 728276479Sdim { 729276479Sdim // The slice registers are present in the packet (when they shouldn't be). 730276479Sdim // Don't try to use the RegisterInfo byte_offset into the restore_data, it will 731276479Sdim // point to the wrong place. 732276479Sdim use_byte_offset_into_buffer = false; 733276479Sdim } 734276479Sdim else { 735276479Sdim // None of our expected sizes match the actual g packet data we're looking at. 736276479Sdim // The most conservative approach here is to use the running total byte offset. 737276479Sdim use_byte_offset_into_buffer = false; 738276479Sdim } 739254721Semaste 740276479Sdim // In case our register definitions don't include the correct offsets, 741276479Sdim // keep track of the size of each reg & compute offset based on that. 742276479Sdim uint32_t running_byte_offset = 0; 743276479Sdim for (uint32_t reg_idx=0; (reg_info = GetRegisterInfoAtIndex (reg_idx)) != NULL; ++reg_idx, running_byte_offset += reg_info->byte_size) 744276479Sdim { 745276479Sdim // Skip composite aka slice registers (e.g. eax is a slice of rax). 746276479Sdim if (reg_info->value_regs) 747276479Sdim continue; 748254721Semaste 749276479Sdim const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 750276479Sdim 751276479Sdim uint32_t register_offset; 752276479Sdim if (use_byte_offset_into_buffer) 753254721Semaste { 754276479Sdim register_offset = reg_info->byte_offset; 755254721Semaste } 756276479Sdim else 757276479Sdim { 758276479Sdim register_offset = running_byte_offset; 759276479Sdim } 760254721Semaste 761276479Sdim // Only write down the registers that need to be written 762276479Sdim // if we are going to be doing registers individually. 763276479Sdim bool write_reg = true; 764276479Sdim const uint32_t reg_byte_size = reg_info->byte_size; 765276479Sdim 766276479Sdim const char *restore_src = (const char *)restore_data.PeekData(register_offset, reg_byte_size); 767276479Sdim if (restore_src) 768254721Semaste { 769254721Semaste StreamString packet; 770254721Semaste packet.Printf ("P%x=", reg); 771254721Semaste packet.PutBytesAsRawHex8 (restore_src, 772254721Semaste reg_byte_size, 773254721Semaste lldb::endian::InlHostByteOrder(), 774254721Semaste lldb::endian::InlHostByteOrder()); 775254721Semaste 776254721Semaste if (thread_suffix_supported) 777254721Semaste packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 778254721Semaste 779254721Semaste SetRegisterIsValid(reg, false); 780254721Semaste if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), 781254721Semaste packet.GetString().size(), 782254721Semaste response, 783262528Semaste false) == GDBRemoteCommunication::PacketResult::Success) 784254721Semaste { 785276479Sdim const char *current_src = (const char *)m_reg_data.PeekData(register_offset, reg_byte_size); 786276479Sdim if (current_src) 787276479Sdim write_reg = memcmp (current_src, restore_src, reg_byte_size) != 0; 788254721Semaste } 789276479Sdim 790276479Sdim if (write_reg) 791276479Sdim { 792276479Sdim StreamString packet; 793276479Sdim packet.Printf ("P%x=", reg); 794276479Sdim packet.PutBytesAsRawHex8 (restore_src, 795276479Sdim reg_byte_size, 796276479Sdim lldb::endian::InlHostByteOrder(), 797276479Sdim lldb::endian::InlHostByteOrder()); 798276479Sdim 799276479Sdim if (thread_suffix_supported) 800276479Sdim packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 801276479Sdim 802276479Sdim SetRegisterIsValid(reg, false); 803276479Sdim if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), 804276479Sdim packet.GetString().size(), 805276479Sdim response, 806276479Sdim false) == GDBRemoteCommunication::PacketResult::Success) 807276479Sdim { 808276479Sdim if (response.IsOKResponse()) 809276479Sdim ++num_restored; 810276479Sdim } 811276479Sdim } 812254721Semaste } 813254721Semaste } 814276479Sdim return num_restored > 0; 815254721Semaste } 816254721Semaste } 817254721Semaste } 818276479Sdim else 819276479Sdim { 820276479Sdim // For the use_g_packet == false case, we're going to write each register 821276479Sdim // individually. The data buffer is binary data in this case, instead of 822276479Sdim // ascii characters. 823276479Sdim 824276479Sdim bool arm64_debugserver = false; 825276479Sdim if (m_thread.GetProcess().get()) 826276479Sdim { 827276479Sdim const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture(); 828276479Sdim if (arch.IsValid() 829276479Sdim && arch.GetMachine() == llvm::Triple::aarch64 830276479Sdim && arch.GetTriple().getVendor() == llvm::Triple::Apple 831276479Sdim && arch.GetTriple().getOS() == llvm::Triple::IOS) 832276479Sdim { 833276479Sdim arm64_debugserver = true; 834276479Sdim } 835276479Sdim } 836276479Sdim uint32_t num_restored = 0; 837276479Sdim const RegisterInfo *reg_info; 838276479Sdim for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex (i)) != NULL; i++) 839276479Sdim { 840276479Sdim if (reg_info->value_regs) // skip registers that are slices of real registers 841276479Sdim continue; 842276479Sdim // Skip the fpsr and fpcr floating point status/control register writing to 843276479Sdim // work around a bug in an older version of debugserver that would lead to 844276479Sdim // register context corruption when writing fpsr/fpcr. 845276479Sdim if (arm64_debugserver && 846276479Sdim (strcmp (reg_info->name, "fpsr") == 0 || strcmp (reg_info->name, "fpcr") == 0)) 847276479Sdim { 848276479Sdim continue; 849276479Sdim } 850276479Sdim StreamString packet; 851276479Sdim packet.Printf ("P%x=", reg_info->kinds[eRegisterKindLLDB]); 852276479Sdim packet.PutBytesAsRawHex8 (data_sp->GetBytes() + reg_info->byte_offset, reg_info->byte_size, lldb::endian::InlHostByteOrder(), lldb::endian::InlHostByteOrder()); 853276479Sdim if (thread_suffix_supported) 854276479Sdim packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetProtocolID()); 855276479Sdim 856276479Sdim SetRegisterIsValid(reg_info, false); 857276479Sdim if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(), 858276479Sdim packet.GetString().size(), 859276479Sdim response, 860276479Sdim false) == GDBRemoteCommunication::PacketResult::Success) 861276479Sdim { 862276479Sdim if (response.IsOKResponse()) 863276479Sdim ++num_restored; 864276479Sdim } 865276479Sdim } 866276479Sdim return num_restored > 0; 867276479Sdim } 868254721Semaste } 869254721Semaste } 870254721Semaste else 871254721Semaste { 872254721Semaste Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); 873254721Semaste if (log) 874254721Semaste { 875254721Semaste if (log->GetVerbose()) 876254721Semaste { 877254721Semaste StreamString strm; 878254721Semaste gdb_comm.DumpHistory(strm); 879254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending write all registers:\n%s", strm.GetData()); 880254721Semaste } 881254721Semaste else 882254721Semaste log->Printf("error: failed to get packet sequence mutex, not sending write all registers"); 883254721Semaste } 884254721Semaste } 885254721Semaste return false; 886254721Semaste} 887254721Semaste 888254721Semaste 889254721Semasteuint32_t 890276479SdimGDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) 891254721Semaste{ 892254721Semaste return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num); 893254721Semaste} 894254721Semaste 895258054Semaste 896254721Semastevoid 897254721SemasteGDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) 898254721Semaste{ 899254721Semaste // For Advanced SIMD and VFP register mapping. 900254721Semaste static uint32_t g_d0_regs[] = { 26, 27, LLDB_INVALID_REGNUM }; // (s0, s1) 901254721Semaste static uint32_t g_d1_regs[] = { 28, 29, LLDB_INVALID_REGNUM }; // (s2, s3) 902254721Semaste static uint32_t g_d2_regs[] = { 30, 31, LLDB_INVALID_REGNUM }; // (s4, s5) 903254721Semaste static uint32_t g_d3_regs[] = { 32, 33, LLDB_INVALID_REGNUM }; // (s6, s7) 904254721Semaste static uint32_t g_d4_regs[] = { 34, 35, LLDB_INVALID_REGNUM }; // (s8, s9) 905254721Semaste static uint32_t g_d5_regs[] = { 36, 37, LLDB_INVALID_REGNUM }; // (s10, s11) 906254721Semaste static uint32_t g_d6_regs[] = { 38, 39, LLDB_INVALID_REGNUM }; // (s12, s13) 907254721Semaste static uint32_t g_d7_regs[] = { 40, 41, LLDB_INVALID_REGNUM }; // (s14, s15) 908254721Semaste static uint32_t g_d8_regs[] = { 42, 43, LLDB_INVALID_REGNUM }; // (s16, s17) 909254721Semaste static uint32_t g_d9_regs[] = { 44, 45, LLDB_INVALID_REGNUM }; // (s18, s19) 910254721Semaste static uint32_t g_d10_regs[] = { 46, 47, LLDB_INVALID_REGNUM }; // (s20, s21) 911254721Semaste static uint32_t g_d11_regs[] = { 48, 49, LLDB_INVALID_REGNUM }; // (s22, s23) 912254721Semaste static uint32_t g_d12_regs[] = { 50, 51, LLDB_INVALID_REGNUM }; // (s24, s25) 913254721Semaste static uint32_t g_d13_regs[] = { 52, 53, LLDB_INVALID_REGNUM }; // (s26, s27) 914254721Semaste static uint32_t g_d14_regs[] = { 54, 55, LLDB_INVALID_REGNUM }; // (s28, s29) 915254721Semaste static uint32_t g_d15_regs[] = { 56, 57, LLDB_INVALID_REGNUM }; // (s30, s31) 916254721Semaste static uint32_t g_q0_regs[] = { 26, 27, 28, 29, LLDB_INVALID_REGNUM }; // (d0, d1) -> (s0, s1, s2, s3) 917254721Semaste static uint32_t g_q1_regs[] = { 30, 31, 32, 33, LLDB_INVALID_REGNUM }; // (d2, d3) -> (s4, s5, s6, s7) 918254721Semaste static uint32_t g_q2_regs[] = { 34, 35, 36, 37, LLDB_INVALID_REGNUM }; // (d4, d5) -> (s8, s9, s10, s11) 919254721Semaste static uint32_t g_q3_regs[] = { 38, 39, 40, 41, LLDB_INVALID_REGNUM }; // (d6, d7) -> (s12, s13, s14, s15) 920254721Semaste static uint32_t g_q4_regs[] = { 42, 43, 44, 45, LLDB_INVALID_REGNUM }; // (d8, d9) -> (s16, s17, s18, s19) 921254721Semaste static uint32_t g_q5_regs[] = { 46, 47, 48, 49, LLDB_INVALID_REGNUM }; // (d10, d11) -> (s20, s21, s22, s23) 922254721Semaste static uint32_t g_q6_regs[] = { 50, 51, 52, 53, LLDB_INVALID_REGNUM }; // (d12, d13) -> (s24, s25, s26, s27) 923254721Semaste static uint32_t g_q7_regs[] = { 54, 55, 56, 57, LLDB_INVALID_REGNUM }; // (d14, d15) -> (s28, s29, s30, s31) 924254721Semaste static uint32_t g_q8_regs[] = { 59, 60, LLDB_INVALID_REGNUM }; // (d16, d17) 925254721Semaste static uint32_t g_q9_regs[] = { 61, 62, LLDB_INVALID_REGNUM }; // (d18, d19) 926254721Semaste static uint32_t g_q10_regs[] = { 63, 64, LLDB_INVALID_REGNUM }; // (d20, d21) 927254721Semaste static uint32_t g_q11_regs[] = { 65, 66, LLDB_INVALID_REGNUM }; // (d22, d23) 928254721Semaste static uint32_t g_q12_regs[] = { 67, 68, LLDB_INVALID_REGNUM }; // (d24, d25) 929254721Semaste static uint32_t g_q13_regs[] = { 69, 70, LLDB_INVALID_REGNUM }; // (d26, d27) 930254721Semaste static uint32_t g_q14_regs[] = { 71, 72, LLDB_INVALID_REGNUM }; // (d28, d29) 931254721Semaste static uint32_t g_q15_regs[] = { 73, 74, LLDB_INVALID_REGNUM }; // (d30, d31) 932254721Semaste 933254721Semaste // This is our array of composite registers, with each element coming from the above register mappings. 934254721Semaste static uint32_t *g_composites[] = { 935254721Semaste g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs, g_d6_regs, g_d7_regs, 936254721Semaste g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs, g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs, 937254721Semaste g_q0_regs, g_q1_regs, g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs, 938254721Semaste g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs, g_q14_regs, g_q15_regs 939254721Semaste }; 940254721Semaste 941254721Semaste static RegisterInfo g_register_infos[] = { 942254721Semaste// NAME ALT SZ OFF ENCODING FORMAT COMPILER DWARF GENERIC GDB LLDB VALUE REGS INVALIDATE REGS 943254721Semaste// ====== ====== === === ============= ============ =================== =================== ====================== === ==== ========== =============== 944254721Semaste { "r0", "arg1", 4, 0, eEncodingUint, eFormatHex, { gcc_r0, dwarf_r0, LLDB_REGNUM_GENERIC_ARG1,0, 0 }, NULL, NULL}, 945254721Semaste { "r1", "arg2", 4, 0, eEncodingUint, eFormatHex, { gcc_r1, dwarf_r1, LLDB_REGNUM_GENERIC_ARG2,1, 1 }, NULL, NULL}, 946254721Semaste { "r2", "arg3", 4, 0, eEncodingUint, eFormatHex, { gcc_r2, dwarf_r2, LLDB_REGNUM_GENERIC_ARG3,2, 2 }, NULL, NULL}, 947254721Semaste { "r3", "arg4", 4, 0, eEncodingUint, eFormatHex, { gcc_r3, dwarf_r3, LLDB_REGNUM_GENERIC_ARG4,3, 3 }, NULL, NULL}, 948254721Semaste { "r4", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r4, dwarf_r4, LLDB_INVALID_REGNUM, 4, 4 }, NULL, NULL}, 949254721Semaste { "r5", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r5, dwarf_r5, LLDB_INVALID_REGNUM, 5, 5 }, NULL, NULL}, 950254721Semaste { "r6", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r6, dwarf_r6, LLDB_INVALID_REGNUM, 6, 6 }, NULL, NULL}, 951254721Semaste { "r7", "fp", 4, 0, eEncodingUint, eFormatHex, { gcc_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, 7, 7 }, NULL, NULL}, 952254721Semaste { "r8", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r8, dwarf_r8, LLDB_INVALID_REGNUM, 8, 8 }, NULL, NULL}, 953254721Semaste { "r9", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r9, dwarf_r9, LLDB_INVALID_REGNUM, 9, 9 }, NULL, NULL}, 954254721Semaste { "r10", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r10, dwarf_r10, LLDB_INVALID_REGNUM, 10, 10 }, NULL, NULL}, 955254721Semaste { "r11", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r11, dwarf_r11, LLDB_INVALID_REGNUM, 11, 11 }, NULL, NULL}, 956254721Semaste { "r12", NULL, 4, 0, eEncodingUint, eFormatHex, { gcc_r12, dwarf_r12, LLDB_INVALID_REGNUM, 12, 12 }, NULL, NULL}, 957254721Semaste { "sp", "r13", 4, 0, eEncodingUint, eFormatHex, { gcc_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, 13, 13 }, NULL, NULL}, 958254721Semaste { "lr", "r14", 4, 0, eEncodingUint, eFormatHex, { gcc_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, 14, 14 }, NULL, NULL}, 959254721Semaste { "pc", "r15", 4, 0, eEncodingUint, eFormatHex, { gcc_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, 15, 15 }, NULL, NULL}, 960254721Semaste { "f0", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 16, 16 }, NULL, NULL}, 961254721Semaste { "f1", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 17, 17 }, NULL, NULL}, 962254721Semaste { "f2", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 18, 18 }, NULL, NULL}, 963254721Semaste { "f3", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 19, 19 }, NULL, NULL}, 964254721Semaste { "f4", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 20, 20 }, NULL, NULL}, 965254721Semaste { "f5", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 21, 21 }, NULL, NULL}, 966254721Semaste { "f6", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 22, 22 }, NULL, NULL}, 967254721Semaste { "f7", NULL, 12, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 23, 23 }, NULL, NULL}, 968254721Semaste { "fps", NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 24, 24 }, NULL, NULL}, 969254721Semaste { "cpsr","flags", 4, 0, eEncodingUint, eFormatHex, { gcc_cpsr, dwarf_cpsr, LLDB_INVALID_REGNUM, 25, 25 }, NULL, NULL}, 970254721Semaste { "s0", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, 26, 26 }, NULL, NULL}, 971254721Semaste { "s1", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, 27, 27 }, NULL, NULL}, 972254721Semaste { "s2", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, 28, 28 }, NULL, NULL}, 973254721Semaste { "s3", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, 29, 29 }, NULL, NULL}, 974254721Semaste { "s4", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, 30, 30 }, NULL, NULL}, 975254721Semaste { "s5", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, 31, 31 }, NULL, NULL}, 976254721Semaste { "s6", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, 32, 32 }, NULL, NULL}, 977254721Semaste { "s7", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, 33, 33 }, NULL, NULL}, 978254721Semaste { "s8", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, 34, 34 }, NULL, NULL}, 979254721Semaste { "s9", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, 35, 35 }, NULL, NULL}, 980254721Semaste { "s10", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, 36, 36 }, NULL, NULL}, 981254721Semaste { "s11", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, 37, 37 }, NULL, NULL}, 982254721Semaste { "s12", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, 38, 38 }, NULL, NULL}, 983254721Semaste { "s13", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, 39, 39 }, NULL, NULL}, 984254721Semaste { "s14", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, 40, 40 }, NULL, NULL}, 985254721Semaste { "s15", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, 41, 41 }, NULL, NULL}, 986254721Semaste { "s16", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, 42, 42 }, NULL, NULL}, 987254721Semaste { "s17", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, 43, 43 }, NULL, NULL}, 988254721Semaste { "s18", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, 44, 44 }, NULL, NULL}, 989254721Semaste { "s19", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, 45, 45 }, NULL, NULL}, 990254721Semaste { "s20", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, 46, 46 }, NULL, NULL}, 991254721Semaste { "s21", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, 47, 47 }, NULL, NULL}, 992254721Semaste { "s22", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, 48, 48 }, NULL, NULL}, 993254721Semaste { "s23", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, 49, 49 }, NULL, NULL}, 994254721Semaste { "s24", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, 50, 50 }, NULL, NULL}, 995254721Semaste { "s25", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, 51, 51 }, NULL, NULL}, 996254721Semaste { "s26", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, 52, 52 }, NULL, NULL}, 997254721Semaste { "s27", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, 53, 53 }, NULL, NULL}, 998254721Semaste { "s28", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, 54, 54 }, NULL, NULL}, 999254721Semaste { "s29", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, 55, 55 }, NULL, NULL}, 1000254721Semaste { "s30", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, 56, 56 }, NULL, NULL}, 1001254721Semaste { "s31", NULL, 4, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, 57, 57 }, NULL, NULL}, 1002254721Semaste { "fpscr",NULL, 4, 0, eEncodingUint, eFormatHex, { LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, 58, 58 }, NULL, NULL}, 1003254721Semaste { "d16", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d16, LLDB_INVALID_REGNUM, 59, 59 }, NULL, NULL}, 1004254721Semaste { "d17", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d17, LLDB_INVALID_REGNUM, 60, 60 }, NULL, NULL}, 1005254721Semaste { "d18", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d18, LLDB_INVALID_REGNUM, 61, 61 }, NULL, NULL}, 1006254721Semaste { "d19", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d19, LLDB_INVALID_REGNUM, 62, 62 }, NULL, NULL}, 1007254721Semaste { "d20", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d20, LLDB_INVALID_REGNUM, 63, 63 }, NULL, NULL}, 1008254721Semaste { "d21", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d21, LLDB_INVALID_REGNUM, 64, 64 }, NULL, NULL}, 1009254721Semaste { "d22", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d22, LLDB_INVALID_REGNUM, 65, 65 }, NULL, NULL}, 1010254721Semaste { "d23", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d23, LLDB_INVALID_REGNUM, 66, 66 }, NULL, NULL}, 1011254721Semaste { "d24", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d24, LLDB_INVALID_REGNUM, 67, 67 }, NULL, NULL}, 1012254721Semaste { "d25", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d25, LLDB_INVALID_REGNUM, 68, 68 }, NULL, NULL}, 1013254721Semaste { "d26", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d26, LLDB_INVALID_REGNUM, 69, 69 }, NULL, NULL}, 1014254721Semaste { "d27", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d27, LLDB_INVALID_REGNUM, 70, 70 }, NULL, NULL}, 1015254721Semaste { "d28", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d28, LLDB_INVALID_REGNUM, 71, 71 }, NULL, NULL}, 1016254721Semaste { "d29", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d29, LLDB_INVALID_REGNUM, 72, 72 }, NULL, NULL}, 1017254721Semaste { "d30", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d30, LLDB_INVALID_REGNUM, 73, 73 }, NULL, NULL}, 1018254721Semaste { "d31", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d31, LLDB_INVALID_REGNUM, 74, 74 }, NULL, NULL}, 1019254721Semaste { "d0", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d0, LLDB_INVALID_REGNUM, 75, 75 }, g_d0_regs, NULL}, 1020254721Semaste { "d1", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d1, LLDB_INVALID_REGNUM, 76, 76 }, g_d1_regs, NULL}, 1021254721Semaste { "d2", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d2, LLDB_INVALID_REGNUM, 77, 77 }, g_d2_regs, NULL}, 1022254721Semaste { "d3", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d3, LLDB_INVALID_REGNUM, 78, 78 }, g_d3_regs, NULL}, 1023254721Semaste { "d4", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d4, LLDB_INVALID_REGNUM, 79, 79 }, g_d4_regs, NULL}, 1024254721Semaste { "d5", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d5, LLDB_INVALID_REGNUM, 80, 80 }, g_d5_regs, NULL}, 1025254721Semaste { "d6", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d6, LLDB_INVALID_REGNUM, 81, 81 }, g_d6_regs, NULL}, 1026254721Semaste { "d7", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d7, LLDB_INVALID_REGNUM, 82, 82 }, g_d7_regs, NULL}, 1027254721Semaste { "d8", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d8, LLDB_INVALID_REGNUM, 83, 83 }, g_d8_regs, NULL}, 1028254721Semaste { "d9", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d9, LLDB_INVALID_REGNUM, 84, 84 }, g_d9_regs, NULL}, 1029254721Semaste { "d10", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d10, LLDB_INVALID_REGNUM, 85, 85 }, g_d10_regs, NULL}, 1030254721Semaste { "d11", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d11, LLDB_INVALID_REGNUM, 86, 86 }, g_d11_regs, NULL}, 1031254721Semaste { "d12", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d12, LLDB_INVALID_REGNUM, 87, 87 }, g_d12_regs, NULL}, 1032254721Semaste { "d13", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d13, LLDB_INVALID_REGNUM, 88, 88 }, g_d13_regs, NULL}, 1033254721Semaste { "d14", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d14, LLDB_INVALID_REGNUM, 89, 89 }, g_d14_regs, NULL}, 1034254721Semaste { "d15", NULL, 8, 0, eEncodingIEEE754, eFormatFloat, { LLDB_INVALID_REGNUM, dwarf_d15, LLDB_INVALID_REGNUM, 90, 90 }, g_d15_regs, NULL}, 1035254721Semaste { "q0", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q0, LLDB_INVALID_REGNUM, 91, 91 }, g_q0_regs, NULL}, 1036254721Semaste { "q1", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q1, LLDB_INVALID_REGNUM, 92, 92 }, g_q1_regs, NULL}, 1037254721Semaste { "q2", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q2, LLDB_INVALID_REGNUM, 93, 93 }, g_q2_regs, NULL}, 1038254721Semaste { "q3", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q3, LLDB_INVALID_REGNUM, 94, 94 }, g_q3_regs, NULL}, 1039254721Semaste { "q4", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q4, LLDB_INVALID_REGNUM, 95, 95 }, g_q4_regs, NULL}, 1040254721Semaste { "q5", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q5, LLDB_INVALID_REGNUM, 96, 96 }, g_q5_regs, NULL}, 1041254721Semaste { "q6", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q6, LLDB_INVALID_REGNUM, 97, 97 }, g_q6_regs, NULL}, 1042254721Semaste { "q7", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q7, LLDB_INVALID_REGNUM, 98, 98 }, g_q7_regs, NULL}, 1043254721Semaste { "q8", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q8, LLDB_INVALID_REGNUM, 99, 99 }, g_q8_regs, NULL}, 1044254721Semaste { "q9", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q9, LLDB_INVALID_REGNUM, 100, 100 }, g_q9_regs, NULL}, 1045254721Semaste { "q10", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q10, LLDB_INVALID_REGNUM, 101, 101 }, g_q10_regs, NULL}, 1046254721Semaste { "q11", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q11, LLDB_INVALID_REGNUM, 102, 102 }, g_q11_regs, NULL}, 1047254721Semaste { "q12", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q12, LLDB_INVALID_REGNUM, 103, 103 }, g_q12_regs, NULL}, 1048254721Semaste { "q13", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q13, LLDB_INVALID_REGNUM, 104, 104 }, g_q13_regs, NULL}, 1049254721Semaste { "q14", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, NULL}, 1050254721Semaste { "q15", NULL, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, NULL} 1051254721Semaste }; 1052254721Semaste 1053254721Semaste static const uint32_t num_registers = llvm::array_lengthof(g_register_infos); 1054254721Semaste static ConstString gpr_reg_set ("General Purpose Registers"); 1055254721Semaste static ConstString sfp_reg_set ("Software Floating Point Registers"); 1056254721Semaste static ConstString vfp_reg_set ("Floating Point Registers"); 1057254721Semaste size_t i; 1058254721Semaste if (from_scratch) 1059254721Semaste { 1060254721Semaste // Calculate the offsets of the registers 1061254721Semaste // Note that the layout of the "composite" registers (d0-d15 and q0-q15) which comes after the 1062254721Semaste // "primordial" registers is important. This enables us to calculate the offset of the composite 1063254721Semaste // register by using the offset of its first primordial register. For example, to calculate the 1064254721Semaste // offset of q0, use s0's offset. 1065254721Semaste if (g_register_infos[2].byte_offset == 0) 1066254721Semaste { 1067254721Semaste uint32_t byte_offset = 0; 1068254721Semaste for (i=0; i<num_registers; ++i) 1069254721Semaste { 1070254721Semaste // For primordial registers, increment the byte_offset by the byte_size to arrive at the 1071254721Semaste // byte_offset for the next register. Otherwise, we have a composite register whose 1072254721Semaste // offset can be calculated by consulting the offset of its first primordial register. 1073254721Semaste if (!g_register_infos[i].value_regs) 1074254721Semaste { 1075254721Semaste g_register_infos[i].byte_offset = byte_offset; 1076254721Semaste byte_offset += g_register_infos[i].byte_size; 1077254721Semaste } 1078254721Semaste else 1079254721Semaste { 1080254721Semaste const uint32_t first_primordial_reg = g_register_infos[i].value_regs[0]; 1081254721Semaste g_register_infos[i].byte_offset = g_register_infos[first_primordial_reg].byte_offset; 1082254721Semaste } 1083254721Semaste } 1084254721Semaste } 1085254721Semaste for (i=0; i<num_registers; ++i) 1086254721Semaste { 1087254721Semaste ConstString name; 1088254721Semaste ConstString alt_name; 1089254721Semaste if (g_register_infos[i].name && g_register_infos[i].name[0]) 1090254721Semaste name.SetCString(g_register_infos[i].name); 1091254721Semaste if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0]) 1092254721Semaste alt_name.SetCString(g_register_infos[i].alt_name); 1093254721Semaste 1094254721Semaste if (i <= 15 || i == 25) 1095254721Semaste AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set); 1096254721Semaste else if (i <= 24) 1097254721Semaste AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set); 1098254721Semaste else 1099254721Semaste AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set); 1100254721Semaste } 1101254721Semaste } 1102254721Semaste else 1103254721Semaste { 1104254721Semaste // Add composite registers to our primordial registers, then. 1105254721Semaste const size_t num_composites = llvm::array_lengthof(g_composites); 1106254721Semaste const size_t num_dynamic_regs = GetNumRegisters(); 1107254721Semaste const size_t num_common_regs = num_registers - num_composites; 1108254721Semaste RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs; 1109254721Semaste 1110254721Semaste // First we need to validate that all registers that we already have match the non composite regs. 1111254721Semaste // If so, then we can add the registers, else we need to bail 1112254721Semaste bool match = true; 1113254721Semaste if (num_dynamic_regs == num_common_regs) 1114254721Semaste { 1115254721Semaste for (i=0; match && i<num_dynamic_regs; ++i) 1116254721Semaste { 1117254721Semaste // Make sure all register names match 1118254721Semaste if (m_regs[i].name && g_register_infos[i].name) 1119254721Semaste { 1120254721Semaste if (strcmp(m_regs[i].name, g_register_infos[i].name)) 1121254721Semaste { 1122254721Semaste match = false; 1123254721Semaste break; 1124254721Semaste } 1125254721Semaste } 1126254721Semaste 1127254721Semaste // Make sure all register byte sizes match 1128254721Semaste if (m_regs[i].byte_size != g_register_infos[i].byte_size) 1129254721Semaste { 1130254721Semaste match = false; 1131254721Semaste break; 1132254721Semaste } 1133254721Semaste } 1134254721Semaste } 1135254721Semaste else 1136254721Semaste { 1137254721Semaste // Wrong number of registers. 1138254721Semaste match = false; 1139254721Semaste } 1140254721Semaste // If "match" is true, then we can add extra registers. 1141254721Semaste if (match) 1142254721Semaste { 1143254721Semaste for (i=0; i<num_composites; ++i) 1144254721Semaste { 1145254721Semaste ConstString name; 1146254721Semaste ConstString alt_name; 1147254721Semaste const uint32_t first_primordial_reg = g_comp_register_infos[i].value_regs[0]; 1148254721Semaste const char *reg_name = g_register_infos[first_primordial_reg].name; 1149254721Semaste if (reg_name && reg_name[0]) 1150254721Semaste { 1151254721Semaste for (uint32_t j = 0; j < num_dynamic_regs; ++j) 1152254721Semaste { 1153254721Semaste const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j); 1154254721Semaste // Find a matching primordial register info entry. 1155254721Semaste if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, reg_name) == 0) 1156254721Semaste { 1157254721Semaste // The name matches the existing primordial entry. 1158254721Semaste // Find and assign the offset, and then add this composite register entry. 1159254721Semaste g_comp_register_infos[i].byte_offset = reg_info->byte_offset; 1160254721Semaste name.SetCString(g_comp_register_infos[i].name); 1161254721Semaste AddRegister(g_comp_register_infos[i], name, alt_name, vfp_reg_set); 1162254721Semaste } 1163254721Semaste } 1164254721Semaste } 1165254721Semaste } 1166254721Semaste } 1167254721Semaste } 1168254721Semaste} 1169