From 66249323d25f6db1dc76bd9fb3b9eebe436519a6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Micha=C5=82=20G=C3=B3rny?= Date: Sat, 4 Sep 2021 15:19:39 +0200 Subject: [PATCH] [lldb] [gdb-remote] Try using for remote arch unconditionally Try determining the process architecture from tag unconditionally, rather than for very specific cases. Generic gdbserver implementations do not support LLDB-specific packets used to determine the process architecture, therefore this fallback is necessary to support architecture-specific behavior on these targets. Rather than maintaining a mapping of all known architectures, just try mapping the GDB values into triplets, as that is going to work most of the time. This change is confirmed to fix LLDB against gdbserver when debugging i386 and aarch64 executables. Differential Revision: https://reviews.llvm.org/D109272 --- .../Process/gdb-remote/ProcessGDBRemote.cpp | 26 +- .../gdb_remote_client/TestGDBServerTargetXML.py | 261 +++++++++++++++++++++ .../gdb_remote_client/basic_eh_frame-i386.yaml | 47 ++++ 3 files changed, 320 insertions(+), 14 deletions(-) create mode 100644 lldb/test/API/functionalities/gdb_remote_client/basic_eh_frame-i386.yaml diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp index b08fe38..87ad0a3 100644 --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4649,24 +4649,22 @@ bool ProcessGDBRemote::GetGDBServerRegisterInfoXMLAndProcess( } } - // If the target.xml includes an architecture entry like + // gdbserver does not implement the LLDB packets used to determine host + // or process architecture. If that is the case, attempt to use + // the field from target.xml, e.g.: + // // i386:x86-64 (seen from VMWare ESXi) - // arm (seen from Segger JLink on unspecified arm board) - // use that if we don't have anything better. + // arm (seen from Segger JLink on unspecified + // arm board) if (!arch_to_use.IsValid() && !target_info.arch.empty()) { - 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); - } + // We don't have any information about vendor or OS. + arch_to_use.SetTriple(llvm::StringSwitch(target_info.arch) + .Case("i386:x86-64", "x86_64") + .Default(target_info.arch) + + "--"); - // 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--"); + if (arch_to_use.IsValid()) GetTarget().MergeArchitecture(arch_to_use); - } } if (arch_to_use.IsValid()) { diff --git a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py index 255e36a..eabd7d8 100644 --- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py @@ -150,3 +150,264 @@ class TestGDBServerTargetXML(GDBRemoteTestBase): ["rip = 0x8887868584838281"]) self.match("register read flags", ["eflags = 0x94939291"]) + + @skipIfXmlSupportMissing + @skipIfRemote + @skipIfLLVMTargetMissing("X86") + def test_i386_regs(self): + """Test grabbing various i386 registers from gdbserver.""" + reg_data = [ + "01020304", # eax + "11121314", # ecx + "21222324", # edx + "31323334", # ebx + "41424344", # esp + "51525354", # ebp + "61626364", # esi + "71727374", # edi + "81828384", # eip + "91929394", # eflags + "0102030405060708090a", # st0 + "1112131415161718191a", # st1 + ] + 6 * [ + "2122232425262728292a" # st2..st7 + ] + [ + "8182838485868788898a8b8c8d8e8f90", # xmm0 + "9192939495969798999a9b9c9d9e9fa0", # xmm1 + ] + 6 * [ + "a1a2a3a4a5a6a7a8a9aaabacadaeafb0", # xmm2..xmm7 + ] + [ + "00000000", # mxcsr + ] + [ + "b1b2b3b4b5b6b7b8b9babbbcbdbebfc0", # ymm0h + "c1c2c3c4c5c6c7c8c9cacbcccdcecfd0", # ymm1h + ] + 6 * [ + "d1d2d3d4d5d6d7d8d9dadbdcdddedfe0", # ymm2h..ymm7h + ] + + class MyResponder(MockGDBServerResponder): + def qXferRead(self, obj, annex, offset, length): + if annex == "target.xml": + return """ + + + i386 + GNU/Linux + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """, False + else: + return None, False + + def readRegister(self, regnum): + return "" + + def readRegisters(self): + return "".join(reg_data) + + def writeRegisters(self, reg_hex): + return "OK" + + def haltReason(self): + return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;" + + self.server.responder = MyResponder() + + target = self.createTarget("basic_eh_frame-i386.yaml") + process = self.connect(target) + lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, + [lldb.eStateStopped]) + + # test generic aliases + self.match("register read fp", + ["ebp = 0x54535251"]) + self.match("register read pc", + ["eip = 0x84838281"]) + self.match("register read flags", + ["eflags = 0x94939291"]) + + @skipIfXmlSupportMissing + @skipIfRemote + @skipIfLLVMTargetMissing("AArch64") + def test_aarch64_regs(self): + """Test grabbing various aarch64 registers from gdbserver.""" + reg_data = [ + "0102030405060708", # x0 + "1112131415161718", # x1 + ] + 27 * [ + "2122232425262728", # x2..x28 + ] + [ + "3132333435363738", # x29 (fp) + "4142434445464748", # x30 (lr) + "5152535455565758", # x31 (sp) + "6162636465666768", # pc + "71727374", # cpsr + "8182838485868788898a8b8c8d8e8f90", # v0 + "9192939495969798999a9b9c9d9e9fa0", # v1 + ] + 30 * [ + "a1a2a3a4a5a6a7a8a9aaabacadaeafb0", # v2..v31 + ] + [ + "00000000", # fpsr + "00000000", # fpcr + ] + + class MyResponder(MockGDBServerResponder): + def qXferRead(self, obj, annex, offset, length): + if annex == "target.xml": + return """ + + + aarch64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """, False + else: + return None, False + + def readRegister(self, regnum): + return "" + + def readRegisters(self): + return "".join(reg_data) + + def writeRegisters(self, reg_hex): + return "OK" + + def haltReason(self): + return "T02thread:1ff0d;threads:1ff0d;thread-pcs:000000010001bc00;07:0102030405060708;10:1112131415161718;" + + self.server.responder = MyResponder() + + target = self.createTarget("basic_eh_frame-aarch64.yaml") + process = self.connect(target) + lldbutil.expect_state_changes(self, self.dbg.GetListener(), process, + [lldb.eStateStopped]) + + # test GPRs + self.match("register read x0", + ["x0 = 0x0807060504030201"]) + self.match("register read x1", + ["x1 = 0x1817161514131211"]) + self.match("register read sp", + ["sp = 0x5857565554535251"]) + self.match("register read pc", + ["pc = 0x6867666564636261"]) + self.match("register read cpsr", + ["cpsr = 0x74737271"]) + + # test generic aliases + self.match("register read arg1", + ["x0 = 0x0807060504030201"]) + self.match("register read arg2", + ["x1 = 0x1817161514131211"]) + self.match("register read flags", + ["cpsr = 0x74737271"]) diff --git a/lldb/test/API/functionalities/gdb_remote_client/basic_eh_frame-i386.yaml b/lldb/test/API/functionalities/gdb_remote_client/basic_eh_frame-i386.yaml new file mode 100644 index 0000000..ca0c687 --- /dev/null +++ b/lldb/test/API/functionalities/gdb_remote_client/basic_eh_frame-i386.yaml @@ -0,0 +1,47 @@ +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_386 + Entry: 0x00401000 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + Address: 0x00401000 + AddressAlign: 0x00000001 + Content: C3 + - Name: .eh_frame + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC ] + Address: 0x00402000 + AddressAlign: 0x00000008 + Content: 1800000000000000017A5200017810011B0C070890010E80010000001000000020000000DCEFFFFF0100000000000000 +Symbols: + - Name: .text + Type: STT_SECTION + Section: .text + Value: 0x00401000 + - Name: .eh_frame + Type: STT_SECTION + Section: .eh_frame + Value: 0x00402000 + - Name: _start + Binding: STB_GLOBAL + - Name: __bss_start + Section: .eh_frame + Binding: STB_GLOBAL + Value: 0x00404000 + - Name: foo + Section: .text + Binding: STB_GLOBAL + Value: 0x00401000 + - Name: _edata + Section: .eh_frame + Binding: STB_GLOBAL + Value: 0x00404000 + - Name: _end + Section: .eh_frame + Binding: STB_GLOBAL + Value: 0x00404000 -- 2.7.4