[Lldb-commits] [lldb] r345106 - Support nwere versions of the Segger J-Link jtag board software.

Jason Molenda via lldb-commits lldb-commits at lists.llvm.org
Tue Oct 23 16:45:56 PDT 2018


Author: jmolenda
Date: Tue Oct 23 16:45:56 2018
New Revision: 345106

URL: http://llvm.org/viewvc/llvm-project?rev=345106&view=rev
Log:
Support nwere versions of the Segger J-Link jtag board software.
Add support in ProcessGDBRemote::GetGDBServerRegisterInfo
for recognizing a generic "arm" architecture that will be used if
nothing better is available so that we don't ignore the register
definitions if we didn't already have an architecture set.
Also in ProcessGDBRemote::DoConnectRemote don't set the target
arch unless we have a valid architecture to set it to.

Platform::ConnectProcess will try to get the current target's
architecture, or the default architecture, when creating the 
target for the connection to be attempted.  If lldb was started
with a target binary, we want to create this target with that
architecture in case the remote gdb stub doesn't supply a
qHostInfo arch.

Add logging to Target::MergeArchitecture.

<rdar://problem/34916465> 


Added:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestArmRegisterDefinition.py
Modified:
    lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Target/Platform.cpp
    lldb/trunk/source/Target/Target.cpp

Added: lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestArmRegisterDefinition.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestArmRegisterDefinition.py?rev=345106&view=auto
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestArmRegisterDefinition.py (added)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/TestArmRegisterDefinition.py Tue Oct 23 16:45:56 2018
@@ -0,0 +1,130 @@
+from __future__ import print_function
+import lldb
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test.decorators import *
+from gdbclientutils import *
+
+class TestArmRegisterDefinition(GDBRemoteTestBase):
+
+    @skipIfXmlSupportMissing
+    @skipIfRemote
+    def test(self):
+        """
+        Test lldb's parsing of the <architecture> tag in the target.xml register
+        description packet.
+        """
+        class MyResponder(MockGDBServerResponder):
+
+            def qXferRead(self, obj, annex, offset, length):
+                if annex == "target.xml":
+                    return """<?xml version="1.0"?>
+                        <!DOCTYPE feature SYSTEM "gdb-target.dtd">
+                        <target>
+                        <architecture>arm</architecture>
+                        <feature name="org.gnu.gdb.arm.m-profile">
+                        <reg name="r0" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r1" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r2" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r3" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r4" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r5" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r6" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r7" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r8" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r9" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r10" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r11" bitsize="32" type="uint32" group="general"/>
+                        <reg name="r12" bitsize="32" type="uint32" group="general"/>
+                        <reg name="sp" bitsize="32" type="data_ptr" group="general"/>
+                        <reg name="lr" bitsize="32" type="uint32" group="general"/>
+                        <reg name="pc" bitsize="32" type="code_ptr" group="general"/>
+                        <reg name="xpsr" bitsize="32" regnum="25" type="uint32" group="general"/>
+                        <reg name="MSP" bitsize="32" regnum="26" type="uint32" group="general"/>
+                        <reg name="PSP" bitsize="32" regnum="27" type="uint32" group="general"/>
+                        <reg name="PRIMASK" bitsize="32" regnum="28" type="uint32" group="general"/>
+                        <reg name="BASEPRI" bitsize="32" regnum="29" type="uint32" group="general"/>
+                        <reg name="FAULTMASK" bitsize="32" regnum="30" type="uint32" group="general"/>
+                        <reg name="CONTROL" bitsize="32" regnum="31" type="uint32" group="general"/>
+                        <reg name="FPSCR" bitsize="32" type="uint32" group="float"/>
+                        <reg name="s0" bitsize="32" type="float" group="float"/>
+                        <reg name="s1" bitsize="32" type="float" group="float"/>
+                        <reg name="s2" bitsize="32" type="float" group="float"/>
+                        <reg name="s3" bitsize="32" type="float" group="float"/>
+                        <reg name="s4" bitsize="32" type="float" group="float"/>
+                        <reg name="s5" bitsize="32" type="float" group="float"/>
+                        <reg name="s6" bitsize="32" type="float" group="float"/>
+                        <reg name="s7" bitsize="32" type="float" group="float"/>
+                        <reg name="s8" bitsize="32" type="float" group="float"/>
+                        <reg name="s9" bitsize="32" type="float" group="float"/>
+                        <reg name="s10" bitsize="32" type="float" group="float"/>
+                        <reg name="s11" bitsize="32" type="float" group="float"/>
+                        <reg name="s12" bitsize="32" type="float" group="float"/>
+                        <reg name="s13" bitsize="32" type="float" group="float"/>
+                        <reg name="s14" bitsize="32" type="float" group="float"/>
+                        <reg name="s15" bitsize="32" type="float" group="float"/>
+                        <reg name="s16" bitsize="32" type="float" group="float"/>
+                        <reg name="s17" bitsize="32" type="float" group="float"/>
+                        <reg name="s18" bitsize="32" type="float" group="float"/>
+                        <reg name="s19" bitsize="32" type="float" group="float"/>
+                        <reg name="s20" bitsize="32" type="float" group="float"/>
+                        <reg name="s21" bitsize="32" type="float" group="float"/>
+                        <reg name="s22" bitsize="32" type="float" group="float"/>
+                        <reg name="s23" bitsize="32" type="float" group="float"/>
+                        <reg name="s24" bitsize="32" type="float" group="float"/>
+                        <reg name="s25" bitsize="32" type="float" group="float"/>
+                        <reg name="s26" bitsize="32" type="float" group="float"/>
+                        <reg name="s27" bitsize="32" type="float" group="float"/>
+                        <reg name="s28" bitsize="32" type="float" group="float"/>
+                        <reg name="s29" bitsize="32" type="float" group="float"/>
+                        <reg name="s30" bitsize="32" type="float" group="float"/>
+                        <reg name="s31" bitsize="32" type="float" group="float"/>
+                        </feature>
+                        </target>""", False
+                else:
+                    return None, False
+
+            def readRegister(self, regnum):
+                return "E01"
+
+            def readRegisters(self):
+                return "20000000f8360020001000002fcb0008f8360020a0360020200c0020000000000000000000000000000000000000000000000000b87f0120b7d100082ed2000800000001b87f01200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
+
+            def haltReason(self):
+                return "S05"
+
+            def qfThreadInfo(self):
+                return "mdead"
+            
+            def qC(self):
+                return ""
+
+            def qSupported(self, client_supported):
+                return "PacketSize=4000;qXfer:memory-map:read-;QStartNoAckMode+;qXfer:threads:read+;hwbreak+;qXfer:features:read+"
+
+            def QThreadSuffixSupported(self):
+                return "OK"
+
+            def QListThreadsInStopReply(self):
+                return "OK"
+
+        self.server.responder = MyResponder()
+        if self.TraceOn():
+            interp = self.dbg.GetCommandInterpreter()
+            result = lldb.SBCommandReturnObject()
+            interp.HandleCommand("log enable gdb-remote packets", result)
+        self.dbg.SetDefaultArchitecture("armv7em")
+        target = self.dbg.CreateTargetWithFileAndArch(None, None)
+
+        process = self.connect(target)
+
+        if self.TraceOn():
+            interp = self.dbg.GetCommandInterpreter()
+            result = lldb.SBCommandReturnObject()
+            interp.HandleCommand("target list", result)
+            print(result.GetOutput())
+
+        r0_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("r0")
+        self.assertEqual(r0_valobj.GetValueAsUnsigned(), 0x20)
+
+        pc_valobj = process.GetThreadAtIndex(0).GetFrameAtIndex(0).FindRegister("pc")
+        self.assertEqual(pc_valobj.GetValueAsUnsigned(), 0x0800d22e)

Modified: lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py?rev=345106&r1=345105&r2=345106&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/functionalities/gdb_remote_client/gdbclientutils.py Tue Oct 23 16:45:56 2018
@@ -102,12 +102,13 @@ class MockGDBServerResponder:
             return self.interrupt()
         if packet == "c":
             return self.cont()
-        if packet == "g":
+        if packet[0] == "g":
             return self.readRegisters()
         if packet[0] == "G":
             return self.writeRegisters(packet[1:])
         if packet[0] == "p":
-            return self.readRegister(int(packet[1:], 16))
+            regnum = packet[1:].split(';')[0]
+            return self.readRegister(int(regnum, 16))
         if packet[0] == "P":
             register, value = packet[1:].split("=")
             return self.readRegister(int(register, 16), value)
@@ -124,6 +125,8 @@ class MockGDBServerResponder:
             return self.qSupported(packet[11:].split(";"))
         if packet == "qfThreadInfo":
             return self.qfThreadInfo()
+        if packet == "qsThreadInfo":
+            return self.qsThreadInfo()
         if packet == "qC":
             return self.qC()
         if packet == "QEnableErrorStrings":
@@ -149,6 +152,13 @@ class MockGDBServerResponder:
         if packet.startswith("qThreadStopInfo"):
             threadnum = int (packet[15:], 16)
             return self.threadStopInfo(threadnum)
+        if packet == "QThreadSuffixSupported":
+            return self.QThreadSuffixSupported()
+        if packet == "QListThreadsInStopReply":
+            return self.QListThreadsInStopReply()
+        if packet.startswith("qMemoryRegionInfo:"):
+            return self.qMemoryRegionInfo()
+
         return self.other(packet)
 
     def interrupt(self):
@@ -184,6 +194,9 @@ class MockGDBServerResponder:
     def qfThreadInfo(self):
         return "l"
 
+    def qsThreadInfo(self):
+        return "l"
+
     def qC(self):
         return "QC0"
 
@@ -216,6 +229,15 @@ class MockGDBServerResponder:
         # empty string means unsupported
         return ""
 
+    def QThreadSuffixSupported(self):
+        return ""
+
+    def QListThreadsInStopReply(self):
+        return ""
+
+    def qMemoryRegionInfo(self):
+        return ""
+
     """
     Raised when we receive a packet for which there is no default action.
     Override the responder class to implement behavior suitable for the test at

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=345106&r1=345105&r2=345106&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue Oct 23 16:45:56 2018
@@ -688,7 +688,9 @@ Status ProcessGDBRemote::DoConnectRemote
         if (m_gdb_comm.GetProcessArchitecture().IsValid()) {
           target.SetArchitecture(m_gdb_comm.GetProcessArchitecture());
         } else {
-          target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
+          if (m_gdb_comm.GetHostArchitecture().IsValid()) {
+            target.SetArchitecture(m_gdb_comm.GetHostArchitecture());
+          }
         }
       }
 
@@ -4508,12 +4510,19 @@ bool ProcessGDBRemote::GetGDBServerRegis
       //   <architecture>arm</architecture> (seen from Segger JLink on unspecified arm board)
       // use that if we don't have anything better.
       if (!arch_to_use.IsValid() && !target_info.arch.empty()) {
-        if (target_info.arch == "i386:x86-64")
-        {
+        if (target_info.arch == "i386:x86-64") {
           // We don't have any information about vendor or OS.
           arch_to_use.SetTriple("x86_64--");
           GetTarget().MergeArchitecture(arch_to_use);
         }
+
+        // SEGGER J-Link jtag boards send this very-generic arch name,
+        // we'll need to use this if we have absolutely nothing better
+        // to work with or the register definitions won't be accepted.
+        if (target_info.arch == "arm") {
+          arch_to_use.SetTriple("arm--");
+          GetTarget().MergeArchitecture(arch_to_use);
+        }
       }
 
       // Initialize these outside of ParseRegisters, since they should not be

Modified: lldb/trunk/source/Target/Platform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Platform.cpp?rev=345106&r1=345105&r2=345106&view=diff
==============================================================================
--- lldb/trunk/source/Target/Platform.cpp (original)
+++ lldb/trunk/source/Target/Platform.cpp Tue Oct 23 16:45:56 2018
@@ -1820,9 +1820,19 @@ lldb::ProcessSP Platform::ConnectProcess
   error.Clear();
 
   if (!target) {
+    ArchSpec arch;
+    if (target && target->GetArchitecture().IsValid())
+      arch = target->GetArchitecture();
+    else
+      arch = Target::GetDefaultArchitecture();
+
+    const char *triple = "";
+    if (arch.IsValid())
+      triple = arch.GetTriple().getTriple().c_str();
+
     TargetSP new_target_sp;
     error = debugger.GetTargetList().CreateTarget(
-        debugger, "", "", eLoadDependentsNo, nullptr, new_target_sp);
+        debugger, "", triple, eLoadDependentsNo, nullptr, new_target_sp);
     target = new_target_sp.get();
   }
 

Modified: lldb/trunk/source/Target/Target.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=345106&r1=345105&r2=345106&view=diff
==============================================================================
--- lldb/trunk/source/Target/Target.cpp (original)
+++ lldb/trunk/source/Target/Target.cpp Tue Oct 23 16:45:56 2018
@@ -1572,11 +1572,18 @@ bool Target::SetArchitecture(const ArchS
 }
 
 bool Target::MergeArchitecture(const ArchSpec &arch_spec) {
+  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_TARGET));
   if (arch_spec.IsValid()) {
     if (m_arch.GetSpec().IsCompatibleMatch(arch_spec)) {
       // The current target arch is compatible with "arch_spec", see if we can
       // improve our current architecture using bits from "arch_spec"
 
+      if (log)
+        log->Printf("Target::MergeArchitecture target has arch %s, merging with "
+                    "arch %s", 
+                    m_arch.GetSpec().GetTriple().getTriple().c_str(),
+                    arch_spec.GetTriple().getTriple().c_str());
+
       // Merge bits from arch_spec into "merged_arch" and set our architecture
       ArchSpec merged_arch(m_arch.GetSpec());
       merged_arch.MergeFrom(arch_spec);




More information about the lldb-commits mailing list