diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp --- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp +++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp @@ -4649,24 +4649,22 @@ } } - // 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 --- a/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py +++ b/lldb/test/API/functionalities/gdb_remote_client/TestGDBServerTargetXML.py @@ -150,3 +150,264 @@ ["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 --- /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