[lldb] [Process/elf-core] Support aarch64 NetBSD core dumps
authorMichal Gorny <mgorny@gentoo.org>
Mon, 1 Apr 2019 15:08:24 +0000 (15:08 +0000)
committerMichal Gorny <mgorny@gentoo.org>
Mon, 1 Apr 2019 15:08:24 +0000 (15:08 +0000)
Include support for NetBSD core dumps from evbarm/aarch64 system,
and matching test cases for them.

Based on earlier work by Kamil Rytarowski.

Differential Revision: https://reviews.llvm.org/D60034

llvm-svn: 357399

lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.aarch64 [new file with mode: 0755]
lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.aarch64.core [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.aarch64 [new file with mode: 0755]
lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.aarch64.core [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.aarch64 [new file with mode: 0755]
lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.aarch64.core [new file with mode: 0644]
lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/TestNetBSDCore.py
lldb/source/Plugins/Process/elf-core/ProcessElfCore.cpp
lldb/source/Plugins/Process/elf-core/RegisterUtilities.h
lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp

diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.aarch64 b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.aarch64
new file mode 100755 (executable)
index 0000000..de0208c
Binary files /dev/null and b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.aarch64 differ
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.aarch64.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.aarch64.core
new file mode 100644 (file)
index 0000000..daee798
Binary files /dev/null and b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/1lwp_SIGSEGV.aarch64.core differ
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.aarch64 b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.aarch64
new file mode 100755 (executable)
index 0000000..8781f03
Binary files /dev/null and b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.aarch64 differ
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.aarch64.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.aarch64.core
new file mode 100644 (file)
index 0000000..b58c97c
Binary files /dev/null and b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_process_SIGSEGV.aarch64.core differ
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.aarch64 b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.aarch64
new file mode 100755 (executable)
index 0000000..89394a7
Binary files /dev/null and b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.aarch64 differ
diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.aarch64.core b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.aarch64.core
new file mode 100644 (file)
index 0000000..b268e05
Binary files /dev/null and b/lldb/packages/Python/lldbsuite/test/functionalities/postmortem/netbsd-core/2lwp_t2_SIGSEGV.aarch64.core differ
index 6d30374..320a566 100644 (file)
@@ -168,6 +168,11 @@ class NetBSD1LWPCoreTestCase(NetBSDCoreCommonTestCase):
         backtrace = ["bar", "foo", "main"]
         self.check_backtrace(thread, filename, backtrace)
 
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_aarch64(self):
+        """Test single-threaded aarch64 core dump."""
+        self.do_test("1lwp_SIGSEGV.aarch64", pid=8339, region_count=32)
+
     @skipIfLLVMTargetMissing("X86")
     def test_amd64(self):
         """Test single-threaded amd64 core dump."""
@@ -193,6 +198,11 @@ class NetBSD2LWPT2CoreTestCase(NetBSDCoreCommonTestCase):
         self.assertEqual(thread.GetStopReasonDataCount(), 1)
         self.assertEqual(thread.GetStopReasonDataAtIndex(0), 0)
 
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_aarch64(self):
+        """Test double-threaded aarch64 core dump where thread 2 is signalled."""
+        self.do_test("2lwp_t2_SIGSEGV.aarch64", pid=14142, region_count=31)
+
     @skipIfLLVMTargetMissing("X86")
     def test_amd64(self):
         """Test double-threaded amd64 core dump where thread 2 is signalled."""
@@ -218,6 +228,11 @@ class NetBSD2LWPProcessSigCoreTestCase(NetBSDCoreCommonTestCase):
         self.assertEqual(thread.GetStopReasonDataCount(), 1)
         self.assertEqual(thread.GetStopReasonDataAtIndex(0), signal.SIGSEGV)
 
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_aarch64(self):
+        """Test double-threaded aarch64 core dump where process is signalled."""
+        self.do_test("2lwp_process_SIGSEGV.aarch64", pid=1403, region_count=30)
+
     @skipIfLLVMTargetMissing("X86")
     def test_amd64(self):
         """Test double-threaded amd64 core dump where process is signalled."""
index c257957..1c79705 100644 (file)
@@ -628,6 +628,32 @@ llvm::Error ProcessElfCore::parseNetBSDNotes(llvm::ArrayRef<CoreNote> notes) {
             llvm::inconvertibleErrorCode());
 
       switch (GetArchitecture().GetMachine()) {
+      case llvm::Triple::aarch64: {
+        // Assume order PT_GETREGS, PT_GETFPREGS
+        if (note.info.n_type == NETBSD::AARCH64::NT_REGS) {
+          // If this is the next thread, push the previous one first.
+          if (had_nt_regs) {
+            m_thread_data.push_back(thread_data);
+            thread_data = ThreadData();
+            had_nt_regs = false;
+          }
+
+          thread_data.gpregset = note.data;
+          thread_data.tid = tid;
+          if (thread_data.gpregset.GetByteSize() == 0)
+            return llvm::make_error<llvm::StringError>(
+                "Could not find general purpose registers note in core file.",
+                llvm::inconvertibleErrorCode());
+          had_nt_regs = true;
+        } else if (note.info.n_type == NETBSD::AARCH64::NT_FPREGS) {
+          if (!had_nt_regs || tid != thread_data.tid)
+            return llvm::make_error<llvm::StringError>(
+                "Error parsing NetBSD core(5) notes: Unexpected order "
+                "of NOTEs PT_GETFPREG before PT_GETREG",
+                llvm::inconvertibleErrorCode());
+          thread_data.notes.push_back(note);
+        }
+      } break;
       case llvm::Triple::x86_64: {
         // Assume order PT_GETREGS, PT_GETFPREGS
         if (note.info.n_type == NETBSD::AMD64::NT_REGS) {
index 26b0fdd..d3b3373 100644 (file)
@@ -57,6 +57,10 @@ enum {
   NT_PROCINFO_CPI_SIGLWP_SIZE = 4,
 };
 
+namespace AARCH64 {
+enum { NT_REGS = 32, NT_FPREGS = 34 };
+}
+
 namespace AMD64 {
 enum { NT_REGS = 33, NT_FPREGS = 35 };
 }
@@ -124,6 +128,7 @@ constexpr RegsetDesc FPR_Desc[] = {
     // The result from FXSAVE is in NT_PRXFPREG for i386 core files
     {llvm::Triple::Linux, llvm::Triple::x86, LINUX::NT_PRXFPREG},
     {llvm::Triple::Linux, llvm::Triple::UnknownArch, LINUX::NT_FPREGSET},
+    {llvm::Triple::NetBSD, llvm::Triple::aarch64, NETBSD::AARCH64::NT_FPREGS},
     {llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::AMD64::NT_FPREGS},
     {llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS},
 };
index d76a892..948f52c 100644 (file)
@@ -112,6 +112,9 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
 
     case llvm::Triple::NetBSD: {
       switch (arch.GetMachine()) {
+      case llvm::Triple::aarch64:
+        reg_interface = new RegisterInfoPOSIX_arm64(arch);
+        break;
       case llvm::Triple::x86_64:
         reg_interface = new RegisterContextNetBSD_x86_64(arch);
         break;