[Lldb-commits] [lldb] r170491 - in /lldb/trunk: docs/lldb-gdb-remote.txt source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp tools/debugserver/source/RNBRemote.cpp

Jason Molenda jmolenda at apple.com
Tue Dec 18 18:54:04 PST 2012


Author: jmolenda
Date: Tue Dec 18 20:54:03 2012
New Revision: 170491

URL: http://llvm.org/viewvc/llvm-project?rev=170491&view=rev
Log:
<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.


Modified:
    lldb/trunk/docs/lldb-gdb-remote.txt
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/tools/debugserver/source/RNBRemote.cpp

Modified: lldb/trunk/docs/lldb-gdb-remote.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/docs/lldb-gdb-remote.txt?rev=170491&r1=170490&r2=170491&view=diff
==============================================================================
--- lldb/trunk/docs/lldb-gdb-remote.txt (original)
+++ lldb/trunk/docs/lldb-gdb-remote.txt Tue Dec 18 20:54:03 2012
@@ -407,14 +407,23 @@
 //  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 @@
 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
 
 

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=170491&r1=170490&r2=170491&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Tue Dec 18 20:54:03 2012
@@ -46,6 +46,7 @@
     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 @@
     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 @@
     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 @@
     m_supports_z3 = true;
     m_supports_z4 = true;
     m_host_arch.Clear();
+    m_process_arch.Clear();
 }
 
 
@@ -963,6 +967,14 @@
     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 @@
     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)

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=170491&r1=170490&r2=170491&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Tue Dec 18 20:54:03 2012
@@ -217,7 +217,10 @@
 
     const lldb_private::ArchSpec &
     GetHostArchitecture ();
-    
+
+    const lldb_private::ArchSpec &
+    GetProcessArchitecture ();
+
     bool
     GetVContSupported (char flavor);
 
@@ -353,6 +356,9 @@
     }
 protected:
 
+    bool
+    GetCurrentProcessInfo ();
+
     //------------------------------------------------------------------
     // Classes that inherit from GDBRemoteCommunicationClient can see and modify these
     //------------------------------------------------------------------
@@ -366,6 +372,7 @@
     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 @@
     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;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=170491&r1=170490&r2=170491&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Dec 18 20:54:03 2012
@@ -393,7 +393,16 @@
     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 @@
         && !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 @@
 
         // 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();

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=170491&r1=170490&r2=170491&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Tue Dec 18 20:54:03 2012
@@ -3781,8 +3781,7 @@
 
 
 // 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 @@
 
     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 @@
     {
         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 @@
     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());





More information about the lldb-commits mailing list