summaryrefslogtreecommitdiffstats
path: root/lldb/tools/debugserver/source/RNBRemote.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/tools/debugserver/source/RNBRemote.cpp')
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp304
1 files changed, 150 insertions, 154 deletions
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 7b2ba3335be..bb8c59ea0eb 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -60,11 +60,10 @@
extern void ASLLogCallback(void *baton, uint32_t flags, const char *format, va_list args);
-RNBRemote::RNBRemote (bool use_native_regs) :
- m_ctx(),
- m_comm(),
- m_extended_mode(false),
- m_noack_mode(false),
+RNBRemote::RNBRemote (bool use_native_regs, const char *arch) :
+ m_ctx (),
+ m_comm (),
+ m_arch (),
m_continue_thread(-1),
m_thread(-1),
m_mutex(),
@@ -75,10 +74,14 @@ RNBRemote::RNBRemote (bool use_native_regs) :
m_rx_pthread(0),
m_breakpoints(),
m_max_payload_size(DEFAULT_GDB_REMOTE_PROTOCOL_BUFSIZE - 4),
+ m_extended_mode(false),
+ m_noack_mode(false),
m_use_native_regs (use_native_regs)
{
DNBLogThreadedIf (LOG_RNB_REMOTE, "%s", __PRETTY_FUNCTION__);
CreatePacketTable ();
+ if (arch && arch[0])
+ m_arch.assign (arch);
}
@@ -803,12 +806,10 @@ RegisterEntryNotAvailable (register_map_entry_t *reg_entry)
reg_entry->nub_info.reg_gdb = INVALID_NUB_REGNUM;
}
-#if defined (__arm__)
//----------------------------------------------------------------------
// ARM regiseter sets as gdb knows them
//----------------------------------------------------------------------
-
register_map_entry_t
g_gdb_register_map_arm[] =
{
@@ -873,32 +874,6 @@ g_gdb_register_map_arm[] =
{ 58, 4, "fpscr", {0}, NULL, 0}
};
-void
-RNBRemote::InitializeRegisters (int use_native_registers)
-{
- if (use_native_registers)
- {
- RNBRemote::InitializeNativeRegisters();
- }
- else
- {
- const size_t num_regs = sizeof (g_gdb_register_map_arm) / sizeof (register_map_entry_t);
- for (uint32_t i=0; i<num_regs; ++i)
- {
- if (!DNBGetRegisterInfoByName (g_gdb_register_map_arm[i].gdb_name, &g_gdb_register_map_arm[i].nub_info))
- {
- RegisterEntryNotAvailable (&g_gdb_register_map_arm[i]);
- assert (g_gdb_register_map_arm[i].gdb_size <= MAX_REGISTER_BYTE_SIZE);
- }
- }
- g_reg_entries = g_gdb_register_map_arm;
- g_num_reg_entries = sizeof (g_gdb_register_map_arm) / sizeof (register_map_entry_t);
- }
-}
-
-
-#elif defined (__i386__)
-
register_map_entry_t
g_gdb_register_map_i386[] =
{
@@ -945,32 +920,6 @@ g_gdb_register_map_i386[] =
{ 40, 4, "mxcsr" , {0}, NULL, 0 },
};
-void
-RNBRemote::InitializeRegisters (int use_native_registers)
-{
- if (use_native_registers)
- {
- RNBRemote::InitializeNativeRegisters();
- }
- else
- {
- const size_t num_regs = sizeof (g_gdb_register_map_i386) / sizeof (register_map_entry_t);
- for (uint32_t i=0; i<num_regs; ++i)
- {
- if (!DNBGetRegisterInfoByName (g_gdb_register_map_i386[i].gdb_name, &g_gdb_register_map_i386[i].nub_info))
- {
- RegisterEntryNotAvailable (&g_gdb_register_map_i386[i]);
- assert (g_gdb_register_map_i386[i].gdb_size <= MAX_REGISTER_BYTE_SIZE);
- }
- }
- g_reg_entries = g_gdb_register_map_i386;
- g_num_reg_entries = sizeof (g_gdb_register_map_i386) / sizeof (register_map_entry_t);
- }
-}
-
-
-#elif defined (__x86_64__)
-
register_map_entry_t
g_gdb_register_map_x86_64[] =
{
@@ -1033,86 +982,113 @@ g_gdb_register_map_x86_64[] =
{ 56, 4, "mxcsr" , {0}, NULL, 0 }
};
-void
-RNBRemote::InitializeRegisters (int use_native_registers)
-{
- if (use_native_registers)
- {
- RNBRemote::InitializeNativeRegisters();
- }
- else
- {
- const size_t num_regs = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t);
- for (uint32_t i=0; i<num_regs; ++i)
- {
- if (!DNBGetRegisterInfoByName (g_gdb_register_map_x86_64[i].gdb_name, &g_gdb_register_map_x86_64[i].nub_info))
- {
- RegisterEntryNotAvailable (&g_gdb_register_map_x86_64[i]);
- assert (g_gdb_register_map_x86_64[i].gdb_size < MAX_REGISTER_BYTE_SIZE);
- }
- }
- g_reg_entries = g_gdb_register_map_x86_64;
- g_num_reg_entries = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t);
- }
-}
-
-
-#else
void
-RNBRemote::InitializeRegisters (int use_native_registers)
+RNBRemote::Initialize()
{
- // No choice, we don't have a GDB register definition for this arch.
- RNBRemote::InitializeNativeRegisters();
+ DNBInitialize();
}
-#endif
-
-void
-RNBRemote::InitializeNativeRegisters()
+bool
+RNBRemote::InitializeRegisters ()
{
- if (g_dynamic_register_map.empty())
- {
- nub_size_t num_reg_sets = 0;
- const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
-
- assert (num_reg_sets > 0 && reg_sets != NULL);
+ pid_t pid = m_ctx.ProcessID();
+ if (pid == INVALID_NUB_PROCESS)
+ return false;
- uint32_t regnum = 0;
- for (nub_size_t set = 0; set < num_reg_sets; ++set)
+ if (m_use_native_regs)
+ {
+ DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting native registers from DNB interface (%s)", __FUNCTION__, m_arch.c_str());
+ // Discover the registers by querying the DNB interface and letting it
+ // state the registers that it would like to export. This allows the
+ // registers to be discovered using multiple qRegisterInfo calls to get
+ // all register information after the architecture for the process is
+ // determined.
+ if (g_dynamic_register_map.empty())
{
- if (reg_sets[set].registers == NULL)
- continue;
+ nub_size_t num_reg_sets = 0;
+ const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
- for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg)
+ assert (num_reg_sets > 0 && reg_sets != NULL);
+
+ uint32_t regnum = 0;
+ for (nub_size_t set = 0; set < num_reg_sets; ++set)
{
- register_map_entry_t reg_entry = {
- regnum++, // register number starts at zero and goes up with no gaps
- reg_sets[set].registers[reg].size, // register size in bytes
- reg_sets[set].registers[reg].name, // register name
- reg_sets[set].registers[reg], // DNBRegisterInfo
- NULL, // Value to print if case we fail to reg this register (if this is NULL, we will return an error)
- reg_sets[set].registers[reg].reg_generic != INVALID_NUB_REGNUM};
-
- g_dynamic_register_map.push_back (reg_entry);
+ if (reg_sets[set].registers == NULL)
+ continue;
+
+ for (uint32_t reg=0; reg < reg_sets[set].num_registers; ++reg)
+ {
+ register_map_entry_t reg_entry = {
+ regnum++, // register number starts at zero and goes up with no gaps
+ reg_sets[set].registers[reg].size, // register size in bytes
+ reg_sets[set].registers[reg].name, // register name
+ reg_sets[set].registers[reg], // DNBRegisterInfo
+ NULL, // Value to print if case we fail to reg this register (if this is NULL, we will return an error)
+ reg_sets[set].registers[reg].reg_generic != INVALID_NUB_REGNUM};
+
+ g_dynamic_register_map.push_back (reg_entry);
+ }
}
+ g_reg_entries = g_dynamic_register_map.data();
+ g_num_reg_entries = g_dynamic_register_map.size();
}
- g_reg_entries = g_dynamic_register_map.data();
- g_num_reg_entries = g_dynamic_register_map.size();
+ return true;
}
-}
-
-
-const register_map_entry_t *
-register_mapping_by_regname (const char *n)
-{
- for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
+ else
{
- if (strcmp (g_reg_entries[reg].gdb_name, n) == 0)
- return &g_reg_entries[reg];
+ DNBLogThreadedIf (LOG_RNB_PROC, "RNBRemote::%s() getting gdb registers (%s)", __FUNCTION__, m_arch.c_str());
+#if defined (__i386__) || defined (__x86_64__)
+ if (m_arch.compare("x86_64") == 0)
+ {
+ const size_t num_regs = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t);
+ for (uint32_t i=0; i<num_regs; ++i)
+ {
+ if (!DNBGetRegisterInfoByName (g_gdb_register_map_x86_64[i].gdb_name, &g_gdb_register_map_x86_64[i].nub_info))
+ {
+ RegisterEntryNotAvailable (&g_gdb_register_map_x86_64[i]);
+ assert (g_gdb_register_map_x86_64[i].gdb_size < MAX_REGISTER_BYTE_SIZE);
+ }
+ }
+ g_reg_entries = g_gdb_register_map_x86_64;
+ g_num_reg_entries = sizeof (g_gdb_register_map_x86_64) / sizeof (register_map_entry_t);
+ return true;
+ }
+ else if (m_arch.compare("i386") == 0)
+ {
+ const size_t num_regs = sizeof (g_gdb_register_map_i386) / sizeof (register_map_entry_t);
+ for (uint32_t i=0; i<num_regs; ++i)
+ {
+ if (!DNBGetRegisterInfoByName (g_gdb_register_map_i386[i].gdb_name, &g_gdb_register_map_i386[i].nub_info))
+ {
+ RegisterEntryNotAvailable (&g_gdb_register_map_i386[i]);
+ assert (g_gdb_register_map_i386[i].gdb_size <= MAX_REGISTER_BYTE_SIZE);
+ }
+ }
+ g_reg_entries = g_gdb_register_map_i386;
+ g_num_reg_entries = sizeof (g_gdb_register_map_i386) / sizeof (register_map_entry_t);
+ return true;
+ }
+#elif defined (__arm__)
+ if (m_arch.find ("arm") == 0)
+ {
+ const size_t num_regs = sizeof (g_gdb_register_map_arm) / sizeof (register_map_entry_t);
+ for (uint32_t i=0; i<num_regs; ++i)
+ {
+ if (!DNBGetRegisterInfoByName (g_gdb_register_map_arm[i].gdb_name, &g_gdb_register_map_arm[i].nub_info))
+ {
+ RegisterEntryNotAvailable (&g_gdb_register_map_arm[i]);
+ assert (g_gdb_register_map_arm[i].gdb_size <= MAX_REGISTER_BYTE_SIZE);
+ }
+ }
+ g_reg_entries = g_gdb_register_map_arm;
+ g_num_reg_entries = sizeof (g_gdb_register_map_arm) / sizeof (register_map_entry_t);
+ return true;
+ }
+#endif
}
- return NULL;
+ return false;
}
/* The inferior has stopped executing; send a packet
@@ -1121,7 +1097,7 @@ register_mapping_by_regname (const char *n)
void
RNBRemote::NotifyThatProcessStopped (void)
{
- RNBRemote::HandlePacket_last_signal ("");
+ RNBRemote::HandlePacket_last_signal (NULL);
return;
}
@@ -1396,6 +1372,9 @@ RNBRemote::HandlePacket_qC (const char *p)
rnb_err_t
RNBRemote::HandlePacket_qRegisterInfo (const char *p)
{
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
p += strlen ("qRegisterInfo");
nub_size_t num_reg_sets = 0;
@@ -1951,6 +1930,9 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
if (thread_ident_info.dispatch_qaddr != 0)
ostrm << std::hex << "qaddr:" << thread_ident_info.dispatch_qaddr << ';';
}
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
DNBRegisterValue reg_value;
for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
{
@@ -2002,45 +1984,45 @@ RNBRemote::HandlePacket_last_signal (const char *unused)
case eStateSuspended:
case eStateStopped:
case eStateCrashed:
- {
- nub_thread_t tid = DNBProcessGetCurrentThread (pid);
- // Make sure we set the current thread so g and p packets return
- // the data the gdb will expect.
- SetCurrentThread (tid);
+ {
+ nub_thread_t tid = DNBProcessGetCurrentThread (pid);
+ // Make sure we set the current thread so g and p packets return
+ // the data the gdb will expect.
+ SetCurrentThread (tid);
- SendStopReplyPacketForThread (tid);
- }
+ SendStopReplyPacketForThread (tid);
+ }
break;
case eStateInvalid:
case eStateUnloaded:
case eStateExited:
- {
- char pid_exited_packet[16] = "";
- int pid_status = 0;
- // Process exited with exit status
- if (!DNBProcessGetExitStatus(pid, &pid_status))
- pid_status = 0;
-
- if (pid_status)
{
- if (WIFEXITED (pid_status))
- snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
- else if (WIFSIGNALED (pid_status))
- snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
- else if (WIFSTOPPED (pid_status))
- snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
- }
+ char pid_exited_packet[16] = "";
+ int pid_status = 0;
+ // Process exited with exit status
+ if (!DNBProcessGetExitStatus(pid, &pid_status))
+ pid_status = 0;
- // If we have an empty exit packet, lets fill one in to be safe.
- if (!pid_exited_packet[0])
- {
- strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
- pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
- }
+ if (pid_status)
+ {
+ if (WIFEXITED (pid_status))
+ snprintf (pid_exited_packet, sizeof(pid_exited_packet), "W%02x", WEXITSTATUS (pid_status));
+ else if (WIFSIGNALED (pid_status))
+ snprintf (pid_exited_packet, sizeof(pid_exited_packet), "X%02x", WEXITSTATUS (pid_status));
+ else if (WIFSTOPPED (pid_status))
+ snprintf (pid_exited_packet, sizeof(pid_exited_packet), "S%02x", WSTOPSIG (pid_status));
+ }
- return SendPacket (pid_exited_packet);
- }
+ // If we have an empty exit packet, lets fill one in to be safe.
+ if (!pid_exited_packet[0])
+ {
+ strncpy (pid_exited_packet, "W00", sizeof(pid_exited_packet)-1);
+ pid_exited_packet[sizeof(pid_exited_packet)-1] = '\0';
+ }
+
+ return SendPacket (pid_exited_packet);
+ }
break;
}
return rnb_success;
@@ -2244,6 +2226,10 @@ RNBRemote::HandlePacket_g (const char *p)
{
return SendPacket ("E11");
}
+
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
nub_process_t pid = m_ctx.ProcessID ();
nub_thread_t tid = GetCurrentThread();
@@ -2283,6 +2269,10 @@ RNBRemote::HandlePacket_G (const char *p)
{
return SendPacket ("E11");
}
+
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
StringExtractor packet(p);
packet.SetFilePos(1); // Skip the 'G'
@@ -2872,6 +2862,9 @@ RNBRemote::HandlePacket_z (const char *p)
rnb_err_t
RNBRemote::HandlePacket_p (const char *p)
{
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
if (p == NULL || *p == '\0')
{
return HandlePacket_ILLFORMED ("No thread specified in p packet");
@@ -2931,6 +2924,9 @@ RNBRemote::HandlePacket_p (const char *p)
rnb_err_t
RNBRemote::HandlePacket_P (const char *p)
{
+ if (g_num_reg_entries == 0)
+ InitializeRegisters ();
+
if (p == NULL || *p == '\0')
{
return HandlePacket_ILLFORMED ("Empty P packet");
OpenPOWER on IntegriCloud