diff options
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp')
| -rw-r--r-- | lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp | 1497 |
1 files changed, 731 insertions, 766 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp index 78e1956..27ce67d 100644 --- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp @@ -21,12 +21,12 @@ #include "lldb/Target/Target.h" #include "lldb/Utility/Utils.h" // Project includes -#include "Utility/StringExtractorGDBRemote.h" #include "ProcessGDBRemote.h" #include "ProcessGDBRemoteLog.h" #include "ThreadGDBRemote.h" #include "Utility/ARM_DWARF_Registers.h" #include "Utility/ARM_ehframe_Registers.h" +#include "Utility/StringExtractorGDBRemote.h" using namespace lldb; using namespace lldb_private; @@ -35,762 +35,735 @@ using namespace lldb_private::process_gdb_remote; //---------------------------------------------------------------------- // GDBRemoteRegisterContext constructor //---------------------------------------------------------------------- -GDBRemoteRegisterContext::GDBRemoteRegisterContext -( - ThreadGDBRemote &thread, - uint32_t concrete_frame_idx, - GDBRemoteDynamicRegisterInfo ®_info, - bool read_all_at_once -) : - RegisterContext (thread, concrete_frame_idx), - m_reg_info (reg_info), - m_reg_valid (), - m_reg_data (), - m_read_all_at_once (read_all_at_once) -{ - // Resize our vector of bools to contain one bool for every register. - // We will use these boolean values to know when a register value - // is valid in m_reg_data. - m_reg_valid.resize (reg_info.GetNumRegisters()); - - // Make a heap based buffer that is big enough to store all registers - DataBufferSP reg_data_sp(new DataBufferHeap (reg_info.GetRegisterDataByteSize(), 0)); - m_reg_data.SetData (reg_data_sp); - m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder()); +GDBRemoteRegisterContext::GDBRemoteRegisterContext( + ThreadGDBRemote &thread, uint32_t concrete_frame_idx, + GDBRemoteDynamicRegisterInfo ®_info, bool read_all_at_once) + : RegisterContext(thread, concrete_frame_idx), m_reg_info(reg_info), + m_reg_valid(), m_reg_data(), m_read_all_at_once(read_all_at_once) { + // Resize our vector of bools to contain one bool for every register. + // We will use these boolean values to know when a register value + // is valid in m_reg_data. + m_reg_valid.resize(reg_info.GetNumRegisters()); + + // Make a heap based buffer that is big enough to store all registers + DataBufferSP reg_data_sp( + new DataBufferHeap(reg_info.GetRegisterDataByteSize(), 0)); + m_reg_data.SetData(reg_data_sp); + m_reg_data.SetByteOrder(thread.GetProcess()->GetByteOrder()); } //---------------------------------------------------------------------- // Destructor //---------------------------------------------------------------------- -GDBRemoteRegisterContext::~GDBRemoteRegisterContext() -{ -} +GDBRemoteRegisterContext::~GDBRemoteRegisterContext() {} -void -GDBRemoteRegisterContext::InvalidateAllRegisters () -{ - SetAllRegisterValid (false); +void GDBRemoteRegisterContext::InvalidateAllRegisters() { + SetAllRegisterValid(false); } -void -GDBRemoteRegisterContext::SetAllRegisterValid (bool b) -{ - std::vector<bool>::iterator pos, end = m_reg_valid.end(); - for (pos = m_reg_valid.begin(); pos != end; ++pos) - *pos = b; +void GDBRemoteRegisterContext::SetAllRegisterValid(bool b) { + std::vector<bool>::iterator pos, end = m_reg_valid.end(); + for (pos = m_reg_valid.begin(); pos != end; ++pos) + *pos = b; } -size_t -GDBRemoteRegisterContext::GetRegisterCount () -{ - return m_reg_info.GetNumRegisters (); +size_t GDBRemoteRegisterContext::GetRegisterCount() { + return m_reg_info.GetNumRegisters(); } const RegisterInfo * -GDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg) -{ - RegisterInfo* reg_info = m_reg_info.GetRegisterInfoAtIndex (reg); - - if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) - { - const ArchSpec &arch = m_thread.GetProcess ()->GetTarget ().GetArchitecture (); - uint8_t reg_size = UpdateDynamicRegisterSize (arch, reg_info); - reg_info->byte_size = reg_size; - } - return reg_info; +GDBRemoteRegisterContext::GetRegisterInfoAtIndex(size_t reg) { + RegisterInfo *reg_info = m_reg_info.GetRegisterInfoAtIndex(reg); + + if (reg_info && reg_info->dynamic_size_dwarf_expr_bytes) { + const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture(); + uint8_t reg_size = UpdateDynamicRegisterSize(arch, reg_info); + reg_info->byte_size = reg_size; + } + return reg_info; } -size_t -GDBRemoteRegisterContext::GetRegisterSetCount () -{ - return m_reg_info.GetNumRegisterSets (); +size_t GDBRemoteRegisterContext::GetRegisterSetCount() { + return m_reg_info.GetNumRegisterSets(); } - - -const RegisterSet * -GDBRemoteRegisterContext::GetRegisterSet (size_t reg_set) -{ - return m_reg_info.GetRegisterSet (reg_set); +const RegisterSet *GDBRemoteRegisterContext::GetRegisterSet(size_t reg_set) { + return m_reg_info.GetRegisterSet(reg_set); } +bool GDBRemoteRegisterContext::ReadRegister(const RegisterInfo *reg_info, + RegisterValue &value) { + // Read the register + if (ReadRegisterBytes(reg_info, m_reg_data)) { + const bool partial_data_ok = false; + Error error(value.SetValueFromData(reg_info, m_reg_data, + reg_info->byte_offset, partial_data_ok)); + return error.Success(); + } + return false; +} - -bool -GDBRemoteRegisterContext::ReadRegister (const RegisterInfo *reg_info, RegisterValue &value) -{ - // Read the register - if (ReadRegisterBytes (reg_info, m_reg_data)) - { - const bool partial_data_ok = false; - Error error (value.SetValueFromData(reg_info, m_reg_data, reg_info->byte_offset, partial_data_ok)); - return error.Success(); - } +bool GDBRemoteRegisterContext::PrivateSetRegisterValue( + uint32_t reg, llvm::ArrayRef<uint8_t> data) { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); + if (reg_info == NULL) return false; -} -bool -GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg, llvm::ArrayRef<uint8_t> data) -{ - const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); - if (reg_info == NULL) - return false; - - // Invalidate if needed - InvalidateIfNeeded(false); - - const size_t reg_byte_size = reg_info->byte_size; - memcpy(const_cast<uint8_t *>(m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), data.data(), - std::min(data.size(), reg_byte_size)); - bool success = data.size() >= reg_byte_size; - if (success) - { - SetRegisterIsValid(reg, true); - } - else if (data.size() > 0) - { - // Only set register is valid to false if we copied some bytes, else - // leave it as it was. - SetRegisterIsValid(reg, false); - } - return success; + // Invalidate if needed + InvalidateIfNeeded(false); + + const size_t reg_byte_size = reg_info->byte_size; + memcpy(const_cast<uint8_t *>( + m_reg_data.PeekData(reg_info->byte_offset, reg_byte_size)), + data.data(), std::min(data.size(), reg_byte_size)); + bool success = data.size() >= reg_byte_size; + if (success) { + SetRegisterIsValid(reg, true); + } else if (data.size() > 0) { + // Only set register is valid to false if we copied some bytes, else + // leave it as it was. + SetRegisterIsValid(reg, false); + } + return success; } -bool -GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, uint64_t new_reg_val) -{ - const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg); - if (reg_info == NULL) - return false; - - // Early in process startup, we can get a thread that has an invalid byte order - // because the process hasn't been completely set up yet (see the ctor where the - // byte order is setfrom the process). If that's the case, we can't set the - // value here. - if (m_reg_data.GetByteOrder() == eByteOrderInvalid) - { - return false; - } - - // Invalidate if needed - InvalidateIfNeeded (false); +bool GDBRemoteRegisterContext::PrivateSetRegisterValue(uint32_t reg, + uint64_t new_reg_val) { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(reg); + if (reg_info == NULL) + return false; - DataBufferSP buffer_sp (new DataBufferHeap (&new_reg_val, sizeof (new_reg_val))); - DataExtractor data (buffer_sp, endian::InlHostByteOrder(), sizeof (void*)); + // Early in process startup, we can get a thread that has an invalid byte + // order + // because the process hasn't been completely set up yet (see the ctor where + // the + // byte order is setfrom the process). If that's the case, we can't set the + // value here. + if (m_reg_data.GetByteOrder() == eByteOrderInvalid) { + return false; + } - // If our register context and our register info disagree, which should never happen, don't - // overwrite past the end of the buffer. - if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) - return false; + // Invalidate if needed + InvalidateIfNeeded(false); - // Grab a pointer to where we are going to put this register - uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); + DataBufferSP buffer_sp(new DataBufferHeap(&new_reg_val, sizeof(new_reg_val))); + DataExtractor data(buffer_sp, endian::InlHostByteOrder(), sizeof(void *)); - if (dst == NULL) - return false; + // If our register context and our register info disagree, which should never + // happen, don't + // overwrite past the end of the buffer. + if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) + return false; + // Grab a pointer to where we are going to put this register + uint8_t *dst = const_cast<uint8_t *>( + m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); - if (data.CopyByteOrderedData (0, // src offset - reg_info->byte_size, // src length - dst, // dst - reg_info->byte_size, // dst length - m_reg_data.GetByteOrder())) // dst byte order - { - SetRegisterIsValid (reg, true); - return true; - } + if (dst == NULL) return false; + + if (data.CopyByteOrderedData(0, // src offset + reg_info->byte_size, // src length + dst, // dst + reg_info->byte_size, // dst length + m_reg_data.GetByteOrder())) // dst byte order + { + SetRegisterIsValid(reg, true); + return true; + } + return false; } // Helper function for GDBRemoteRegisterContext::ReadRegisterBytes(). -bool -GDBRemoteRegisterContext::GetPrimordialRegister(const RegisterInfo *reg_info, - GDBRemoteCommunicationClient &gdb_comm) -{ - const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB]; - const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin]; - StringExtractorGDBRemote response; - if (DataBufferSP buffer_sp = gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg)) - return PrivateSetRegisterValue(lldb_reg, - llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(), buffer_sp->GetByteSize())); - return false; +bool GDBRemoteRegisterContext::GetPrimordialRegister( + const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) { + const uint32_t lldb_reg = reg_info->kinds[eRegisterKindLLDB]; + const uint32_t remote_reg = reg_info->kinds[eRegisterKindProcessPlugin]; + StringExtractorGDBRemote response; + if (DataBufferSP buffer_sp = + gdb_comm.ReadRegister(m_thread.GetProtocolID(), remote_reg)) + return PrivateSetRegisterValue( + lldb_reg, llvm::ArrayRef<uint8_t>(buffer_sp->GetBytes(), + buffer_sp->GetByteSize())); + return false; } -bool -GDBRemoteRegisterContext::ReadRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data) -{ - ExecutionContext exe_ctx (CalculateThread()); +bool GDBRemoteRegisterContext::ReadRegisterBytes(const RegisterInfo *reg_info, + DataExtractor &data) { + ExecutionContext exe_ctx(CalculateThread()); - Process *process = exe_ctx.GetProcessPtr(); - Thread *thread = exe_ctx.GetThreadPtr(); - if (process == NULL || thread == NULL) - return false; - - GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); + Process *process = exe_ctx.GetProcessPtr(); + Thread *thread = exe_ctx.GetThreadPtr(); + if (process == NULL || thread == NULL) + return false; - InvalidateIfNeeded(false); + GDBRemoteCommunicationClient &gdb_comm( + ((ProcessGDBRemote *)process)->GetGDBRemote()); - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + InvalidateIfNeeded(false); - if (!GetRegisterIsValid(reg)) - { - if (m_read_all_at_once) - { - if (DataBufferSP buffer_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) - { - memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()), buffer_sp->GetBytes(), - std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize())); - if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) - { - SetAllRegisterValid(true); - return true; - } - } - return false; - } - if (reg_info->value_regs) - { - // Process this composite register request by delegating to the constituent - // primordial registers. - - // Index of the primordial register. - bool success = true; - for (uint32_t idx = 0; success; ++idx) - { - const uint32_t prim_reg = reg_info->value_regs[idx]; - if (prim_reg == LLDB_INVALID_REGNUM) - break; - // We have a valid primordial register as our constituent. - // Grab the corresponding register info. - const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg); - if (prim_reg_info == NULL) - success = false; - else - { - // Read the containing register if it hasn't already been read - if (!GetRegisterIsValid(prim_reg)) - success = GetPrimordialRegister(prim_reg_info, gdb_comm); - } - } + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - if (success) - { - // If we reach this point, all primordial register requests have succeeded. - // Validate this composite register. - SetRegisterIsValid (reg_info, true); - } + if (!GetRegisterIsValid(reg)) { + if (m_read_all_at_once) { + if (DataBufferSP buffer_sp = + gdb_comm.ReadAllRegisters(m_thread.GetProtocolID())) { + memcpy(const_cast<uint8_t *>(m_reg_data.GetDataStart()), + buffer_sp->GetBytes(), + std::min(buffer_sp->GetByteSize(), m_reg_data.GetByteSize())); + if (buffer_sp->GetByteSize() >= m_reg_data.GetByteSize()) { + SetAllRegisterValid(true); + return true; } - else - { - // Get each register individually - GetPrimordialRegister(reg_info, gdb_comm); + } + return false; + } + if (reg_info->value_regs) { + // Process this composite register request by delegating to the + // constituent + // primordial registers. + + // Index of the primordial register. + bool success = true; + for (uint32_t idx = 0; success; ++idx) { + const uint32_t prim_reg = reg_info->value_regs[idx]; + if (prim_reg == LLDB_INVALID_REGNUM) + break; + // We have a valid primordial register as our constituent. + // Grab the corresponding register info. + const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg); + if (prim_reg_info == NULL) + success = false; + else { + // Read the containing register if it hasn't already been read + if (!GetRegisterIsValid(prim_reg)) + success = GetPrimordialRegister(prim_reg_info, gdb_comm); } - - // Make sure we got a valid register value after reading it - if (!GetRegisterIsValid(reg)) - return false; + } + + if (success) { + // If we reach this point, all primordial register requests have + // succeeded. + // Validate this composite register. + SetRegisterIsValid(reg_info, true); + } + } else { + // Get each register individually + GetPrimordialRegister(reg_info, gdb_comm); } - if (&data != &m_reg_data) - { -#if defined (LLDB_CONFIGURATION_DEBUG) - assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size); -#endif - // If our register context and our register info disagree, which should never happen, don't - // read past the end of the buffer. - if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) - return false; - - // If we aren't extracting into our own buffer (which - // only happens when this function is called from - // ReadRegisterValue(uint32_t, Scalar&)) then - // we transfer bytes from our buffer into the data - // buffer that was passed in - - data.SetByteOrder (m_reg_data.GetByteOrder()); - data.SetData (m_reg_data, reg_info->byte_offset, reg_info->byte_size); - } - return true; + // Make sure we got a valid register value after reading it + if (!GetRegisterIsValid(reg)) + return false; + } + + if (&data != &m_reg_data) { +#if defined(LLDB_CONFIGURATION_DEBUG) + assert(m_reg_data.GetByteSize() >= + reg_info->byte_offset + reg_info->byte_size); +#endif + // If our register context and our register info disagree, which should + // never happen, don't + // read past the end of the buffer. + if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) + return false; + + // If we aren't extracting into our own buffer (which + // only happens when this function is called from + // ReadRegisterValue(uint32_t, Scalar&)) then + // we transfer bytes from our buffer into the data + // buffer that was passed in + + data.SetByteOrder(m_reg_data.GetByteOrder()); + data.SetData(m_reg_data, reg_info->byte_offset, reg_info->byte_size); + } + return true; } -bool -GDBRemoteRegisterContext::WriteRegister (const RegisterInfo *reg_info, - const RegisterValue &value) -{ - DataExtractor data; - if (value.GetData (data)) - return WriteRegisterBytes (reg_info, data, 0); - return false; +bool GDBRemoteRegisterContext::WriteRegister(const RegisterInfo *reg_info, + const RegisterValue &value) { + DataExtractor data; + if (value.GetData(data)) + return WriteRegisterBytes(reg_info, data, 0); + return false; } // Helper function for GDBRemoteRegisterContext::WriteRegisterBytes(). -bool -GDBRemoteRegisterContext::SetPrimordialRegister(const RegisterInfo *reg_info, - GDBRemoteCommunicationClient &gdb_comm) -{ - StreamString packet; - StringExtractorGDBRemote response; - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - // Invalidate just this register - SetRegisterIsValid(reg, false); - - return gdb_comm.WriteRegister( - m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], - {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size), reg_info->byte_size}); +bool GDBRemoteRegisterContext::SetPrimordialRegister( + const RegisterInfo *reg_info, GDBRemoteCommunicationClient &gdb_comm) { + StreamString packet; + StringExtractorGDBRemote response; + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + // Invalidate just this register + SetRegisterIsValid(reg, false); + + return gdb_comm.WriteRegister( + m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], + {m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size), + reg_info->byte_size}); } -bool -GDBRemoteRegisterContext::WriteRegisterBytes (const RegisterInfo *reg_info, DataExtractor &data, uint32_t data_offset) -{ - ExecutionContext exe_ctx (CalculateThread()); +bool GDBRemoteRegisterContext::WriteRegisterBytes(const RegisterInfo *reg_info, + DataExtractor &data, + uint32_t data_offset) { + ExecutionContext exe_ctx(CalculateThread()); - Process *process = exe_ctx.GetProcessPtr(); - Thread *thread = exe_ctx.GetThreadPtr(); - if (process == NULL || thread == NULL) - return false; + Process *process = exe_ctx.GetProcessPtr(); + Thread *thread = exe_ctx.GetThreadPtr(); + if (process == NULL || thread == NULL) + return false; - GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); + GDBRemoteCommunicationClient &gdb_comm( + ((ProcessGDBRemote *)process)->GetGDBRemote()); -#if defined (LLDB_CONFIGURATION_DEBUG) - assert (m_reg_data.GetByteSize() >= reg_info->byte_offset + reg_info->byte_size); +#if defined(LLDB_CONFIGURATION_DEBUG) + assert(m_reg_data.GetByteSize() >= + reg_info->byte_offset + reg_info->byte_size); #endif - // If our register context and our register info disagree, which should never happen, don't - // overwrite past the end of the buffer. - if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) - return false; + // If our register context and our register info disagree, which should never + // happen, don't + // overwrite past the end of the buffer. + if (m_reg_data.GetByteSize() < reg_info->byte_offset + reg_info->byte_size) + return false; - // Grab a pointer to where we are going to put this register - uint8_t *dst = const_cast<uint8_t*>(m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); + // Grab a pointer to where we are going to put this register + uint8_t *dst = const_cast<uint8_t *>( + m_reg_data.PeekData(reg_info->byte_offset, reg_info->byte_size)); - if (dst == NULL) - return false; + if (dst == NULL) + return false; + + if (data.CopyByteOrderedData(data_offset, // src offset + reg_info->byte_size, // src length + dst, // dst + reg_info->byte_size, // dst length + m_reg_data.GetByteOrder())) // dst byte order + { + GDBRemoteClientBase::Lock lock(gdb_comm, false); + if (lock) { + if (m_read_all_at_once) { + // Invalidate all register values + InvalidateIfNeeded(true); + // Set all registers in one packet + if (gdb_comm.WriteAllRegisters( + m_thread.GetProtocolID(), + {m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())})) - if (data.CopyByteOrderedData (data_offset, // src offset - reg_info->byte_size, // src length - dst, // dst - reg_info->byte_size, // dst length - m_reg_data.GetByteOrder())) // dst byte order - { - GDBRemoteClientBase::Lock lock(gdb_comm, false); - if (lock) { - if (m_read_all_at_once) - { - // Invalidate all register values - InvalidateIfNeeded (true); - - // Set all registers in one packet - if (gdb_comm.WriteAllRegisters(m_thread.GetProtocolID(), - {m_reg_data.GetDataStart(), size_t(m_reg_data.GetByteSize())})) - - { - SetAllRegisterValid (false); - return true; - } - } - else - { - bool success = true; - - if (reg_info->value_regs) - { - // This register is part of another register. In this case we read the actual - // register data for any "value_regs", and once all that data is read, we will - // have enough data in our register context bytes for the value of this register - - // Invalidate this composite register first. - - for (uint32_t idx = 0; success; ++idx) - { - const uint32_t reg = reg_info->value_regs[idx]; - if (reg == LLDB_INVALID_REGNUM) - break; - // We have a valid primordial register as our constituent. - // Grab the corresponding register info. - const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg); - if (value_reg_info == NULL) - success = false; - else - success = SetPrimordialRegister(value_reg_info, gdb_comm); - } - } - else - { - // This is an actual register, write it - success = SetPrimordialRegister(reg_info, gdb_comm); - } - - // Check if writing this register will invalidate any other register values? - // If so, invalidate them - if (reg_info->invalidate_regs) - { - for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0]; - reg != LLDB_INVALID_REGNUM; - reg = reg_info->invalidate_regs[++idx]) - { - SetRegisterIsValid(reg, false); - } - } - - return success; - } + SetAllRegisterValid(false); + return true; } - else - { - Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); - if (log) - { - if (log->GetVerbose()) - { - StreamString strm; - gdb_comm.DumpHistory(strm); - log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\":\n%s", reg_info->name, strm.GetData()); - } - else - log->Printf("error: failed to get packet sequence mutex, not sending write register for \"%s\"", reg_info->name); - } + } else { + bool success = true; + + if (reg_info->value_regs) { + // This register is part of another register. In this case we read the + // actual + // register data for any "value_regs", and once all that data is read, + // we will + // have enough data in our register context bytes for the value of + // this register + + // Invalidate this composite register first. + + for (uint32_t idx = 0; success; ++idx) { + const uint32_t reg = reg_info->value_regs[idx]; + if (reg == LLDB_INVALID_REGNUM) + break; + // We have a valid primordial register as our constituent. + // Grab the corresponding register info. + const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg); + if (value_reg_info == NULL) + success = false; + else + success = SetPrimordialRegister(value_reg_info, gdb_comm); + } + } else { + // This is an actual register, write it + success = SetPrimordialRegister(reg_info, gdb_comm); } + + // Check if writing this register will invalidate any other register + // values? + // If so, invalidate them + if (reg_info->invalidate_regs) { + for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0]; + reg != LLDB_INVALID_REGNUM; + reg = reg_info->invalidate_regs[++idx]) { + SetRegisterIsValid(reg, false); + } + } + + return success; + } + } else { + Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD | + GDBR_LOG_PACKETS)); + if (log) { + if (log->GetVerbose()) { + StreamString strm; + gdb_comm.DumpHistory(strm); + log->Printf("error: failed to get packet sequence mutex, not sending " + "write register for \"%s\":\n%s", + reg_info->name, strm.GetData()); + } else + log->Printf("error: failed to get packet sequence mutex, not sending " + "write register for \"%s\"", + reg_info->name); + } } + } + return false; +} + +bool GDBRemoteRegisterContext::ReadAllRegisterValues( + RegisterCheckpoint ®_checkpoint) { + ExecutionContext exe_ctx(CalculateThread()); + + Process *process = exe_ctx.GetProcessPtr(); + Thread *thread = exe_ctx.GetThreadPtr(); + if (process == NULL || thread == NULL) return false; + + GDBRemoteCommunicationClient &gdb_comm( + ((ProcessGDBRemote *)process)->GetGDBRemote()); + + uint32_t save_id = 0; + if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) { + reg_checkpoint.SetID(save_id); + reg_checkpoint.GetData().reset(); + return true; + } else { + reg_checkpoint.SetID(0); // Invalid save ID is zero + return ReadAllRegisterValues(reg_checkpoint.GetData()); + } } -bool -GDBRemoteRegisterContext::ReadAllRegisterValues (RegisterCheckpoint ®_checkpoint) -{ - ExecutionContext exe_ctx (CalculateThread()); - +bool GDBRemoteRegisterContext::WriteAllRegisterValues( + const RegisterCheckpoint ®_checkpoint) { + uint32_t save_id = reg_checkpoint.GetID(); + if (save_id != 0) { + ExecutionContext exe_ctx(CalculateThread()); + Process *process = exe_ctx.GetProcessPtr(); Thread *thread = exe_ctx.GetThreadPtr(); if (process == NULL || thread == NULL) - return false; - - GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); - - uint32_t save_id = 0; - if (gdb_comm.SaveRegisterState(thread->GetProtocolID(), save_id)) - { - reg_checkpoint.SetID(save_id); - reg_checkpoint.GetData().reset(); - return true; - } - else - { - reg_checkpoint.SetID(0); // Invalid save ID is zero - return ReadAllRegisterValues(reg_checkpoint.GetData()); - } -} + return false; -bool -GDBRemoteRegisterContext::WriteAllRegisterValues (const RegisterCheckpoint ®_checkpoint) -{ - uint32_t save_id = reg_checkpoint.GetID(); - if (save_id != 0) - { - ExecutionContext exe_ctx (CalculateThread()); - - Process *process = exe_ctx.GetProcessPtr(); - Thread *thread = exe_ctx.GetThreadPtr(); - if (process == NULL || thread == NULL) - return false; - - GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); - - return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id); - } - else - { - return WriteAllRegisterValues(reg_checkpoint.GetData()); - } + GDBRemoteCommunicationClient &gdb_comm( + ((ProcessGDBRemote *)process)->GetGDBRemote()); + + return gdb_comm.RestoreRegisterState(m_thread.GetProtocolID(), save_id); + } else { + return WriteAllRegisterValues(reg_checkpoint.GetData()); + } } -bool -GDBRemoteRegisterContext::ReadAllRegisterValues (lldb::DataBufferSP &data_sp) -{ - ExecutionContext exe_ctx (CalculateThread()); +bool GDBRemoteRegisterContext::ReadAllRegisterValues( + lldb::DataBufferSP &data_sp) { + ExecutionContext exe_ctx(CalculateThread()); - Process *process = exe_ctx.GetProcessPtr(); - Thread *thread = exe_ctx.GetThreadPtr(); - if (process == NULL || thread == NULL) - return false; + Process *process = exe_ctx.GetProcessPtr(); + Thread *thread = exe_ctx.GetThreadPtr(); + if (process == NULL || thread == NULL) + return false; - GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); + GDBRemoteCommunicationClient &gdb_comm( + ((ProcessGDBRemote *)process)->GetGDBRemote()); - const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false; + const bool use_g_packet = + gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false; - GDBRemoteClientBase::Lock lock(gdb_comm, false); - if (lock) - { - if (gdb_comm.SyncThreadState(m_thread.GetProtocolID())) - InvalidateAllRegisters(); + GDBRemoteClientBase::Lock lock(gdb_comm, false); + if (lock) { + if (gdb_comm.SyncThreadState(m_thread.GetProtocolID())) + InvalidateAllRegisters(); - if (use_g_packet && (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID()))) - return true; + if (use_g_packet && + (data_sp = gdb_comm.ReadAllRegisters(m_thread.GetProtocolID()))) + return true; - // We're going to read each register - // individually and store them as binary data in a buffer. - const RegisterInfo *reg_info; + // We're going to read each register + // individually and store them as binary data in a buffer. + const RegisterInfo *reg_info; - for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) - { - if (reg_info->value_regs) // skip registers that are slices of real registers - continue; - ReadRegisterBytes(reg_info, m_reg_data); - // ReadRegisterBytes saves the contents of the register in to the m_reg_data buffer - } - data_sp.reset(new DataBufferHeap(m_reg_data.GetDataStart(), m_reg_info.GetRegisterDataByteSize())); - return true; + for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) { + if (reg_info + ->value_regs) // skip registers that are slices of real registers + continue; + ReadRegisterBytes(reg_info, m_reg_data); + // ReadRegisterBytes saves the contents of the register in to the + // m_reg_data buffer } - else - { - - Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); - if (log) - { - if (log->GetVerbose()) - { - StreamString strm; - gdb_comm.DumpHistory(strm); - log->Printf("error: failed to get packet sequence mutex, not sending read all registers:\n%s", strm.GetData()); - } - else - log->Printf("error: failed to get packet sequence mutex, not sending read all registers"); - } + data_sp.reset(new DataBufferHeap(m_reg_data.GetDataStart(), + m_reg_info.GetRegisterDataByteSize())); + return true; + } else { + + Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD | + GDBR_LOG_PACKETS)); + if (log) { + if (log->GetVerbose()) { + StreamString strm; + gdb_comm.DumpHistory(strm); + log->Printf("error: failed to get packet sequence mutex, not sending " + "read all registers:\n%s", + strm.GetData()); + } else + log->Printf("error: failed to get packet sequence mutex, not sending " + "read all registers"); } + } - data_sp.reset(); - return false; + data_sp.reset(); + return false; } -bool -GDBRemoteRegisterContext::WriteAllRegisterValues (const lldb::DataBufferSP &data_sp) -{ - if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0) - return false; +bool GDBRemoteRegisterContext::WriteAllRegisterValues( + const lldb::DataBufferSP &data_sp) { + if (!data_sp || data_sp->GetBytes() == NULL || data_sp->GetByteSize() == 0) + return false; - ExecutionContext exe_ctx (CalculateThread()); + ExecutionContext exe_ctx(CalculateThread()); - Process *process = exe_ctx.GetProcessPtr(); - Thread *thread = exe_ctx.GetThreadPtr(); - if (process == NULL || thread == NULL) - return false; + Process *process = exe_ctx.GetProcessPtr(); + Thread *thread = exe_ctx.GetThreadPtr(); + if (process == NULL || thread == NULL) + return false; - GDBRemoteCommunicationClient &gdb_comm (((ProcessGDBRemote *)process)->GetGDBRemote()); + GDBRemoteCommunicationClient &gdb_comm( + ((ProcessGDBRemote *)process)->GetGDBRemote()); - const bool use_g_packet = gdb_comm.AvoidGPackets ((ProcessGDBRemote *)process) == false; + const bool use_g_packet = + gdb_comm.AvoidGPackets((ProcessGDBRemote *)process) == false; - GDBRemoteClientBase::Lock lock(gdb_comm, false); - if (lock) - { - // The data_sp contains the G response packet. - if (use_g_packet) - { - if (gdb_comm.WriteAllRegisters(m_thread.GetProtocolID(), - {data_sp->GetBytes(), size_t(data_sp->GetByteSize())})) - return true; - - uint32_t num_restored = 0; - // We need to manually go through all of the registers and - // restore them manually - DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(), m_reg_data.GetAddressByteSize()); - - const RegisterInfo *reg_info; - - // The g packet contents may either include the slice registers (registers defined in - // terms of other registers, e.g. eax is a subset of rax) or not. The slice registers - // should NOT be in the g packet, but some implementations may incorrectly include them. - // - // If the slice registers are included in the packet, we must step over the slice registers - // when parsing the packet -- relying on the RegisterInfo byte_offset field would be incorrect. - // If the slice registers are not included, then using the byte_offset values into the - // data buffer is the best way to find individual register values. - - uint64_t size_including_slice_registers = 0; - uint64_t size_not_including_slice_registers = 0; - uint64_t size_by_highest_offset = 0; - - for (uint32_t reg_idx = 0; (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; ++reg_idx) - { - size_including_slice_registers += reg_info->byte_size; - if (reg_info->value_regs == NULL) - size_not_including_slice_registers += reg_info->byte_size; - if (reg_info->byte_offset >= size_by_highest_offset) - size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size; - } + GDBRemoteClientBase::Lock lock(gdb_comm, false); + if (lock) { + // The data_sp contains the G response packet. + if (use_g_packet) { + if (gdb_comm.WriteAllRegisters( + m_thread.GetProtocolID(), + {data_sp->GetBytes(), size_t(data_sp->GetByteSize())})) + return true; - bool use_byte_offset_into_buffer; - if (size_by_highest_offset == restore_data.GetByteSize()) - { - // The size of the packet agrees with the highest offset: + size in the register file - use_byte_offset_into_buffer = true; - } - else if (size_not_including_slice_registers == restore_data.GetByteSize()) - { - // The size of the packet is the same as concatenating all of the registers sequentially, - // skipping the slice registers - use_byte_offset_into_buffer = true; - } - else if (size_including_slice_registers == restore_data.GetByteSize()) - { - // The slice registers are present in the packet (when they shouldn't be). - // Don't try to use the RegisterInfo byte_offset into the restore_data, it will - // point to the wrong place. - use_byte_offset_into_buffer = false; - } - else - { - // None of our expected sizes match the actual g packet data we're looking at. - // The most conservative approach here is to use the running total byte offset. - use_byte_offset_into_buffer = false; - } + uint32_t num_restored = 0; + // We need to manually go through all of the registers and + // restore them manually + DataExtractor restore_data(data_sp, m_reg_data.GetByteOrder(), + m_reg_data.GetAddressByteSize()); + + const RegisterInfo *reg_info; + + // The g packet contents may either include the slice registers (registers + // defined in + // terms of other registers, e.g. eax is a subset of rax) or not. The + // slice registers + // should NOT be in the g packet, but some implementations may incorrectly + // include them. + // + // If the slice registers are included in the packet, we must step over + // the slice registers + // when parsing the packet -- relying on the RegisterInfo byte_offset + // field would be incorrect. + // If the slice registers are not included, then using the byte_offset + // values into the + // data buffer is the best way to find individual register values. + + uint64_t size_including_slice_registers = 0; + uint64_t size_not_including_slice_registers = 0; + uint64_t size_by_highest_offset = 0; + + for (uint32_t reg_idx = 0; + (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; ++reg_idx) { + size_including_slice_registers += reg_info->byte_size; + if (reg_info->value_regs == NULL) + size_not_including_slice_registers += reg_info->byte_size; + if (reg_info->byte_offset >= size_by_highest_offset) + size_by_highest_offset = reg_info->byte_offset + reg_info->byte_size; + } + + bool use_byte_offset_into_buffer; + if (size_by_highest_offset == restore_data.GetByteSize()) { + // The size of the packet agrees with the highest offset: + size in the + // register file + use_byte_offset_into_buffer = true; + } else if (size_not_including_slice_registers == + restore_data.GetByteSize()) { + // The size of the packet is the same as concatenating all of the + // registers sequentially, + // skipping the slice registers + use_byte_offset_into_buffer = true; + } else if (size_including_slice_registers == restore_data.GetByteSize()) { + // The slice registers are present in the packet (when they shouldn't + // be). + // Don't try to use the RegisterInfo byte_offset into the restore_data, + // it will + // point to the wrong place. + use_byte_offset_into_buffer = false; + } else { + // None of our expected sizes match the actual g packet data we're + // looking at. + // The most conservative approach here is to use the running total byte + // offset. + use_byte_offset_into_buffer = false; + } + + // In case our register definitions don't include the correct offsets, + // keep track of the size of each reg & compute offset based on that. + uint32_t running_byte_offset = 0; + for (uint32_t reg_idx = 0; + (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; + ++reg_idx, running_byte_offset += reg_info->byte_size) { + // Skip composite aka slice registers (e.g. eax is a slice of rax). + if (reg_info->value_regs) + continue; - // In case our register definitions don't include the correct offsets, - // keep track of the size of each reg & compute offset based on that. - uint32_t running_byte_offset = 0; - for (uint32_t reg_idx = 0; (reg_info = GetRegisterInfoAtIndex(reg_idx)) != NULL; - ++reg_idx, running_byte_offset += reg_info->byte_size) - { - // Skip composite aka slice registers (e.g. eax is a slice of rax). - if (reg_info->value_regs) - continue; - - const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; - - uint32_t register_offset; - if (use_byte_offset_into_buffer) - { - register_offset = reg_info->byte_offset; - } - else - { - register_offset = running_byte_offset; - } - - const uint32_t reg_byte_size = reg_info->byte_size; - - const uint8_t *restore_src = restore_data.PeekData(register_offset, reg_byte_size); - if (restore_src) - { - SetRegisterIsValid(reg, false); - if (gdb_comm.WriteRegister(m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], - {restore_src, reg_byte_size})) - ++num_restored; - } - } - return num_restored > 0; + const uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; + + uint32_t register_offset; + if (use_byte_offset_into_buffer) { + register_offset = reg_info->byte_offset; + } else { + register_offset = running_byte_offset; } - else - { - // For the use_g_packet == false case, we're going to write each register - // individually. The data buffer is binary data in this case, instead of - // ascii characters. - - bool arm64_debugserver = false; - if (m_thread.GetProcess().get()) - { - const ArchSpec &arch = m_thread.GetProcess()->GetTarget().GetArchitecture(); - if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 && - arch.GetTriple().getVendor() == llvm::Triple::Apple && - arch.GetTriple().getOS() == llvm::Triple::IOS) - { - arm64_debugserver = true; - } - } - uint32_t num_restored = 0; - const RegisterInfo *reg_info; - for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; i++) - { - if (reg_info->value_regs) // skip registers that are slices of real registers - continue; - // Skip the fpsr and fpcr floating point status/control register writing to - // work around a bug in an older version of debugserver that would lead to - // register context corruption when writing fpsr/fpcr. - if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 || strcmp(reg_info->name, "fpcr") == 0)) - { - continue; - } - - SetRegisterIsValid(reg_info, false); - if (gdb_comm.WriteRegister(m_thread.GetProtocolID(), reg_info->kinds[eRegisterKindProcessPlugin], - {data_sp->GetBytes() + reg_info->byte_offset, reg_info->byte_size})) - ++num_restored; - } - return num_restored > 0; + + const uint32_t reg_byte_size = reg_info->byte_size; + + const uint8_t *restore_src = + restore_data.PeekData(register_offset, reg_byte_size); + if (restore_src) { + SetRegisterIsValid(reg, false); + if (gdb_comm.WriteRegister( + m_thread.GetProtocolID(), + reg_info->kinds[eRegisterKindProcessPlugin], + {restore_src, reg_byte_size})) + ++num_restored; } - } - else - { - Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS)); - if (log) - { - if (log->GetVerbose()) - { - StreamString strm; - gdb_comm.DumpHistory(strm); - log->Printf("error: failed to get packet sequence mutex, not sending write all registers:\n%s", strm.GetData()); - } - else - log->Printf("error: failed to get packet sequence mutex, not sending write all registers"); + } + return num_restored > 0; + } else { + // For the use_g_packet == false case, we're going to write each register + // individually. The data buffer is binary data in this case, instead of + // ascii characters. + + bool arm64_debugserver = false; + if (m_thread.GetProcess().get()) { + const ArchSpec &arch = + m_thread.GetProcess()->GetTarget().GetArchitecture(); + if (arch.IsValid() && arch.GetMachine() == llvm::Triple::aarch64 && + arch.GetTriple().getVendor() == llvm::Triple::Apple && + arch.GetTriple().getOS() == llvm::Triple::IOS) { + arm64_debugserver = true; + } + } + uint32_t num_restored = 0; + const RegisterInfo *reg_info; + for (uint32_t i = 0; (reg_info = GetRegisterInfoAtIndex(i)) != NULL; + i++) { + if (reg_info->value_regs) // skip registers that are slices of real + // registers + continue; + // Skip the fpsr and fpcr floating point status/control register writing + // to + // work around a bug in an older version of debugserver that would lead + // to + // register context corruption when writing fpsr/fpcr. + if (arm64_debugserver && (strcmp(reg_info->name, "fpsr") == 0 || + strcmp(reg_info->name, "fpcr") == 0)) { + continue; } + + SetRegisterIsValid(reg_info, false); + if (gdb_comm.WriteRegister(m_thread.GetProtocolID(), + reg_info->kinds[eRegisterKindProcessPlugin], + {data_sp->GetBytes() + reg_info->byte_offset, + reg_info->byte_size})) + ++num_restored; + } + return num_restored > 0; } - return false; + } else { + Log *log(ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet(GDBR_LOG_THREAD | + GDBR_LOG_PACKETS)); + if (log) { + if (log->GetVerbose()) { + StreamString strm; + gdb_comm.DumpHistory(strm); + log->Printf("error: failed to get packet sequence mutex, not sending " + "write all registers:\n%s", + strm.GetData()); + } else + log->Printf("error: failed to get packet sequence mutex, not sending " + "write all registers"); + } + } + return false; } - -uint32_t -GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber (lldb::RegisterKind kind, uint32_t num) -{ - return m_reg_info.ConvertRegisterKindToRegisterNumber (kind, num); +uint32_t GDBRemoteRegisterContext::ConvertRegisterKindToRegisterNumber( + lldb::RegisterKind kind, uint32_t num) { + return m_reg_info.ConvertRegisterKindToRegisterNumber(kind, num); } - -void -GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) -{ - // For Advanced SIMD and VFP register mapping. - static uint32_t g_d0_regs[] = { 26, 27, LLDB_INVALID_REGNUM }; // (s0, s1) - static uint32_t g_d1_regs[] = { 28, 29, LLDB_INVALID_REGNUM }; // (s2, s3) - static uint32_t g_d2_regs[] = { 30, 31, LLDB_INVALID_REGNUM }; // (s4, s5) - static uint32_t g_d3_regs[] = { 32, 33, LLDB_INVALID_REGNUM }; // (s6, s7) - static uint32_t g_d4_regs[] = { 34, 35, LLDB_INVALID_REGNUM }; // (s8, s9) - static uint32_t g_d5_regs[] = { 36, 37, LLDB_INVALID_REGNUM }; // (s10, s11) - static uint32_t g_d6_regs[] = { 38, 39, LLDB_INVALID_REGNUM }; // (s12, s13) - static uint32_t g_d7_regs[] = { 40, 41, LLDB_INVALID_REGNUM }; // (s14, s15) - static uint32_t g_d8_regs[] = { 42, 43, LLDB_INVALID_REGNUM }; // (s16, s17) - static uint32_t g_d9_regs[] = { 44, 45, LLDB_INVALID_REGNUM }; // (s18, s19) - static uint32_t g_d10_regs[] = { 46, 47, LLDB_INVALID_REGNUM }; // (s20, s21) - static uint32_t g_d11_regs[] = { 48, 49, LLDB_INVALID_REGNUM }; // (s22, s23) - static uint32_t g_d12_regs[] = { 50, 51, LLDB_INVALID_REGNUM }; // (s24, s25) - static uint32_t g_d13_regs[] = { 52, 53, LLDB_INVALID_REGNUM }; // (s26, s27) - static uint32_t g_d14_regs[] = { 54, 55, LLDB_INVALID_REGNUM }; // (s28, s29) - static uint32_t g_d15_regs[] = { 56, 57, LLDB_INVALID_REGNUM }; // (s30, s31) - static uint32_t g_q0_regs[] = { 26, 27, 28, 29, LLDB_INVALID_REGNUM }; // (d0, d1) -> (s0, s1, s2, s3) - static uint32_t g_q1_regs[] = { 30, 31, 32, 33, LLDB_INVALID_REGNUM }; // (d2, d3) -> (s4, s5, s6, s7) - static uint32_t g_q2_regs[] = { 34, 35, 36, 37, LLDB_INVALID_REGNUM }; // (d4, d5) -> (s8, s9, s10, s11) - static uint32_t g_q3_regs[] = { 38, 39, 40, 41, LLDB_INVALID_REGNUM }; // (d6, d7) -> (s12, s13, s14, s15) - static uint32_t g_q4_regs[] = { 42, 43, 44, 45, LLDB_INVALID_REGNUM }; // (d8, d9) -> (s16, s17, s18, s19) - static uint32_t g_q5_regs[] = { 46, 47, 48, 49, LLDB_INVALID_REGNUM }; // (d10, d11) -> (s20, s21, s22, s23) - static uint32_t g_q6_regs[] = { 50, 51, 52, 53, LLDB_INVALID_REGNUM }; // (d12, d13) -> (s24, s25, s26, s27) - static uint32_t g_q7_regs[] = { 54, 55, 56, 57, LLDB_INVALID_REGNUM }; // (d14, d15) -> (s28, s29, s30, s31) - static uint32_t g_q8_regs[] = { 59, 60, LLDB_INVALID_REGNUM }; // (d16, d17) - static uint32_t g_q9_regs[] = { 61, 62, LLDB_INVALID_REGNUM }; // (d18, d19) - static uint32_t g_q10_regs[] = { 63, 64, LLDB_INVALID_REGNUM }; // (d20, d21) - static uint32_t g_q11_regs[] = { 65, 66, LLDB_INVALID_REGNUM }; // (d22, d23) - static uint32_t g_q12_regs[] = { 67, 68, LLDB_INVALID_REGNUM }; // (d24, d25) - static uint32_t g_q13_regs[] = { 69, 70, LLDB_INVALID_REGNUM }; // (d26, d27) - static uint32_t g_q14_regs[] = { 71, 72, LLDB_INVALID_REGNUM }; // (d28, d29) - static uint32_t g_q15_regs[] = { 73, 74, LLDB_INVALID_REGNUM }; // (d30, d31) - - // This is our array of composite registers, with each element coming from the above register mappings. - static uint32_t *g_composites[] = { - g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs, g_d6_regs, g_d7_regs, - g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs, g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs, - g_q0_regs, g_q1_regs, g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs, - g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs, g_q14_regs, g_q15_regs - }; - - // clang-format off +void GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) { + // For Advanced SIMD and VFP register mapping. + static uint32_t g_d0_regs[] = {26, 27, LLDB_INVALID_REGNUM}; // (s0, s1) + static uint32_t g_d1_regs[] = {28, 29, LLDB_INVALID_REGNUM}; // (s2, s3) + static uint32_t g_d2_regs[] = {30, 31, LLDB_INVALID_REGNUM}; // (s4, s5) + static uint32_t g_d3_regs[] = {32, 33, LLDB_INVALID_REGNUM}; // (s6, s7) + static uint32_t g_d4_regs[] = {34, 35, LLDB_INVALID_REGNUM}; // (s8, s9) + static uint32_t g_d5_regs[] = {36, 37, LLDB_INVALID_REGNUM}; // (s10, s11) + static uint32_t g_d6_regs[] = {38, 39, LLDB_INVALID_REGNUM}; // (s12, s13) + static uint32_t g_d7_regs[] = {40, 41, LLDB_INVALID_REGNUM}; // (s14, s15) + static uint32_t g_d8_regs[] = {42, 43, LLDB_INVALID_REGNUM}; // (s16, s17) + static uint32_t g_d9_regs[] = {44, 45, LLDB_INVALID_REGNUM}; // (s18, s19) + static uint32_t g_d10_regs[] = {46, 47, LLDB_INVALID_REGNUM}; // (s20, s21) + static uint32_t g_d11_regs[] = {48, 49, LLDB_INVALID_REGNUM}; // (s22, s23) + static uint32_t g_d12_regs[] = {50, 51, LLDB_INVALID_REGNUM}; // (s24, s25) + static uint32_t g_d13_regs[] = {52, 53, LLDB_INVALID_REGNUM}; // (s26, s27) + static uint32_t g_d14_regs[] = {54, 55, LLDB_INVALID_REGNUM}; // (s28, s29) + static uint32_t g_d15_regs[] = {56, 57, LLDB_INVALID_REGNUM}; // (s30, s31) + static uint32_t g_q0_regs[] = { + 26, 27, 28, 29, LLDB_INVALID_REGNUM}; // (d0, d1) -> (s0, s1, s2, s3) + static uint32_t g_q1_regs[] = { + 30, 31, 32, 33, LLDB_INVALID_REGNUM}; // (d2, d3) -> (s4, s5, s6, s7) + static uint32_t g_q2_regs[] = { + 34, 35, 36, 37, LLDB_INVALID_REGNUM}; // (d4, d5) -> (s8, s9, s10, s11) + static uint32_t g_q3_regs[] = { + 38, 39, 40, 41, LLDB_INVALID_REGNUM}; // (d6, d7) -> (s12, s13, s14, s15) + static uint32_t g_q4_regs[] = { + 42, 43, 44, 45, LLDB_INVALID_REGNUM}; // (d8, d9) -> (s16, s17, s18, s19) + static uint32_t g_q5_regs[] = { + 46, 47, 48, 49, + LLDB_INVALID_REGNUM}; // (d10, d11) -> (s20, s21, s22, s23) + static uint32_t g_q6_regs[] = { + 50, 51, 52, 53, + LLDB_INVALID_REGNUM}; // (d12, d13) -> (s24, s25, s26, s27) + static uint32_t g_q7_regs[] = { + 54, 55, 56, 57, + LLDB_INVALID_REGNUM}; // (d14, d15) -> (s28, s29, s30, s31) + static uint32_t g_q8_regs[] = {59, 60, LLDB_INVALID_REGNUM}; // (d16, d17) + static uint32_t g_q9_regs[] = {61, 62, LLDB_INVALID_REGNUM}; // (d18, d19) + static uint32_t g_q10_regs[] = {63, 64, LLDB_INVALID_REGNUM}; // (d20, d21) + static uint32_t g_q11_regs[] = {65, 66, LLDB_INVALID_REGNUM}; // (d22, d23) + static uint32_t g_q12_regs[] = {67, 68, LLDB_INVALID_REGNUM}; // (d24, d25) + static uint32_t g_q13_regs[] = {69, 70, LLDB_INVALID_REGNUM}; // (d26, d27) + static uint32_t g_q14_regs[] = {71, 72, LLDB_INVALID_REGNUM}; // (d28, d29) + static uint32_t g_q15_regs[] = {73, 74, LLDB_INVALID_REGNUM}; // (d30, d31) + + // This is our array of composite registers, with each element coming from the + // above register mappings. + static uint32_t *g_composites[] = { + g_d0_regs, g_d1_regs, g_d2_regs, g_d3_regs, g_d4_regs, g_d5_regs, + g_d6_regs, g_d7_regs, g_d8_regs, g_d9_regs, g_d10_regs, g_d11_regs, + g_d12_regs, g_d13_regs, g_d14_regs, g_d15_regs, g_q0_regs, g_q1_regs, + g_q2_regs, g_q3_regs, g_q4_regs, g_q5_regs, g_q6_regs, g_q7_regs, + g_q8_regs, g_q9_regs, g_q10_regs, g_q11_regs, g_q12_regs, g_q13_regs, + g_q14_regs, g_q15_regs}; + + // clang-format off static RegisterInfo g_register_infos[] = { // NAME ALT SZ OFF ENCODING FORMAT EH_FRAME DWARF GENERIC PROCESS PLUGIN LLDB VALUE REGS INVALIDATE REGS SIZE EXPR SIZE LEN // ====== ====== === === ============= ========== =================== =================== ====================== ============= ==== ========== =============== ========= ======== @@ -902,121 +875,113 @@ GDBRemoteDynamicRegisterInfo::HardcodeARMRegisters(bool from_scratch) { "q14", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q14, LLDB_INVALID_REGNUM, 105, 105 }, g_q14_regs, nullptr, nullptr, 0 }, { "q15", nullptr, 16, 0, eEncodingVector, eFormatVectorOfUInt8, { LLDB_INVALID_REGNUM, dwarf_q15, LLDB_INVALID_REGNUM, 106, 106 }, g_q15_regs, nullptr, nullptr, 0 } }; - // clang-format on - - static const uint32_t num_registers = llvm::array_lengthof(g_register_infos); - static ConstString gpr_reg_set ("General Purpose Registers"); - static ConstString sfp_reg_set ("Software Floating Point Registers"); - static ConstString vfp_reg_set ("Floating Point Registers"); - size_t i; - if (from_scratch) - { - // Calculate the offsets of the registers - // Note that the layout of the "composite" registers (d0-d15 and q0-q15) which comes after the - // "primordial" registers is important. This enables us to calculate the offset of the composite - // register by using the offset of its first primordial register. For example, to calculate the - // offset of q0, use s0's offset. - if (g_register_infos[2].byte_offset == 0) - { - uint32_t byte_offset = 0; - for (i=0; i<num_registers; ++i) - { - // For primordial registers, increment the byte_offset by the byte_size to arrive at the - // byte_offset for the next register. Otherwise, we have a composite register whose - // offset can be calculated by consulting the offset of its first primordial register. - if (!g_register_infos[i].value_regs) - { - g_register_infos[i].byte_offset = byte_offset; - byte_offset += g_register_infos[i].byte_size; - } - else - { - const uint32_t first_primordial_reg = g_register_infos[i].value_regs[0]; - g_register_infos[i].byte_offset = g_register_infos[first_primordial_reg].byte_offset; - } - } - } - for (i=0; i<num_registers; ++i) - { - ConstString name; - ConstString alt_name; - if (g_register_infos[i].name && g_register_infos[i].name[0]) - name.SetCString(g_register_infos[i].name); - if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0]) - alt_name.SetCString(g_register_infos[i].alt_name); - - if (i <= 15 || i == 25) - AddRegister (g_register_infos[i], name, alt_name, gpr_reg_set); - else if (i <= 24) - AddRegister (g_register_infos[i], name, alt_name, sfp_reg_set); - else - AddRegister (g_register_infos[i], name, alt_name, vfp_reg_set); + // clang-format on + + static const uint32_t num_registers = llvm::array_lengthof(g_register_infos); + static ConstString gpr_reg_set("General Purpose Registers"); + static ConstString sfp_reg_set("Software Floating Point Registers"); + static ConstString vfp_reg_set("Floating Point Registers"); + size_t i; + if (from_scratch) { + // Calculate the offsets of the registers + // Note that the layout of the "composite" registers (d0-d15 and q0-q15) + // which comes after the + // "primordial" registers is important. This enables us to calculate the + // offset of the composite + // register by using the offset of its first primordial register. For + // example, to calculate the + // offset of q0, use s0's offset. + if (g_register_infos[2].byte_offset == 0) { + uint32_t byte_offset = 0; + for (i = 0; i < num_registers; ++i) { + // For primordial registers, increment the byte_offset by the byte_size + // to arrive at the + // byte_offset for the next register. Otherwise, we have a composite + // register whose + // offset can be calculated by consulting the offset of its first + // primordial register. + if (!g_register_infos[i].value_regs) { + g_register_infos[i].byte_offset = byte_offset; + byte_offset += g_register_infos[i].byte_size; + } else { + const uint32_t first_primordial_reg = + g_register_infos[i].value_regs[0]; + g_register_infos[i].byte_offset = + g_register_infos[first_primordial_reg].byte_offset; } + } } - else - { - // Add composite registers to our primordial registers, then. - const size_t num_composites = llvm::array_lengthof(g_composites); - const size_t num_dynamic_regs = GetNumRegisters(); - const size_t num_common_regs = num_registers - num_composites; - RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs; - - // First we need to validate that all registers that we already have match the non composite regs. - // If so, then we can add the registers, else we need to bail - bool match = true; - if (num_dynamic_regs == num_common_regs) - { - for (i=0; match && i<num_dynamic_regs; ++i) - { - // Make sure all register names match - if (m_regs[i].name && g_register_infos[i].name) - { - if (strcmp(m_regs[i].name, g_register_infos[i].name)) - { - match = false; - break; - } - } - - // Make sure all register byte sizes match - if (m_regs[i].byte_size != g_register_infos[i].byte_size) - { - match = false; - break; - } - } - } - else - { - // Wrong number of registers. + for (i = 0; i < num_registers; ++i) { + ConstString name; + ConstString alt_name; + if (g_register_infos[i].name && g_register_infos[i].name[0]) + name.SetCString(g_register_infos[i].name); + if (g_register_infos[i].alt_name && g_register_infos[i].alt_name[0]) + alt_name.SetCString(g_register_infos[i].alt_name); + + if (i <= 15 || i == 25) + AddRegister(g_register_infos[i], name, alt_name, gpr_reg_set); + else if (i <= 24) + AddRegister(g_register_infos[i], name, alt_name, sfp_reg_set); + else + AddRegister(g_register_infos[i], name, alt_name, vfp_reg_set); + } + } else { + // Add composite registers to our primordial registers, then. + const size_t num_composites = llvm::array_lengthof(g_composites); + const size_t num_dynamic_regs = GetNumRegisters(); + const size_t num_common_regs = num_registers - num_composites; + RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs; + + // First we need to validate that all registers that we already have match + // the non composite regs. + // If so, then we can add the registers, else we need to bail + bool match = true; + if (num_dynamic_regs == num_common_regs) { + for (i = 0; match && i < num_dynamic_regs; ++i) { + // Make sure all register names match + if (m_regs[i].name && g_register_infos[i].name) { + if (strcmp(m_regs[i].name, g_register_infos[i].name)) { match = false; + break; + } } - // If "match" is true, then we can add extra registers. - if (match) - { - for (i=0; i<num_composites; ++i) - { - ConstString name; - ConstString alt_name; - const uint32_t first_primordial_reg = g_comp_register_infos[i].value_regs[0]; - const char *reg_name = g_register_infos[first_primordial_reg].name; - if (reg_name && reg_name[0]) - { - for (uint32_t j = 0; j < num_dynamic_regs; ++j) - { - const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j); - // Find a matching primordial register info entry. - if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, reg_name) == 0) - { - // The name matches the existing primordial entry. - // Find and assign the offset, and then add this composite register entry. - g_comp_register_infos[i].byte_offset = reg_info->byte_offset; - name.SetCString(g_comp_register_infos[i].name); - AddRegister(g_comp_register_infos[i], name, alt_name, vfp_reg_set); - } - } - } + + // Make sure all register byte sizes match + if (m_regs[i].byte_size != g_register_infos[i].byte_size) { + match = false; + break; + } + } + } else { + // Wrong number of registers. + match = false; + } + // If "match" is true, then we can add extra registers. + if (match) { + for (i = 0; i < num_composites; ++i) { + ConstString name; + ConstString alt_name; + const uint32_t first_primordial_reg = + g_comp_register_infos[i].value_regs[0]; + const char *reg_name = g_register_infos[first_primordial_reg].name; + if (reg_name && reg_name[0]) { + for (uint32_t j = 0; j < num_dynamic_regs; ++j) { + const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j); + // Find a matching primordial register info entry. + if (reg_info && reg_info->name && + ::strcasecmp(reg_info->name, reg_name) == 0) { + // The name matches the existing primordial entry. + // Find and assign the offset, and then add this composite + // register entry. + g_comp_register_infos[i].byte_offset = reg_info->byte_offset; + name.SetCString(g_comp_register_infos[i].name); + AddRegister(g_comp_register_infos[i], name, alt_name, + vfp_reg_set); } + } } + } } + } } |
