summaryrefslogtreecommitdiffstats
path: root/lldb/tools/debugserver/source
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/debugserver/source')
-rw-r--r--lldb/tools/debugserver/source/DNBThreadResumeActions.h7
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.cpp35
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachProcess.h6
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachThread.cpp91
-rw-r--r--lldb/tools/debugserver/source/MacOSX/MachThread.h7
-rw-r--r--lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp2
-rw-r--r--lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp2
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp196
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.h21
9 files changed, 209 insertions, 158 deletions
diff --git a/lldb/tools/debugserver/source/DNBThreadResumeActions.h b/lldb/tools/debugserver/source/DNBThreadResumeActions.h
index f3fb8de6a82..81c7c43b722 100644
--- a/lldb/tools/debugserver/source/DNBThreadResumeActions.h
+++ b/lldb/tools/debugserver/source/DNBThreadResumeActions.h
@@ -85,6 +85,13 @@ public:
{
return m_actions.size();
}
+
+ void
+ Clear()
+ {
+ m_actions.clear();
+ m_signal_handled.clear();
+ }
protected:
std::vector<DNBThreadResumeAction> m_actions;
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
index 10f86f91225..05298168037 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.cpp
@@ -101,6 +101,7 @@ MachProcess::MachProcess() :
m_stdio_thread (0),
m_stdio_mutex (PTHREAD_MUTEX_RECURSIVE),
m_stdout_data (),
+ m_thread_actions (),
m_thread_list (),
m_exception_messages (),
m_exception_messages_mutex (PTHREAD_MUTEX_RECURSIVE),
@@ -314,7 +315,8 @@ MachProcess::Resume (const DNBThreadResumeActions& thread_actions)
if (CanResume(state))
{
- PrivateResume(thread_actions);
+ m_thread_actions = thread_actions;
+ PrivateResume();
return true;
}
else if (state == eStateRunning)
@@ -337,7 +339,8 @@ MachProcess::Kill (const struct timespec *timeout_abstime)
DNBError err;
err.SetErrorToErrno();
DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Kill() DoSIGSTOP() ::ptrace (PT_KILL, pid=%u, 0, 0) => 0x%8.8x (%s)", err.Error(), err.AsString());
- PrivateResume (DNBThreadResumeActions (eStateRunning, 0));
+ m_thread_actions = DNBThreadResumeActions (eStateRunning, 0);
+ PrivateResume ();
return true;
}
@@ -392,7 +395,8 @@ MachProcess::DoSIGSTOP (bool clear_bps_and_wps, uint32_t *thread_idx_ptr)
// No threads were stopped with a SIGSTOP, we need to run and halt the
// process with a signal
DNBLogThreadedIf(LOG_PROCESS, "MachProcess::DoSIGSTOP() state = %s -- resuming process", DNBStateAsString (state));
- PrivateResume (DNBThreadResumeActions (eStateRunning, 0));
+ m_thread_actions = DNBThreadResumeActions (eStateRunning, 0);
+ PrivateResume ();
// Reset the event that says we were indeed running
m_events.ResetEvents(eEventProcessRunningStateChanged);
@@ -428,20 +432,19 @@ MachProcess::Detach()
DNBLogThreadedIf(LOG_PROCESS, "MachProcess::Detach() DoSIGSTOP() returned %s", DNBStateAsString(state));
{
- DNBThreadResumeActions thread_actions;
+ m_thread_actions.Clear();
DNBThreadResumeAction thread_action;
thread_action.tid = m_thread_list.ThreadIDAtIndex (thread_idx);
thread_action.state = eStateRunning;
thread_action.signal = -1;
thread_action.addr = INVALID_NUB_ADDRESS;
- thread_actions.Append (thread_action);
-
- thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, 0);
+ m_thread_actions.Append (thread_action);
+ m_thread_actions.SetDefaultThreadActionIfNeeded (eStateRunning, 0);
PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);
- ReplyToAllExceptions (thread_actions);
+ ReplyToAllExceptions ();
}
@@ -597,7 +600,7 @@ MachProcess::WriteMemory (nub_addr_t addr, nub_size_t size, const void *buf)
void
-MachProcess::ReplyToAllExceptions (const DNBThreadResumeActions& thread_actions)
+MachProcess::ReplyToAllExceptions ()
{
PTHREAD_MUTEX_LOCKER(locker, m_exception_messages_mutex);
if (m_exception_messages.empty() == false)
@@ -610,13 +613,13 @@ MachProcess::ReplyToAllExceptions (const DNBThreadResumeActions& thread_actions)
DNBLogThreadedIf(LOG_EXCEPTIONS, "Replying to exception %d...", std::distance(begin, pos));
int thread_reply_signal = 0;
- const DNBThreadResumeAction *action = thread_actions.GetActionForThread (pos->state.thread_port, false);
+ const DNBThreadResumeAction *action = m_thread_actions.GetActionForThread (pos->state.thread_port, false);
if (action)
{
thread_reply_signal = action->signal;
if (thread_reply_signal)
- thread_actions.SetSignalHandledForThread (pos->state.thread_port);
+ m_thread_actions.SetSignalHandledForThread (pos->state.thread_port);
}
DNBError err (pos->Reply(this, thread_reply_signal));
@@ -630,20 +633,20 @@ MachProcess::ReplyToAllExceptions (const DNBThreadResumeActions& thread_actions)
}
}
void
-MachProcess::PrivateResume (const DNBThreadResumeActions& thread_actions)
+MachProcess::PrivateResume ()
{
PTHREAD_MUTEX_LOCKER (locker, m_exception_messages_mutex);
- ReplyToAllExceptions (thread_actions);
+ ReplyToAllExceptions ();
// bool stepOverBreakInstruction = step;
// Let the thread prepare to resume and see if any threads want us to
// step over a breakpoint instruction (ProcessWillResume will modify
// the value of stepOverBreakInstruction).
- m_thread_list.ProcessWillResume (this, thread_actions);
+ m_thread_list.ProcessWillResume (this, m_thread_actions);
// Set our state accordingly
- if (thread_actions.NumActionsWithState(eStateStepping))
+ if (m_thread_actions.NumActionsWithState(eStateStepping))
SetState (eStateStepping);
else
SetState (eStateRunning);
@@ -1100,7 +1103,7 @@ MachProcess::ExceptionMessageBundleComplete()
else
{
// Resume without checking our current state.
- PrivateResume (DNBThreadResumeActions (eStateRunning, 0));
+ PrivateResume ();
}
}
else
diff --git a/lldb/tools/debugserver/source/MacOSX/MachProcess.h b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
index 04ad02eb634..8866187b56a 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachProcess.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachProcess.h
@@ -17,6 +17,7 @@
#include "DNBDefs.h"
#include "DNBBreakpoint.h"
#include "DNBError.h"
+#include "DNBThreadResumeActions.h"
//#include "MachDYLD.h"
#include "MachException.h"
#include "MachVMMemory.h"
@@ -219,8 +220,8 @@ private:
eMachProcessFlagsUsingSBS = (1 << 1)
};
void Clear ();
- void ReplyToAllExceptions (const DNBThreadResumeActions& thread_actions);
- void PrivateResume (const DNBThreadResumeActions& thread_actions);
+ void ReplyToAllExceptions ();
+ void PrivateResume ();
nub_size_t RemoveTrapsFromBuffer (nub_addr_t addr, nub_size_t size, uint8_t *buf) const;
uint32_t Flags () const { return m_flags; }
@@ -239,6 +240,7 @@ private:
pthread_t m_stdio_thread; // Thread ID for the thread that watches for child process stdio
PThreadMutex m_stdio_mutex; // Multithreaded protection for stdio
std::string m_stdout_data;
+ DNBThreadResumeActions m_thread_actions; // The thread actions for the current MachProcess::Resume() call
MachException::Message::collection
m_exception_messages; // A collection of exception messages caught when listening to the exception port
PThreadMutex m_exception_messages_mutex; // Multithreaded protection for m_exception_messages
diff --git a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp
index 7890c069a77..003a58b79d6 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachThread.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/MachThread.cpp
@@ -339,6 +339,12 @@ MachThread::ThreadWillResume(const DNBThreadResumeAction *thread_action)
m_stop_exception.Clear();
}
+nub_break_t
+MachThread::CurrentBreakpoint()
+{
+ return m_process->Breakpoints().FindIDByAddress(GetPC());
+}
+
bool
MachThread::ShouldStop(bool &step_more)
{
@@ -394,14 +400,18 @@ MachThread::ShouldStop(bool &step_more)
bool
MachThread::IsStepping()
{
+#if ENABLE_AUTO_STEPPING_OVER_BP
// Return true if this thread is currently being stepped.
// MachThread::ThreadWillResume currently determines this by looking if we
// have been asked to single step, or if we are at a breakpoint instruction
// and have been asked to resume. In the latter case we need to disable the
// breakpoint we are at, single step, re-enable and continue.
nub_state_t state = GetState();
- return (state == eStateStepping) ||
- (state == eStateRunning && NUB_BREAK_ID_IS_VALID(CurrentBreakpoint()));
+ return ((state == eStateStepping) ||
+ (state == eStateRunning && NUB_BREAK_ID_IS_VALID(CurrentBreakpoint())));
+#else
+ return GetState() == eStateStepping;
+#endif
}
@@ -430,6 +440,7 @@ MachThread::ThreadDidStop()
// Update the basic information for a thread
MachThread::GetBasicInfo(m_tid, &m_basicInfo);
+#if ENABLE_AUTO_STEPPING_OVER_BP
// See if we were at a breakpoint when we last resumed that we disabled,
// re-enable it.
nub_break_t breakID = CurrentBreakpoint();
@@ -469,10 +480,12 @@ MachThread::ThreadDidStop()
SetState(eStateStopped);
}
}
-
-
- SetCurrentBreakpoint(INVALID_NUB_BREAK_ID);
-
+#else
+ if (m_basicInfo.suspend_count > 0)
+ SetState(eStateSuspended);
+ else
+ SetState(eStateStopped);
+#endif
return true;
}
@@ -496,30 +509,27 @@ MachThread::NotifyException(MachException::Data& exc)
if (!handled)
{
handled = true;
- nub_addr_t pc = GetPC();
- nub_break_t breakID = m_process->Breakpoints().FindIDByAddress(pc);
- SetCurrentBreakpoint(breakID);
- switch (exc.exc_type)
- {
- case EXC_BAD_ACCESS:
- break;
- case EXC_BAD_INSTRUCTION:
- break;
- case EXC_ARITHMETIC:
- break;
- case EXC_EMULATION:
- break;
- case EXC_SOFTWARE:
- break;
- case EXC_BREAKPOINT:
- break;
- case EXC_SYSCALL:
- break;
- case EXC_MACH_SYSCALL:
- break;
- case EXC_RPC_ALERT:
- break;
- }
+// switch (exc.exc_type)
+// {
+// case EXC_BAD_ACCESS:
+// break;
+// case EXC_BAD_INSTRUCTION:
+// break;
+// case EXC_ARITHMETIC:
+// break;
+// case EXC_EMULATION:
+// break;
+// case EXC_SOFTWARE:
+// break;
+// case EXC_BREAKPOINT:
+// break;
+// case EXC_SYSCALL:
+// break;
+// case EXC_MACH_SYSCALL:
+// break;
+// case EXC_RPC_ALERT:
+// break;
+// }
}
return handled;
}
@@ -658,27 +668,6 @@ MachThread::DisableHardwareWatchpoint (const DNBBreakpoint *wp)
return false;
}
-
-void
-MachThread::NotifyBreakpointChanged (const DNBBreakpoint *bp)
-{
- nub_break_t breakID = bp->GetID();
- if (bp->IsEnabled())
- {
- if (bp->Address() == GetPC())
- {
- SetCurrentBreakpoint(breakID);
- }
- }
- else
- {
- if (CurrentBreakpoint() == breakID)
- {
- SetCurrentBreakpoint(INVALID_NUB_BREAK_ID);
- }
- }
-}
-
bool
MachThread::GetIdentifierInfo ()
{
diff --git a/lldb/tools/debugserver/source/MacOSX/MachThread.h b/lldb/tools/debugserver/source/MacOSX/MachThread.h
index 0b2a8bf1ff9..e7e18fe262c 100644
--- a/lldb/tools/debugserver/source/MacOSX/MachThread.h
+++ b/lldb/tools/debugserver/source/MacOSX/MachThread.h
@@ -60,8 +60,7 @@ public:
bool SetPC(uint64_t value); // Set program counter
uint64_t GetSP(uint64_t failValue = INVALID_NUB_ADDRESS); // Get stack pointer
- nub_break_t CurrentBreakpoint() const { return m_breakID; }
- void SetCurrentBreakpoint(nub_break_t breakID) { m_breakID = breakID; }
+ nub_break_t CurrentBreakpoint();
uint32_t EnableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
uint32_t EnableHardwareWatchpoint (const DNBBreakpoint *watchpoint);
bool DisableHardwareBreakpoint (const DNBBreakpoint *breakpoint);
@@ -88,7 +87,9 @@ public:
bool SetRegisterValue ( uint32_t reg_set_idx, uint32_t reg_idx, const DNBRegisterValue *reg_value );
nub_size_t GetRegisterContext (void *buf, nub_size_t buf_len);
nub_size_t SetRegisterContext (const void *buf, nub_size_t buf_len);
- void NotifyBreakpointChanged (const DNBBreakpoint *bp);
+ void NotifyBreakpointChanged (const DNBBreakpoint *bp)
+ {
+ }
bool IsUserReady();
struct thread_basic_info *
diff --git a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
index 1222b809904..411e91426e1 100644
--- a/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/i386/DNBArchImplI386.cpp
@@ -428,8 +428,6 @@ DNBArchImplI386::NotifyException(MachException::Data& exc)
// Write the new PC back out
SetGPRState ();
}
-
- m_thread->SetCurrentBreakpoint(breakID);
}
return true;
}
diff --git a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
index fde3be6ab5d..ce0e9c2c579 100644
--- a/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
+++ b/lldb/tools/debugserver/source/MacOSX/x86_64/DNBArchImplX86_64.cpp
@@ -355,8 +355,6 @@ DNBArchImplX86_64::NotifyException(MachException::Data& exc)
// Write the new PC back out
SetGPRState ();
}
-
- m_thread->SetCurrentBreakpoint(breakID);
}
return true;
}
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 7fa05073d72..7ce808dbab4 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -76,6 +76,7 @@ RNBRemote::RNBRemote (bool use_native_regs, const char *arch) :
m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4),
m_extended_mode(false),
m_noack_mode(false),
+ m_thread_suffix_supported (false),
m_use_native_regs (use_native_regs)
{
DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
@@ -170,12 +171,13 @@ RNBRemote::CreatePacketTable ()
t.push_back (Packet (query_step_packet_supported, &RNBRemote::HandlePacket_qStepPacketSupported,NULL, "qStepPacketSupported", "Replys with OK if the 's' packet is supported."));
t.push_back (Packet (query_host_info, &RNBRemote::HandlePacket_qHostInfo, NULL, "qHostInfo", "Replies with multiple 'key:value;' tuples appended to each other."));
// t.push_back (Packet (query_symbol_lookup, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "qSymbol", "Notify that host debugger is ready to do symbol lookups"));
- t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_Q , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
- t.push_back (Packet (set_logging_mode, &RNBRemote::HandlePacket_Q , NULL, "QSetLogging:", "Request that the " DEBUGSERVER_PROGRAM_NAME " set its logging mode bits"));
- t.push_back (Packet (set_max_packet_size, &RNBRemote::HandlePacket_Q , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle"));
- t.push_back (Packet (set_max_payload_size, &RNBRemote::HandlePacket_Q , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle"));
- t.push_back (Packet (set_environment_variable, &RNBRemote::HandlePacket_Q , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment"));
- t.push_back (Packet (set_disable_aslr, &RNBRemote::HandlePacket_Q , NULL, "QSetDisableASLR:", "Set wether to disable ASLR when launching the process with the set argv ('A') packet"));
+ t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
+ t.push_back (Packet (prefix_reg_packets_with_tid, &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specifc packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command"));
+ t.push_back (Packet (set_logging_mode, &RNBRemote::HandlePacket_QSetLogging , NULL, "QSetLogging:", "Check if register packets ('g', 'G', 'p', and 'P' support having the thread ID prefix"));
+ t.push_back (Packet (set_max_packet_size, &RNBRemote::HandlePacket_QSetMaxPacketSize , NULL, "QSetMaxPacketSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized packet gdb can handle"));
+ t.push_back (Packet (set_max_payload_size, &RNBRemote::HandlePacket_QSetMaxPayloadSize , NULL, "QSetMaxPayloadSize:", "Tell " DEBUGSERVER_PROGRAM_NAME " the max sized payload gdb can handle"));
+ t.push_back (Packet (set_environment_variable, &RNBRemote::HandlePacket_QEnvironment , NULL, "QEnvironment:", "Add an environment variable to the inferior's environment"));
+ t.push_back (Packet (set_disable_aslr, &RNBRemote::HandlePacket_QSetDisableASLR , NULL, "QSetDisableASLR:", "Set wether to disable ASLR when launching the process with the set argv ('A') packet"));
// t.push_back (Packet (pass_signals_to_inferior, &RNBRemote::HandlePacket_UNIMPLEMENTED, NULL, "QPassSignals:", "Specify which signals are passed to the inferior"));
t.push_back (Packet (allocate_memory, &RNBRemote::HandlePacket_AllocateMemory, NULL, "_M", "Allocate memory in the inferior process."));
t.push_back (Packet (deallocate_memory, &RNBRemote::HandlePacket_DeallocateMemory, NULL, "_m", "Deallocate memory in the inferior process."));
@@ -1702,104 +1704,105 @@ set_logging (const char *p)
return rnb_success;
}
-
+rnb_err_t
+RNBRemote::HandlePacket_QThreadSuffixSupported (const char *p)
+{
+ m_thread_suffix_supported = true;
+ return SendPacket ("OK");
+}
rnb_err_t
-RNBRemote::HandlePacket_Q (const char *p)
+RNBRemote::HandlePacket_QStartNoAckMode (const char *p)
{
- if (p == NULL || strlen (p) <= 1)
- {
- return HandlePacket_ILLFORMED ("No subtype specified in Q packet");
- }
+ // Send the OK packet first so the correct checksum is appended...
+ rnb_err_t result = SendPacket ("OK");
+ m_noack_mode = true;
+ return result;
+}
- /* Switch to no-ack protocol mode after the "OK" packet is sent
- and the ack for that comes back from gdb. */
- if (strcmp (p, "QStartNoAckMode") == 0)
- {
- rnb_err_t result = SendPacket ("OK");
- m_noack_mode = true;
- return result;
- }
+rnb_err_t
+RNBRemote::HandlePacket_QSetLogging (const char *p)
+{
+ p += sizeof ("QSetLogging:") - 1;
+ rnb_err_t result = set_logging (p);
+ if (result == rnb_success)
+ return SendPacket ("OK");
+ else
+ return SendPacket ("E35");
+}
- if (strncmp (p, "QSetLogging:", sizeof ("QSetLogging:") - 1) == 0)
+rnb_err_t
+RNBRemote::HandlePacket_QSetDisableASLR (const char *p)
+{
+ extern int g_disable_aslr;
+ p += sizeof ("QSetDisableASLR:") - 1;
+ switch (*p)
{
- p += sizeof ("QSetLogging:") - 1;
- rnb_err_t result = set_logging (p);
- if (result == rnb_success)
- return SendPacket ("OK");
- else
- return SendPacket ("E35");
+ case '0': g_disable_aslr = 0; break;
+ case '1': g_disable_aslr = 1; break;
+ default:
+ return SendPacket ("E56");
}
+ return SendPacket ("OK");
+}
- if (strncmp (p, "QSetDisableASLR:", sizeof ("QSetDisableASLR:") - 1) == 0)
- {
- extern int g_disable_aslr;
- p += sizeof ("QSetDisableASLR:") - 1;
- switch (*p)
- {
- case '0': g_disable_aslr = 0; break;
- case '1': g_disable_aslr = 1; break;
- default:
- return SendPacket ("E56");
- }
- return SendPacket ("OK");
- }
+rnb_err_t
+RNBRemote::HandlePacket_QSetMaxPayloadSize (const char *p)
+{
/* The number of characters in a packet payload that gdb is
prepared to accept. The packet-start char, packet-end char,
2 checksum chars and terminating null character are not included
in this size. */
- if (strncmp (p, "QSetMaxPayloadSize:", sizeof ("QSetMaxPayloadSize:") - 1) == 0)
+ p += sizeof ("QSetMaxPayloadSize:") - 1;
+ errno = 0;
+ uint32_t size = strtoul (p, NULL, 16);
+ if (errno != 0 && size == 0)
{
- p += sizeof ("QSetMaxPayloadSize:") - 1;
- errno = 0;
- uint32_t size = strtoul (p, NULL, 16);
- if (errno != 0 && size == 0)
- {
- return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPayloadSize packet");
- }
- m_max_payload_size = size;
- return SendPacket ("OK");
+ return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPayloadSize packet");
}
+ m_max_payload_size = size;
+ return SendPacket ("OK");
+}
+rnb_err_t
+RNBRemote::HandlePacket_QSetMaxPacketSize (const char *p)
+{
/* This tells us the largest packet that gdb can handle.
i.e. the size of gdb's packet-reading buffer.
QSetMaxPayloadSize is preferred because it is less ambiguous. */
-
- if (strncmp (p, "QSetMaxPacketSize:", sizeof ("QSetMaxPacketSize:") - 1) == 0)
+ p += sizeof ("QSetMaxPacketSize:") - 1;
+ errno = 0;
+ uint32_t size = strtoul (p, NULL, 16);
+ if (errno != 0 && size == 0)
{
- p += sizeof ("QSetMaxPacketSize:") - 1;
- errno = 0;
- uint32_t size = strtoul (p, NULL, 16);
- if (errno != 0 && size == 0)
- {
- return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPacketSize packet");
- }
- m_max_payload_size = size - 5;
- return SendPacket ("OK");
+ return HandlePacket_ILLFORMED ("Invalid length in QSetMaxPacketSize packet");
}
+ m_max_payload_size = size - 5;
+ return SendPacket ("OK");
+}
+
+
+
+rnb_err_t
+RNBRemote::HandlePacket_QEnvironment (const char *p)
+{
/* This sets the environment for the target program. The packet is of the form:
QEnvironment:VARIABLE=VALUE
*/
- if (strncmp (p, "QEnvironment:", sizeof ("QEnvironment:") - 1) == 0)
- {
- DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
- (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
+ DNBLogThreadedIf (LOG_RNB_REMOTE, "%8u RNBRemote::%s Handling QEnvironment: \"%s\"",
+ (uint32_t)m_comm.Timer().ElapsedMicroSeconds(true), __FUNCTION__, p);
- p += sizeof ("QEnvironment:") - 1;
- RNBContext& ctx = Context();
-
- ctx.PushEnvironment (p);
- return SendPacket ("OK");
- }
+ p += sizeof ("QEnvironment:") - 1;
+ RNBContext& ctx = Context();
- // Unrecognized Q packet
- return SendPacket ("");
+ ctx.PushEnvironment (p);
+ return SendPacket ("OK");
}
void
@@ -2245,7 +2248,9 @@ RNBRemote::HandlePacket_g (const char *p)
InitializeRegisters ();
nub_process_t pid = m_ctx.ProcessID ();
- nub_thread_t tid = GetCurrentThread();
+ nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p + 1);
+ if (tid == INVALID_NUB_THREAD)
+ return HandlePacket_ILLFORMED ("No thread specified in p packet");
if (m_use_native_regs)
{
@@ -2291,7 +2296,9 @@ RNBRemote::HandlePacket_G (const char *p)
packet.SetFilePos(1); // Skip the 'G'
nub_process_t pid = m_ctx.ProcessID();
- nub_thread_t tid = GetCurrentThread();
+ nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
+ if (tid == INVALID_NUB_THREAD)
+ return HandlePacket_ILLFORMED ("No thread specified in p packet");
if (m_use_native_regs)
{
@@ -2870,6 +2877,30 @@ RNBRemote::HandlePacket_z (const char *p)
return HandlePacket_UNIMPLEMENTED(p);
}
+// Extract the thread number from the thread suffix that might be appended to
+// thread specific packets. This will only be enabled if m_thread_suffix_supported
+// is true.
+nub_thread_t
+RNBRemote::ExtractThreadIDFromThreadSuffix (const char *p)
+{
+ if (m_thread_suffix_supported)
+ {
+ nub_thread_t tid = INVALID_NUB_THREAD;
+ if (p)
+ {
+ const char *tid_cstr = strstr (p, "thread:");
+ if (tid_cstr)
+ {
+ tid_cstr += strlen ("thread:");
+ tid = strtoul(tid_cstr, NULL, 16);
+ }
+ DNBLogThreadedIf (LOG_RNB_PACKETS, "RNBRemote::ExtractThreadIDFromThreadSuffix(%s) got thread 0x%4.4x", p, tid);
+ }
+ }
+ return GetCurrentThread();
+
+}
+
/* `p XX'
print the contents of register X */
@@ -2889,12 +2920,17 @@ RNBRemote::HandlePacket_p (const char *p)
}
nub_process_t pid = m_ctx.ProcessID();
errno = 0;
- uint32_t reg = strtoul (p + 1, NULL, 16);
+ char *tid_cstr = NULL;
+ uint32_t reg = strtoul (p + 1, &tid_cstr, 16);
if (errno != 0 && reg == 0)
{
- return HandlePacket_ILLFORMED ("Could not parse thread number in p packet");
+ return HandlePacket_ILLFORMED ("Could not parse register number in p packet");
}
+ nub_thread_t tid = ExtractThreadIDFromThreadSuffix (tid_cstr);
+ if (tid == INVALID_NUB_THREAD)
+ return HandlePacket_ILLFORMED ("No thread specified in p packet");
+
const register_map_entry_t *reg_entry;
if (reg < g_num_reg_entries)
@@ -2925,7 +2961,6 @@ RNBRemote::HandlePacket_p (const char *p)
}
else
{
- nub_thread_t tid = GetCurrentThread();
register_value_in_hex_fixed_width (ostrm, pid, tid, reg_entry);
}
return SendPacket (ostrm.str());
@@ -2985,8 +3020,9 @@ RNBRemote::HandlePacket_P (const char *p)
reg_value.info = reg_entry->nub_info;
packet.GetHexBytes (reg_value.value.v_sint8, reg_entry->gdb_size, 0xcc);
- nub_thread_t tid;
- tid = GetCurrentThread ();
+ nub_thread_t tid = ExtractThreadIDFromThreadSuffix (p);
+ if (tid == INVALID_NUB_THREAD)
+ return HandlePacket_ILLFORMED ("No thread specified in p packet");
if (!DNBThreadSetRegisterValueByID (pid, tid, reg_entry->nub_info.set, reg_entry->nub_info.reg, &reg_value))
{
diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h
index fab42bc9693..82febf7d226 100644
--- a/lldb/tools/debugserver/source/RNBRemote.h
+++ b/lldb/tools/debugserver/source/RNBRemote.h
@@ -93,6 +93,7 @@ public:
query_host_info, // 'qHostInfo'
pass_signals_to_inferior, // 'QPassSignals'
start_noack_mode, // 'QStartNoAckMode'
+ prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID
set_logging_mode, // 'QSetLogging:'
set_max_packet_size, // 'QSetMaxPacketSize:'
set_max_payload_size, // 'QSetMaxPayloadSize:'
@@ -156,7 +157,14 @@ public:
rnb_err_t HandlePacket_qThreadExtraInfo (const char *p);
rnb_err_t HandlePacket_qThreadStopInfo (const char *p);
rnb_err_t HandlePacket_qHostInfo (const char *p);
- rnb_err_t HandlePacket_Q (const char *p);
+ rnb_err_t HandlePacket_QStartNoAckMode (const char *p);
+ rnb_err_t HandlePacket_QThreadSuffixSupported (const char *p);
+ rnb_err_t HandlePacket_QSetLogging (const char *p);
+ rnb_err_t HandlePacket_QSetDisableASLR (const char *p);
+ rnb_err_t HandlePacket_QSetMaxPayloadSize (const char *p);
+ rnb_err_t HandlePacket_QSetMaxPacketSize (const char *p);
+ rnb_err_t HandlePacket_QEnvironment (const char *p);
+ rnb_err_t HandlePacket_QPrefixRegisterPacketsWithThreadID (const char *p);
rnb_err_t HandlePacket_last_signal (const char *p);
rnb_err_t HandlePacket_m (const char *p);
rnb_err_t HandlePacket_M (const char *p);
@@ -237,6 +245,9 @@ protected:
void CreatePacketTable ();
rnb_err_t GetPacketPayload (std::string &);
+ nub_thread_t
+ ExtractThreadIDFromThreadSuffix (const char *p);
+
// gdb can send multiple Z/z packets for the same address and
// these calls must be ref counted.
struct Breakpoint
@@ -286,7 +297,13 @@ protected:
uint32_t m_max_payload_size; // the maximum sized payload we should send to gdb
bool m_extended_mode:1, // are we in extended mode?
m_noack_mode:1, // are we in no-ack mode?
- m_use_native_regs:1; // Use native registers by querying DNB layer for register definitions?
+ m_noack_mode_just_enabled:1, // Did we just enable this and need to compute one more checksum?
+ m_use_native_regs:1, // Use native registers by querying DNB layer for register definitions?
+ m_thread_suffix_supported:1; // Set to true if the 'p', 'P', 'g', and 'G' packets should be prefixed with the thread ID and colon:
+ // "$pRR;thread:TTTT;" instead of "$pRR"
+ // "$PRR=VVVVVVVV;thread:TTTT;" instead of "$PRR=VVVVVVVV"
+ // "$g;thread:TTTT" instead of "$g"
+ // "$GVVVVVVVVVVVVVV;thread:TTTT;#00 instead of "$GVVVVVVVVVVVVVV"
};
/* We translate the /usr/include/mach/exception_types.h exception types
OpenPOWER on IntegriCloud