[Lldb-commits] [lldb] e35dbb3 - Fix LLDB elf core dump register access for ARM/AArch64

Muhammad Omair Javaid via lldb-commits lldb-commits at lists.llvm.org
Tue Apr 28 21:25:10 PDT 2020


Author: Muhammad Omair Javaid
Date: 2020-04-29T09:24:39+05:00
New Revision: e35dbb3c8878236754c4ec127591d9ef4665bdf8

URL: https://github.com/llvm/llvm-project/commit/e35dbb3c8878236754c4ec127591d9ef4665bdf8
DIFF: https://github.com/llvm/llvm-project/commit/e35dbb3c8878236754c4ec127591d9ef4665bdf8.diff

LOG: Fix LLDB elf core dump register access for ARM/AArch64

Summary:
This patch adds support to access AArch64 FP SIMD core dump registers and adds a test case to verify registers.

This patches fixes a bug where doing "register read --all" causes lldb to crash.

Reviewers: labath

Reviewed By: labath

Subscribers: kristof.beyls, danielkiss, lldb-commits

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

Added: 
    lldb/test/API/functionalities/postmortem/elf-core/aarch64-neon.c
    lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.core
    lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64.core
    lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64.out

Modified: 
    lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
    lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
    lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
    lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
index 310c5e142ef3..b76f26a584c0 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm.cpp
@@ -44,10 +44,12 @@ bool RegisterContextCorePOSIX_arm::WriteFPR() {
 bool RegisterContextCorePOSIX_arm::ReadRegister(const RegisterInfo *reg_info,
                                                 RegisterValue &value) {
   lldb::offset_t offset = reg_info->byte_offset;
-  uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
-  if (offset == reg_info->byte_offset + reg_info->byte_size) {
-    value = v;
-    return true;
+  if (offset + reg_info->byte_size <= GetGPRSize()) {
+    uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+    if (offset == reg_info->byte_offset + reg_info->byte_size) {
+      value = v;
+      return true;
+    }
   }
   return false;
 }

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
index 3e176b6eeff9..95c419b053fa 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.cpp
@@ -24,6 +24,9 @@ RegisterContextCorePOSIX_arm64::RegisterContextCorePOSIX_arm64(
                                                   gpregset.GetByteSize());
   m_gpr.SetData(m_gpr_buffer);
   m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+  m_fpregset = getRegset(
+      notes, register_info->GetTargetArchitecture().GetTriple(), FPR_Desc);
 }
 
 RegisterContextCorePOSIX_arm64::~RegisterContextCorePOSIX_arm64() {}
@@ -45,11 +48,26 @@ bool RegisterContextCorePOSIX_arm64::WriteFPR() {
 bool RegisterContextCorePOSIX_arm64::ReadRegister(const RegisterInfo *reg_info,
                                                   RegisterValue &value) {
   lldb::offset_t offset = reg_info->byte_offset;
-  uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
-  if (offset == reg_info->byte_offset + reg_info->byte_size) {
-    value = v;
-    return true;
+  if (offset + reg_info->byte_size <= GetGPRSize()) {
+    uint64_t v = m_gpr.GetMaxU64(&offset, reg_info->byte_size);
+    if (offset == reg_info->byte_offset + reg_info->byte_size) {
+      value = v;
+      return true;
+    }
   }
+
+  const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
+  if (reg == LLDB_INVALID_REGNUM)
+    return false;
+
+  offset -= GetGPRSize();
+  if (IsFPR(reg) && offset + reg_info->byte_size <= sizeof(FPU)) {
+    Status error;
+    value.SetFromMemoryData(reg_info, m_fpregset.GetDataStart() + offset,
+                            reg_info->byte_size, lldb::eByteOrderLittle, error);
+    return error.Success();
+  }
+
   return false;
 }
 

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
index 7c35d89c4f13..5bbcdf5677f6 100644
--- a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_arm64.h
@@ -48,6 +48,7 @@ class RegisterContextCorePOSIX_arm64 : public RegisterContextPOSIX_arm64 {
 private:
   lldb::DataBufferSP m_gpr_buffer;
   lldb_private::DataExtractor m_gpr;
+  lldb_private::DataExtractor m_fpregset;
 };
 
 #endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_ARM64_H

diff  --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index 435d3358b030..63bb02e5eb60 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -19,6 +19,7 @@ class LinuxCoreTestCase(TestBase):
 
     mydir = TestBase.compute_mydir(__file__)
 
+    _aarch64_pid = 37688
     _i386_pid = 32306
     _x86_64_pid = 32259
     _s390x_pid = 1045
@@ -27,12 +28,20 @@ class LinuxCoreTestCase(TestBase):
     _mips_o32_pid = 3532
     _ppc64le_pid = 28147
 
+    _aarch64_regions = 4
     _i386_regions = 4
     _x86_64_regions = 5
     _s390x_regions = 2
     _mips_regions = 5
     _ppc64le_regions = 2
 
+
+    @skipIf(triple='^mips')
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_aarch64(self):
+        """Test that lldb can read the process information from an aarch64 linux core file."""
+        self.do_test("linux-aarch64", self._aarch64_pid, self._aarch64_regions, "a.out")
+
     @skipIf(triple='^mips')
     @skipIfLLVMTargetMissing("X86")
     def test_i386(self):
@@ -247,6 +256,61 @@ def test_x86_64_sysroot(self):
 
         self.dbg.DeleteTarget(target)
 
+    @skipIf(triple='^mips')
+    @skipIfLLVMTargetMissing("AArch64")
+    def test_aarch64_regs(self):
+        # check 64 bit ARM core files
+        target = self.dbg.CreateTarget(None)
+        self.assertTrue(target, VALID_TARGET)
+        process = target.LoadCore("linux-aarch64-neon.core")
+
+        values = {}
+        values["x1"] = "0x000000000000002f"
+        values["w1"] = "0x0000002f"
+        values["fp"] = "0x0000007fc5dd7f20"
+        values["lr"] = "0x0000000000400180"
+        values["sp"] = "0x0000007fc5dd7f00"
+        values["pc"] = "0x000000000040014c"
+        values["v0"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["v1"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0xf8 0x3f 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["v2"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["v3"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x0c 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["v4"] = "{0x00 0x00 0x90 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["v5"] = "{0x00 0x00 0xb0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["v6"] = "{0x00 0x00 0xd0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["v7"] = "{0x00 0x00 0xf0 0x40 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["v8"] = "{0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11 0x11}"
+        values["v27"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["v28"] = "{0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00}"
+        values["v31"] = "{0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30 0x30}"
+        values["s2"] = "0"
+        values["s3"] = "0"
+        values["s4"] = "4.5"
+        values["s5"] = "5.5"
+        values["s6"] = "6.5"
+        values["s7"] = "7.5"
+        values["s8"] = "1.14437e-28"
+        values["s30"] = "0"
+        values["s31"] = "6.40969e-10"
+        values["d0"] = "0.5"
+        values["d1"] = "1.5"
+        values["d2"] = "2.5"
+        values["d3"] = "3.5"
+        values["d4"] = "5.35161536149201e-315"
+        values["d5"] = "5.36197666906508e-315"
+        values["d6"] = "5.37233797663815e-315"
+        values["d7"] = "5.38269928421123e-315"
+        values["d8"] = "1.80107573659442e-226"
+        values["d30"] = "0"
+        values["d31"] = "1.39804328609529e-76"
+        values["fpsr"] = "0x00000000"
+        values["fpcr"] = "0x00000000"
+
+        for regname, value in values.items():
+            self.expect("register read {}".format(regname), substrs=["{} = {}".format(regname, value)])
+
+        self.expect("register read --all")
+
     @skipIf(triple='^mips')
     @skipIfLLVMTargetMissing("ARM")
     def test_arm_core(self):
@@ -276,6 +340,8 @@ def test_arm_core(self):
         for regname, value in values.items():
             self.expect("register read {}".format(regname), substrs=["{} = {}".format(regname, value)])
 
+        self.expect("register read --all")
+
     def check_memory_regions(self, process, region_count):
         region_list = process.GetMemoryRegions()
         self.assertEqual(region_list.GetSize(), region_count)

diff  --git a/lldb/test/API/functionalities/postmortem/elf-core/aarch64-neon.c b/lldb/test/API/functionalities/postmortem/elf-core/aarch64-neon.c
new file mode 100644
index 000000000000..e5742d2e44b7
--- /dev/null
+++ b/lldb/test/API/functionalities/postmortem/elf-core/aarch64-neon.c
@@ -0,0 +1,28 @@
+// compile with -march=armv8-a+sve on compatible aarch64 compiler
+// linux-aarch64-sve.core was generated by: aarch64-linux-gnu-gcc-8
+// commandline: -march=armv8-a+sve -nostdlib -static -g linux-aarch64-sve.c
+static void bar(char *boom) {
+  char F = 'b';
+  asm volatile("fmov     d0,  #0.5\n\t");
+  asm volatile("fmov     d1,  #1.5\n\t");
+  asm volatile("fmov     d2,  #2.5\n\t");
+  asm volatile("fmov     d3,  #3.5\n\t");
+  asm volatile("fmov     s4,  #4.5\n\t");
+  asm volatile("fmov     s5,  #5.5\n\t");
+  asm volatile("fmov     s6,  #6.5\n\t");
+  asm volatile("fmov     s7,  #7.5\n\t");
+  asm volatile("movi     v8.16b, #0x11\n\t");
+  asm volatile("movi     v31.16b, #0x30\n\t");
+
+  *boom = 47; // Frame bar
+}
+
+static void foo(char *boom, void (*boomer)(char *)) {
+  char F = 'f';
+  boomer(boom); // Frame foo
+}
+
+void _start(void) {
+  char F = '_';
+  foo(0, bar); // Frame _start
+}

diff  --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.core b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.core
new file mode 100644
index 000000000000..5444c53a896a
Binary files /dev/null and b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64-neon.core 
diff er

diff  --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64.core b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64.core
new file mode 100644
index 000000000000..f9211cab2778
Binary files /dev/null and b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64.core 
diff er

diff  --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64.out b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64.out
new file mode 100755
index 000000000000..78304a97a826
Binary files /dev/null and b/lldb/test/API/functionalities/postmortem/elf-core/linux-aarch64.out 
diff er


        


More information about the lldb-commits mailing list