summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2015-12-18 00:45:35 +0000
committerJason Molenda <jmolenda@apple.com>2015-12-18 00:45:35 +0000
commit545304d323d6bbebdddcd93a7b657e761b8df168 (patch)
treef17f00e522076977eb48896d516600eae1ad3b51 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
parent545b8861fc40bb194d6e8daa382f9d6d4659a13b (diff)
downloadbcm5719-llvm-545304d323d6bbebdddcd93a7b657e761b8df168.tar.gz
bcm5719-llvm-545304d323d6bbebdddcd93a7b657e761b8df168.zip
The lldb side changes to go along with r255711 where a new
"thread-pcs" key is added to the T (questionmark) packet in gdb-remote protocol so that lldb doesn't need to query the pc values of every thread before it resumes a process. The only odd part with this is that I'm sending the pc values in big endian order, so we need to know the endianness of the remote process before we can use them. All other register values in gdb-remote protocol are sent in native-endian format so this requirement doesn't exist. This addition is a performance enhancement -- lldb will fall back to querying the pc of each thread individually if it needs to -- so when we don't have the byte order for the process yet, we don't use these values. Practically speaking, the only way I've been able to elicit this condition is for the first T packet when we attach to a process. <rdar://problem/21963031> llvm-svn: 255942
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp46
1 files changed, 46 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
index 7b9471e9225..b0a1eaaeb79 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
@@ -147,6 +147,52 @@ GDBRemoteRegisterContext::PrivateSetRegisterValue (uint32_t reg, StringExtractor
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);
+
+ DataBufferSP buffer_sp (new DataBufferHeap (&new_reg_val, sizeof (new_reg_val)));
+ DataExtractor data (buffer_sp, endian::InlHostByteOrder(), sizeof (void*));
+
+ // 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 (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,
OpenPOWER on IntegriCloud