summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/docs/lldb-gdb-remote.txt17
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp106
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h10
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp27
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp62
5 files changed, 199 insertions, 23 deletions
diff --git a/lldb/docs/lldb-gdb-remote.txt b/lldb/docs/lldb-gdb-remote.txt
index 594e3fc3a86..e80af4f66e4 100644
--- a/lldb/docs/lldb-gdb-remote.txt
+++ b/lldb/docs/lldb-gdb-remote.txt
@@ -407,14 +407,23 @@ ptrsize: is a number that represents how big pointers are in bytes on the debug
// Medium. On systems which can launch multiple different architecture processes,
// the qHostInfo may not disambiguate sufficiently to know what kind of
// process is being debugged.
-// e.g. on a 64-bit x86 Mc system both 32-bit and 64-bit user processes are possible,
+// e.g. on a 64-bit x86 Mac system both 32-bit and 64-bit user processes are possible,
// and with Mach-O univeral files, the executable file may contain both 32- and
// 64-bit slices so it may be impossible to know until you're attached to a real
// process to know what you're working with.
+//
+// All numeric fields return base-16 numbers without any "0x" prefix.
//----------------------------------------------------------------------
+An i386 process:
+
+send packet: $qProcessInfo#00
+read packet: $pid:42a8;parent-pid:42bf;real-uid:ecf;real-gid:b;effective-uid:ecf;effective-gid:b;cputype:7;cpusubtype:3;ostype:macosx;vendor:apple;endian:little;ptrsize:4;#00
+
+An x86_64 process:
+
send packet: $qProcessInfo#00
-$pid:0x9517;parent-pid:0x9519;real-uid:0xecf;real-gid:0xb;effective-uid:0xecf;effective-gid:0xb;cputype:0x7;ptrsize:0x4;#00
+read packet: $pid:d22c;parent-pid:d34d;real-uid:ecf;real-gid:b;effective-uid:ecf;effective-gid:b;cputype:1000007;cpusubtype:3;ostype:macosx;vendor:apple;endian:little;ptrsize:8;#00
Key value pairs include:
@@ -425,6 +434,10 @@ real-gid: the real group id of the process
effective-uid: the effective user id of the process
effective-gid: the effective group id of the process
cputype: the Mach-O CPU type of the process
+cpusubtype: the Mach-O CPU subtype of the process
+ostype: is a string the represents the OS being debugged (darwin, lunix, freebsd)
+vendor: is a string that represents the vendor (apple)
+endian: is one of "little", "big", or "pdp"
ptrsize: is a number that represents how big pointers are in bytes
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 9aa504110db..63ddc5d957d 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -46,6 +46,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
m_supports_vCont_s (eLazyBoolCalculate),
m_supports_vCont_S (eLazyBoolCalculate),
m_qHostInfo_is_valid (eLazyBoolCalculate),
+ m_qProcessInfo_is_valid (eLazyBoolCalculate),
m_supports_alloc_dealloc_memory (eLazyBoolCalculate),
m_supports_memory_region_info (eLazyBoolCalculate),
m_supports_watchpoint_support_info (eLazyBoolCalculate),
@@ -71,6 +72,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient(bool is_platform) :
m_async_response (),
m_async_signal (-1),
m_host_arch(),
+ m_process_arch(),
m_os_version_major (UINT32_MAX),
m_os_version_minor (UINT32_MAX),
m_os_version_update (UINT32_MAX)
@@ -187,6 +189,7 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings()
m_supports_vCont_s = eLazyBoolCalculate;
m_supports_vCont_S = eLazyBoolCalculate;
m_qHostInfo_is_valid = eLazyBoolCalculate;
+ m_qProcessInfo_is_valid = eLazyBoolCalculate;
m_supports_alloc_dealloc_memory = eLazyBoolCalculate;
m_supports_memory_region_info = eLazyBoolCalculate;
m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
@@ -203,6 +206,7 @@ GDBRemoteCommunicationClient::ResetDiscoverableSettings()
m_supports_z3 = true;
m_supports_z4 = true;
m_host_arch.Clear();
+ m_process_arch.Clear();
}
@@ -963,6 +967,14 @@ GDBRemoteCommunicationClient::GetSystemArchitecture ()
return ArchSpec();
}
+const lldb_private::ArchSpec &
+GDBRemoteCommunicationClient::GetProcessArchitecture ()
+{
+ if (m_qProcessInfo_is_valid == eLazyBoolCalculate)
+ GetCurrentProcessInfo ();
+ return m_process_arch;
+}
+
bool
GDBRemoteCommunicationClient::GetHostInfo (bool force)
@@ -1634,6 +1646,100 @@ GDBRemoteCommunicationClient::GetProcessInfo (lldb::pid_t pid, ProcessInstanceIn
return false;
}
+bool
+GDBRemoteCommunicationClient::GetCurrentProcessInfo ()
+{
+ if (m_qProcessInfo_is_valid == eLazyBoolYes)
+ return true;
+ if (m_qProcessInfo_is_valid == eLazyBoolNo)
+ return false;
+
+ GetHostInfo ();
+
+ StringExtractorGDBRemote response;
+ if (SendPacketAndWaitForResponse ("qProcessInfo", response, false))
+ {
+ if (response.IsNormalResponse())
+ {
+ std::string name;
+ std::string value;
+ uint32_t cpu = LLDB_INVALID_CPUTYPE;
+ uint32_t sub = 0;
+ std::string arch_name;
+ std::string os_name;
+ std::string vendor_name;
+ std::string triple;
+ uint32_t pointer_byte_size = 0;
+ StringExtractor extractor;
+ ByteOrder byte_order = eByteOrderInvalid;
+ uint32_t num_keys_decoded = 0;
+ while (response.GetNameColonValue(name, value))
+ {
+ if (name.compare("cputype") == 0)
+ {
+ cpu = Args::StringToUInt32 (value.c_str(), LLDB_INVALID_CPUTYPE, 16);
+ if (cpu != LLDB_INVALID_CPUTYPE)
+ ++num_keys_decoded;
+ }
+ else if (name.compare("cpusubtype") == 0)
+ {
+ sub = Args::StringToUInt32 (value.c_str(), 0, 16);
+ if (sub != 0)
+ ++num_keys_decoded;
+ }
+ else if (name.compare("ostype") == 0)
+ {
+ os_name.swap (value);
+ ++num_keys_decoded;
+ }
+ else if (name.compare("vendor") == 0)
+ {
+ vendor_name.swap(value);
+ ++num_keys_decoded;
+ }
+ else if (name.compare("endian") == 0)
+ {
+ ++num_keys_decoded;
+ if (value.compare("little") == 0)
+ byte_order = eByteOrderLittle;
+ else if (value.compare("big") == 0)
+ byte_order = eByteOrderBig;
+ else if (value.compare("pdp") == 0)
+ byte_order = eByteOrderPDP;
+ else
+ --num_keys_decoded;
+ }
+ else if (name.compare("ptrsize") == 0)
+ {
+ pointer_byte_size = Args::StringToUInt32 (value.c_str(), 0, 16);
+ if (pointer_byte_size != 0)
+ ++num_keys_decoded;
+ }
+ }
+ if (num_keys_decoded > 0)
+ m_qProcessInfo_is_valid = eLazyBoolYes;
+ if (cpu != LLDB_INVALID_CPUTYPE && !os_name.empty() && !vendor_name.empty())
+ {
+ m_process_arch.SetArchitecture (eArchTypeMachO, cpu, sub);
+ if (pointer_byte_size)
+ {
+ assert (pointer_byte_size == m_process_arch.GetAddressByteSize());
+ }
+ m_host_arch.GetTriple().setVendorName (llvm::StringRef (vendor_name));
+ m_host_arch.GetTriple().setOSName (llvm::StringRef (os_name));
+ return true;
+ }
+ }
+ }
+ else
+ {
+ m_qProcessInfo_is_valid = eLazyBoolNo;
+ }
+
+ return false;
+}
+
+
uint32_t
GDBRemoteCommunicationClient::FindProcesses (const ProcessInstanceInfoMatch &match_info,
ProcessInstanceInfoList &process_infos)
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 449aa5ad0ac..201ce61eece 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -217,7 +217,10 @@ public:
const lldb_private::ArchSpec &
GetHostArchitecture ();
-
+
+ const lldb_private::ArchSpec &
+ GetProcessArchitecture ();
+
bool
GetVContSupported (char flavor);
@@ -353,6 +356,9 @@ public:
}
protected:
+ bool
+ GetCurrentProcessInfo ();
+
//------------------------------------------------------------------
// Classes that inherit from GDBRemoteCommunicationClient can see and modify these
//------------------------------------------------------------------
@@ -366,6 +372,7 @@ protected:
lldb_private::LazyBool m_supports_vCont_s;
lldb_private::LazyBool m_supports_vCont_S;
lldb_private::LazyBool m_qHostInfo_is_valid;
+ lldb_private::LazyBool m_qProcessInfo_is_valid;
lldb_private::LazyBool m_supports_alloc_dealloc_memory;
lldb_private::LazyBool m_supports_memory_region_info;
lldb_private::LazyBool m_supports_watchpoint_support_info;
@@ -402,6 +409,7 @@ protected:
bool m_interrupt_sent;
lldb_private::ArchSpec m_host_arch;
+ lldb_private::ArchSpec m_process_arch;
uint32_t m_os_version_major;
uint32_t m_os_version_minor;
uint32_t m_os_version_update;
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 0b6f12eca43..b00c4c95a56 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -393,7 +393,16 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
bool from_scratch = (reg_num == 0);
const ArchSpec &target_arch = GetTarget().GetArchitecture();
- const ArchSpec &remote_arch = m_gdb_comm.GetHostArchitecture();
+ const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
+ const ArchSpec &remote_process_arch = m_gdb_comm.GetProcessArchitecture();
+
+ // Use the process' architecture instead of the host arch, if available
+ ArchSpec remote_arch;
+ if (remote_process_arch.IsValid ())
+ remote_arch = remote_process_arch;
+ else
+ remote_arch = remote_host_arch;
+
if (!target_arch.IsValid())
{
if (remote_arch.IsValid()
@@ -480,7 +489,11 @@ ProcessGDBRemote::DoConnectRemote (Stream *strm, const char *remote_url)
&& !GetTarget().GetArchitecture().IsValid()
&& m_gdb_comm.GetHostArchitecture().IsValid())
{
- GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
+ // Prefer the *process'* architecture over that of the *host*, if available.
+ if (m_gdb_comm.GetProcessArchitecture().IsValid())
+ GetTarget().SetArchitecture(m_gdb_comm.GetProcessArchitecture());
+ else
+ GetTarget().SetArchitecture(m_gdb_comm.GetHostArchitecture());
}
return error;
@@ -866,7 +879,15 @@ ProcessGDBRemote::DidLaunchOrAttach ()
// See if the GDB server supports the qHostInfo information
- const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
+ ArchSpec gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
+
+ // See if the GDB server supports the qProcessInfo packet, if so
+ // prefer that over the Host information as it will be more specific
+ // to our process.
+
+ if (m_gdb_comm.GetProcessArchitecture().IsValid())
+ gdb_remote_arch = m_gdb_comm.GetProcessArchitecture();
+
if (gdb_remote_arch.IsValid())
{
ArchSpec &target_arch = GetTarget().GetArchitecture();
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 1c13a325e75..271ceb5cef8 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -3781,8 +3781,7 @@ RNBRemote::HandlePacket_qHostInfo (const char *p)
// Note that all numeric values returned by qProcessInfo are hex encoded,
-// including the pid and the cpu type, and are fixed with "0x" to indicate
-// this encoding.
+// including the pid and the cpu type.
rnb_err_t
RNBRemote::HandlePacket_qProcessInfo (const char *p)
@@ -3796,7 +3795,7 @@ RNBRemote::HandlePacket_qProcessInfo (const char *p)
pid = m_ctx.ProcessID();
- rep << "pid:0x" << std::hex << pid << ";";
+ rep << "pid:" << std::hex << pid << ";";
int procpid_mib[4];
procpid_mib[0] = CTL_KERN;
@@ -3810,34 +3809,63 @@ RNBRemote::HandlePacket_qProcessInfo (const char *p)
{
if (proc_kinfo_size > 0)
{
- rep << "parent-pid:0x" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";";
- rep << "real-uid:0x" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";";
- rep << "real-gid:0x" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";";
- rep << "effective-uid:0x" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";";
+ rep << "parent-pid:" << std::hex << proc_kinfo.kp_eproc.e_ppid << ";";
+ rep << "real-uid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_ruid << ";";
+ rep << "real-gid:" << std::hex << proc_kinfo.kp_eproc.e_pcred.p_rgid << ";";
+ rep << "effective-uid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_uid << ";";
if (proc_kinfo.kp_eproc.e_ucred.cr_ngroups > 0)
- rep << "effective-gid:0x" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";";
+ rep << "effective-gid:" << std::hex << proc_kinfo.kp_eproc.e_ucred.cr_groups[0] << ";";
}
}
int cputype_mib[CTL_MAXNAME]={0,};
size_t cputype_mib_len = CTL_MAXNAME;
+ cpu_type_t cputype = -1;
if (::sysctlnametomib("sysctl.proc_cputype", cputype_mib, &cputype_mib_len) == 0)
{
cputype_mib[cputype_mib_len] = pid;
cputype_mib_len++;
- cpu_type_t cpu;
- size_t len = sizeof(cpu);
- if (::sysctl (cputype_mib, cputype_mib_len, &cpu, &len, 0, 0) == 0)
+ size_t len = sizeof(cputype);
+ if (::sysctl (cputype_mib, cputype_mib_len, &cputype, &len, 0, 0) == 0)
{
- rep << "cputype:0x" << std::hex << cpu << ";";
+ rep << "cputype:" << std::hex << cputype << ";";
}
}
- nub_thread_t thread = DNBProcessGetCurrentThread (pid);
+ uint32_t cpusubtype;
+ size_t cpusubtype_len = sizeof(cpusubtype);
+ if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &cpusubtype_len, NULL, 0) == 0)
+ {
+ if (cputype == CPU_TYPE_X86_64 && cpusubtype == CPU_SUBTYPE_486)
+ {
+ cpusubtype = CPU_SUBTYPE_X86_64_ALL;
+ }
+ rep << "cpusubtype:" << std::hex << cpusubtype << ';';
+ }
+
+ // The OS in the triple should be "ios" or "macosx" which doesn't match our
+ // "Darwin" which gets returned from "kern.ostype", so we need to hardcode
+ // this for now.
+ if (cputype == CPU_TYPE_ARM)
+ rep << "ostype:ios;";
+ else
+ rep << "ostype:macosx;";
+
+ rep << "vendor:apple;";
+
+#if defined (__LITTLE_ENDIAN__)
+ rep << "endian:little;";
+#elif defined (__BIG_ENDIAN__)
+ rep << "endian:big;";
+#elif defined (__PDP_ENDIAN__)
+ rep << "endian:pdp;";
+#endif
+
+ nub_thread_t thread = DNBProcessGetCurrentThread (pid);
kern_return_t kr;
-#if defined (__x86_64__) || defined (__i386__)
+#if (defined (__x86_64__) || defined (__i386__)) && defined (x86_THREAD_STATE)
x86_thread_state_t gp_regs;
mach_msg_type_number_t gp_count = x86_THREAD_STATE_COUNT;
kr = thread_get_state (thread, x86_THREAD_STATE,
@@ -3845,12 +3873,12 @@ RNBRemote::HandlePacket_qProcessInfo (const char *p)
if (kr == KERN_SUCCESS)
{
if (gp_regs.tsh.flavor == x86_THREAD_STATE64)
- rep << "ptrsize:0x8;";
+ rep << "ptrsize:8;";
else
- rep << "ptrsize:0x4;";
+ rep << "ptrsize:4;";
}
#elif defined (__arm__)
- rep << "ptrsize:0x4;";
+ rep << "ptrsize:4;";
#endif
return SendPacket (rep.str());
OpenPOWER on IntegriCloud