[Lldb-commits] [lldb] d3a9043 - [lldb][RISCV] Add RegisterContextPOSIXCore for RISC-V 64 (#93297)

via lldb-commits lldb-commits at lists.llvm.org
Wed Jun 5 02:14:53 PDT 2024


Author: Alexey Merzlyakov
Date: 2024-06-05T10:14:48+01:00
New Revision: d3a9043ec2ee7ea278be4f3c86823512e44d01bf

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

LOG: [lldb][RISCV] Add RegisterContextPOSIXCore for RISC-V 64 (#93297)

The PR adds the support of CoreDump debugging for RISC-V 64. It
implements new `RegisterContextCorePOSIX_riscv64` class.

Also, the contribution fixes `GetRegisterCount()` ->
`GetRegisterSetCount()` misprint in
`RegisterContextPOSIX_riscv64::GetRegisterSetCount()` method, which
leaded to `set && "Register set should be valid."` assertion during
`register info aX` command call.

The patch was tested (on coredumps generated for simple Integer/FP
calculation code) for _cross x86_64 -> RISCV_ and _native RISCV_ LLDB
builds. There were performed basic LLDB functionality tests, such as:

 - CoreDump file load
 - Backtrace / frames
 - GP/FP registers read/info/list
 - Basic switch between threads
 - Disassembler code
 - Memory regions read / display

Added: 
    lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_riscv64.cpp
    lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_riscv64.h
    lldb/test/API/functionalities/postmortem/elf-core/linux-riscv64.core
    lldb/test/API/functionalities/postmortem/elf-core/linux-riscv64.out

Modified: 
    lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.cpp
    lldb/source/Plugins/Process/elf-core/CMakeLists.txt
    lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
    lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py

Removed: 
    


################################################################################
diff  --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.cpp
index 1834a94dc0260..035ce00e11626 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv64.cpp
@@ -58,7 +58,7 @@ RegisterContextPOSIX_riscv64::GetRegisterInfoAtIndex(size_t reg) {
 }
 
 size_t RegisterContextPOSIX_riscv64::GetRegisterSetCount() {
-  return m_register_info_up->GetRegisterCount();
+  return m_register_info_up->GetRegisterSetCount();
 }
 
 const lldb_private::RegisterSet *

diff  --git a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt
index 8ddc671e3ae66..72925c835b5c8 100644
--- a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt
@@ -9,6 +9,7 @@ add_lldb_library(lldbPluginProcessElfCore PLUGIN
   RegisterContextPOSIXCore_ppc64le.cpp
   RegisterContextPOSIXCore_s390x.cpp
   RegisterContextPOSIXCore_x86_64.cpp
+  RegisterContextPOSIXCore_riscv64.cpp
   RegisterUtilities.cpp
 
   LINK_LIBS

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_riscv64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_riscv64.cpp
new file mode 100644
index 0000000000000..5ba18cdb9889a
--- /dev/null
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_riscv64.cpp
@@ -0,0 +1,82 @@
+//===-- RegisterContextPOSIXCore_riscv64.cpp ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextPOSIXCore_riscv64.h"
+
+#include "lldb/Utility/DataBufferHeap.h"
+
+using namespace lldb_private;
+
+std::unique_ptr<RegisterContextCorePOSIX_riscv64>
+RegisterContextCorePOSIX_riscv64::Create(Thread &thread, const ArchSpec &arch,
+                                         const DataExtractor &gpregset,
+                                         llvm::ArrayRef<CoreNote> notes) {
+  return std::unique_ptr<RegisterContextCorePOSIX_riscv64>(
+      new RegisterContextCorePOSIX_riscv64(
+          thread, std::make_unique<RegisterInfoPOSIX_riscv64>(arch, Flags()),
+          gpregset, notes));
+}
+
+RegisterContextCorePOSIX_riscv64::RegisterContextCorePOSIX_riscv64(
+    Thread &thread, std::unique_ptr<RegisterInfoPOSIX_riscv64> register_info,
+    const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
+    : RegisterContextPOSIX_riscv64(thread, std::move(register_info)) {
+
+  m_gpr_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
+                                                  gpregset.GetByteSize());
+  m_gpr.SetData(m_gpr_buffer);
+  m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+  ArchSpec arch = m_register_info_up->GetTargetArchitecture();
+  DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc);
+  m_fpr_buffer = std::make_shared<DataBufferHeap>(fpregset.GetDataStart(),
+                                                  fpregset.GetByteSize());
+  m_fpr.SetData(m_fpr_buffer);
+  m_fpr.SetByteOrder(fpregset.GetByteOrder());
+}
+
+RegisterContextCorePOSIX_riscv64::~RegisterContextCorePOSIX_riscv64() = default;
+
+bool RegisterContextCorePOSIX_riscv64::ReadGPR() { return true; }
+
+bool RegisterContextCorePOSIX_riscv64::ReadFPR() { return true; }
+
+bool RegisterContextCorePOSIX_riscv64::WriteGPR() {
+  assert(false && "Writing registers is not allowed for core dumps");
+  return false;
+}
+
+bool RegisterContextCorePOSIX_riscv64::WriteFPR() {
+  assert(false && "Writing registers is not allowed for core dumps");
+  return false;
+}
+
+bool RegisterContextCorePOSIX_riscv64::ReadRegister(
+    const RegisterInfo *reg_info, RegisterValue &value) {
+  const uint8_t *src = nullptr;
+  lldb::offset_t offset = reg_info->byte_offset;
+
+  if (IsGPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+    src = m_gpr.GetDataStart();
+  } else if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
+    src = m_fpr.GetDataStart();
+    offset -= GetGPRSize();
+  } else {
+    return false;
+  }
+
+  Status error;
+  value.SetFromMemoryData(*reg_info, src + offset, reg_info->byte_size,
+                          lldb::eByteOrderLittle, error);
+  return error.Success();
+}
+
+bool RegisterContextCorePOSIX_riscv64::WriteRegister(
+    const RegisterInfo *reg_info, const RegisterValue &value) {
+  return false;
+}

diff  --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_riscv64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_riscv64.h
new file mode 100644
index 0000000000000..3cf9531df2c1d
--- /dev/null
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_riscv64.h
@@ -0,0 +1,60 @@
+//===-- RegisterContextPOSIXCore_riscv64.h ----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_RISCV64_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_RISCV64_H
+
+#include "Plugins/Process/Utility/RegisterContextPOSIX_riscv64.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.h"
+
+#include "Plugins/Process/elf-core/RegisterUtilities.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/RegisterValue.h"
+
+#include <memory>
+
+class RegisterContextCorePOSIX_riscv64 : public RegisterContextPOSIX_riscv64 {
+public:
+  static std::unique_ptr<RegisterContextCorePOSIX_riscv64>
+  Create(lldb_private::Thread &thread, const lldb_private::ArchSpec &arch,
+         const lldb_private::DataExtractor &gpregset,
+         llvm::ArrayRef<lldb_private::CoreNote> notes);
+
+  ~RegisterContextCorePOSIX_riscv64() override;
+
+  bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
+                    lldb_private::RegisterValue &value) override;
+
+  bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
+                     const lldb_private::RegisterValue &value) override;
+
+protected:
+  RegisterContextCorePOSIX_riscv64(
+      lldb_private::Thread &thread,
+      std::unique_ptr<RegisterInfoPOSIX_riscv64> register_info,
+      const lldb_private::DataExtractor &gpregset,
+      llvm::ArrayRef<lldb_private::CoreNote> notes);
+
+  bool ReadGPR() override;
+
+  bool ReadFPR() override;
+
+  bool WriteGPR() override;
+
+  bool WriteFPR() override;
+
+private:
+  lldb::DataBufferSP m_gpr_buffer;
+  lldb::DataBufferSP m_fpr_buffer;
+
+  lldb_private::DataExtractor m_gpr;
+  lldb_private::DataExtractor m_fpr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_RISCV64_H

diff  --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
index 3ce2a4a5c3fa4..2a83163884e16 100644
--- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
+++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp
@@ -35,6 +35,7 @@
 #include "RegisterContextPOSIXCore_mips64.h"
 #include "RegisterContextPOSIXCore_powerpc.h"
 #include "RegisterContextPOSIXCore_ppc64le.h"
+#include "RegisterContextPOSIXCore_riscv64.h"
 #include "RegisterContextPOSIXCore_s390x.h"
 #include "RegisterContextPOSIXCore_x86_64.h"
 #include "ThreadElfCore.h"
@@ -168,7 +169,8 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
     }
 
     if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64 &&
-        arch.GetMachine() != llvm::Triple::arm) {
+        arch.GetMachine() != llvm::Triple::arm &&
+        arch.GetMachine() != llvm::Triple::riscv64) {
       LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported",
                 __FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
       assert(false && "Architecture or OS not supported");
@@ -184,6 +186,10 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
           *this, std::make_unique<RegisterInfoPOSIX_arm>(arch), m_gpregset_data,
           m_notes);
       break;
+    case llvm::Triple::riscv64:
+      m_thread_reg_ctx_sp = RegisterContextCorePOSIX_riscv64::Create(
+          *this, arch, m_gpregset_data, m_notes);
+      break;
     case llvm::Triple::mipsel:
     case llvm::Triple::mips:
       m_thread_reg_ctx_sp = std::make_shared<RegisterContextCorePOSIX_mips64>(

diff  --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
index 8ec0cbdd0fdd1..1eaaa87d3b87d 100644
--- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
+++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py
@@ -21,12 +21,14 @@ class LinuxCoreTestCase(TestBase):
     _x86_64_pid = 32259
     _s390x_pid = 1045
     _ppc64le_pid = 28147
+    _riscv64_pid = 89328
 
     _aarch64_regions = 4
     _i386_regions = 4
     _x86_64_regions = 5
     _s390x_regions = 2
     _ppc64le_regions = 2
+    _riscv64_regions = 4
 
     @skipIfLLVMTargetMissing("AArch64")
     def test_aarch64(self):
@@ -58,6 +60,11 @@ def test_s390x(self):
         """Test that lldb can read the process information from an s390x linux core file."""
         self.do_test("linux-s390x", self._s390x_pid, self._s390x_regions, "a.out")
 
+    @skipIfLLVMTargetMissing("RISCV")
+    def test_riscv64(self):
+        """Test that lldb can read the process information from an riscv64 linux core file."""
+        self.do_test("linux-riscv64", self._riscv64_pid, self._riscv64_regions, "a.out")
+
     @skipIfLLVMTargetMissing("X86")
     def test_same_pid_running(self):
         """Test that we read the information from the core correctly even if we have a running
@@ -629,6 +636,99 @@ def test_arm_core(self):
 
         self.expect("register read --all")
 
+    @skipIfLLVMTargetMissing("RISCV")
+    def test_riscv64_regs(self):
+        # check basic registers using 64 bit RISC-V core file
+        target = self.dbg.CreateTarget(None)
+        self.assertTrue(target, VALID_TARGET)
+        process = target.LoadCore("linux-riscv64.core")
+
+        values = {}
+        values["pc"] = "0x000000000001015e"
+        values["ra"] = "0x000000000001018c"
+        values["sp"] = "0x0000003fffd132a0"
+        values["gp"] = "0x0000002ae919af50"
+        values["tp"] = "0x0000003fdceae3e0"
+        values["t0"] = "0x0"
+        values["t1"] = "0x0000002ae9187b1c"
+        values["t2"] = "0x0000000000000021"
+        values["fp"] = "0x0000003fffd132d0"
+        values["s1"] = "0x0000002ae919cd98"
+        values["a0"] = "0x0"
+        values["a1"] = "0x0000000000010144"
+        values["a2"] = "0x0000002ae919cdb0"
+        values["a3"] = "0x000000000000002f"
+        values["a4"] = "0x000000000000002f"
+        values["a5"] = "0x0"
+        values["a6"] = "0x7efefefefefefeff"
+        values["a7"] = "0x00000000000000dd"
+        values["s2"] = "0x0000002ae9196860"
+        values["s3"] = "0x0000002ae919cdb0"
+        values["s4"] = "0x0000003fffc63be8"
+        values["s5"] = "0x0000002ae919cb78"
+        values["s6"] = "0x0000002ae9196860"
+        values["s7"] = "0x0000002ae9196860"
+        values["s8"] = "0x0"
+        values["s9"] = "0x000000000000000f"
+        values["s10"] = "0x0000002ae919a8d0"
+        values["s11"] = "0x0000000000000008"
+        values["t3"] = "0x0000003fdce07df4"
+        values["t4"] = "0x0"
+        values["t5"] = "0x0000000000000020"
+        values["t6"] = "0x0000002ae919f1b0"
+        values["zero"] = "0x0"
+        values["fcsr"] = "0x00000000"
+
+        fpr_names = {
+            "ft0",
+            "ft1",
+            "ft2",
+            "ft3",
+            "ft4",
+            "ft5",
+            "ft6",
+            "ft7",
+            "ft8",
+            "ft9",
+            "ft10",
+            "ft11",
+            "fa0",
+            "fa1",
+            "fa2",
+            "fa3",
+            "fa4",
+            "fa5",
+            "fa6",
+            "fa7",
+            "fs0",
+            "fs1",
+            "fs2",
+            "fs3",
+            "fs4",
+            "fs5",
+            "fs6",
+            "fs7",
+            "fs8",
+            "fs9",
+            "fs10",
+            "fs11",
+        }
+        fpr_value = "0x0000000000000000"
+
+        for regname, value in values.items():
+            self.expect(
+                "register read {}".format(regname),
+                substrs=["{} = {}".format(regname, value)],
+            )
+
+        for regname in fpr_names:
+            self.expect(
+                "register read {}".format(regname),
+                substrs=["{} = {}".format(regname, fpr_value)],
+            )
+
+        self.expect("register read --all")
+
     def test_get_core_file_api(self):
         """
         Test SBProcess::GetCoreFile() API can successfully get the core file.

diff  --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-riscv64.core b/lldb/test/API/functionalities/postmortem/elf-core/linux-riscv64.core
new file mode 100644
index 0000000000000..0b159fcab931d
Binary files /dev/null and b/lldb/test/API/functionalities/postmortem/elf-core/linux-riscv64.core 
diff er

diff  --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-riscv64.out b/lldb/test/API/functionalities/postmortem/elf-core/linux-riscv64.out
new file mode 100755
index 0000000000000..ae28aa9ba9aad
Binary files /dev/null and b/lldb/test/API/functionalities/postmortem/elf-core/linux-riscv64.out 
diff er


        


More information about the lldb-commits mailing list