diff options
| author | Jason Molenda <jmolenda@apple.com> | 2012-12-19 02:54:03 +0000 |
|---|---|---|
| committer | Jason Molenda <jmolenda@apple.com> | 2012-12-19 02:54:03 +0000 |
| commit | f17b5ac6e1239a5ff8c46c0351ba140b35f7a6ab (patch) | |
| tree | b88ee14026d17dae8cc22635ac01bb24e808eede /lldb/source | |
| parent | 503053a737bf1c54899bcc2d1b4c514485e30054 (diff) | |
| download | bcm5719-llvm-f17b5ac6e1239a5ff8c46c0351ba140b35f7a6ab.tar.gz bcm5719-llvm-f17b5ac6e1239a5ff8c46c0351ba140b35f7a6ab.zip | |
<rdar://problem/11961650>
Update the debugserver "qProcessInfo" implementation to return the
cpu type, cpu subtype, OS and vendor information just like qHostInfo
does so lldb can create an ArchSpec based on the returned values.
Add a new GetProcessArchitecture to GDBRemoteCommunicationClient akin
to GetHostArchitecture. If the qProcessInfo packet is supported,
GetProcessArchitecture will return the cpu type / subtype of the
process -- e.g. a 32-bit user process running on a 64-bit x86_64 Mac
system.
Have ProcessGDBRemote set the Target's architecture based on the
GetProcessArchitecture when we've completed an attach/launch/connect.
llvm-svn: 170491
Diffstat (limited to 'lldb/source')
3 files changed, 139 insertions, 4 deletions
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(); |

