-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[lldb] Support riscv32 ELF corefiles #115408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I'm in an awkward position where I'm not able to share the riscv32 core files I've been testing this against. @ita-sc & @AlexeyMerzlyakov, I know you two have worked on riscv64, is there any chance you could help me generate a riscv32 core file I can use to write a test for this? |
@llvm/pr-subscribers-lldb Author: Jonas Devlieghere (JDevlieghere) ChangesPatch is 30.04 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/115408.diff 10 Files Affected:
diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt
index 308ea29e31ad7..5ffd2d7114cc9 100644
--- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt
+++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt
@@ -39,6 +39,7 @@ add_lldb_library(lldbPluginProcessUtility
RegisterContextPOSIX_arm64.cpp
RegisterContextPOSIX_loongarch64.cpp
RegisterContextPOSIX_mips64.cpp
+ RegisterContextPOSIX_riscv32.cpp
RegisterContextPOSIX_powerpc.cpp
RegisterContextPOSIX_ppc64le.cpp
RegisterContextPOSIX_riscv64.cpp
@@ -53,6 +54,7 @@ add_lldb_library(lldbPluginProcessUtility
RegisterInfoPOSIX_arm64.cpp
RegisterInfoPOSIX_loongarch64.cpp
RegisterInfoPOSIX_ppc64le.cpp
+ RegisterInfoPOSIX_riscv32.cpp
RegisterInfoPOSIX_riscv64.cpp
StopInfoMachException.cpp
ThreadMemory.cpp
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv32.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv32.cpp
new file mode 100644
index 0000000000000..64064f86cea04
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv32.cpp
@@ -0,0 +1,81 @@
+//===-- RegisterContextPOSIX_riscv32.cpp ------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "RegisterContextPOSIX_riscv32.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/DataBufferHeap.h"
+#include "lldb/Utility/DataExtractor.h"
+#include "lldb/Utility/Endian.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Scalar.h"
+#include "llvm/Support/Compiler.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+RegisterContextPOSIX_riscv32::RegisterContextPOSIX_riscv32(
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_riscv32> register_info)
+ : lldb_private::RegisterContext(thread, 0),
+ m_register_info_up(std::move(register_info)) {}
+
+RegisterContextPOSIX_riscv32::~RegisterContextPOSIX_riscv32() = default;
+
+void RegisterContextPOSIX_riscv32::invalidate() {}
+
+void RegisterContextPOSIX_riscv32::InvalidateAllRegisters() {}
+
+size_t RegisterContextPOSIX_riscv32::GetRegisterCount() {
+ return m_register_info_up->GetRegisterCount();
+}
+
+size_t RegisterContextPOSIX_riscv32::GetGPRSize() {
+ return m_register_info_up->GetGPRSize();
+}
+
+unsigned RegisterContextPOSIX_riscv32::GetRegisterSize(unsigned int reg) {
+ return m_register_info_up->GetRegisterInfo()[reg].byte_size;
+}
+
+unsigned RegisterContextPOSIX_riscv32::GetRegisterOffset(unsigned int reg) {
+ return m_register_info_up->GetRegisterInfo()[reg].byte_offset;
+}
+
+const lldb_private::RegisterInfo *
+RegisterContextPOSIX_riscv32::GetRegisterInfoAtIndex(size_t reg) {
+ if (reg < GetRegisterCount())
+ return &GetRegisterInfo()[reg];
+
+ return nullptr;
+}
+
+size_t RegisterContextPOSIX_riscv32::GetRegisterSetCount() {
+ return m_register_info_up->GetRegisterCount();
+}
+
+const lldb_private::RegisterSet *
+RegisterContextPOSIX_riscv32::GetRegisterSet(size_t set) {
+ return m_register_info_up->GetRegisterSet(set);
+}
+
+const lldb_private::RegisterInfo *
+RegisterContextPOSIX_riscv32::GetRegisterInfo() {
+ return m_register_info_up->GetRegisterInfo();
+}
+
+bool RegisterContextPOSIX_riscv32::IsGPR(unsigned int reg) {
+ return m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
+ RegisterInfoPOSIX_riscv32::eRegsetMaskDefault;
+}
+
+bool RegisterContextPOSIX_riscv32::IsFPR(unsigned int reg) {
+ return m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
+ RegisterInfoPOSIX_riscv32::eRegsetMaskFP;
+}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv32.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv32.h
new file mode 100644
index 0000000000000..0c25ce11f5754
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_riscv32.h
@@ -0,0 +1,63 @@
+//===-- RegisterContextPOSIX_riscv32.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_UTILITY_REGISTERCONTEXTPOSIX_RISCV32_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_RISCV32_H
+
+#include "RegisterInfoInterface.h"
+#include "RegisterInfoPOSIX_riscv32.h"
+#include "lldb-riscv-register-enums.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Utility/Log.h"
+
+class RegisterContextPOSIX_riscv32 : public lldb_private::RegisterContext {
+public:
+ RegisterContextPOSIX_riscv32(
+ lldb_private::Thread &thread,
+ std::unique_ptr<RegisterInfoPOSIX_riscv32> register_info);
+
+ ~RegisterContextPOSIX_riscv32() override;
+
+ void invalidate();
+
+ void InvalidateAllRegisters() override;
+
+ size_t GetRegisterCount() override;
+
+ virtual size_t GetGPRSize();
+
+ virtual unsigned GetRegisterSize(unsigned reg);
+
+ virtual unsigned GetRegisterOffset(unsigned reg);
+
+ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
+
+ size_t GetRegisterSetCount() override;
+
+ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
+
+protected:
+ std::unique_ptr<RegisterInfoPOSIX_riscv32> m_register_info_up;
+
+ virtual const lldb_private::RegisterInfo *GetRegisterInfo();
+
+ bool IsGPR(unsigned reg);
+
+ bool IsFPR(unsigned reg);
+
+ size_t GetFPRSize() { return sizeof(RegisterInfoPOSIX_riscv32::FPR); }
+
+ uint32_t GetRegNumFCSR() const { return fpr_fcsr_riscv; }
+
+ virtual bool ReadGPR() = 0;
+ virtual bool ReadFPR() = 0;
+ virtual bool WriteGPR() = 0;
+ virtual bool WriteFPR() = 0;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_RISCV32_H
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv32.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv32.cpp
new file mode 100644
index 0000000000000..e213b4a4a1820
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv32.cpp
@@ -0,0 +1,142 @@
+//===-- RegisterInfoPOSIX_riscv32.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 "RegisterInfoPOSIX_riscv32.h"
+#include "lldb/Utility/Flags.h"
+#include "lldb/lldb-defines.h"
+#include "llvm/Support/Compiler.h"
+
+#include <cassert>
+#include <stddef.h>
+
+#define GPR_OFFSET(idx) ((idx) * 4 + 0)
+#define FPR_OFFSET(idx) ((idx) * 4 + sizeof(RegisterInfoPOSIX_riscv32::GPR))
+
+#define REG_CONTEXT_SIZE \
+ (sizeof(RegisterInfoPOSIX_riscv32::GPR) + \
+ sizeof(RegisterInfoPOSIX_riscv32::FPR))
+
+#define DECLARE_REGISTER_INFOS_RISCV32_STRUCT
+#include "RegisterInfos_riscv32.h"
+#undef DECLARE_REGISTER_INFOS_RISCV32_STRUCT
+
+const lldb_private::RegisterInfo *RegisterInfoPOSIX_riscv32::GetRegisterInfoPtr(
+ const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::riscv32:
+ return g_register_infos_riscv32_le;
+ default:
+ assert(false && "Unhandled target architecture.");
+ return nullptr;
+ }
+}
+
+uint32_t RegisterInfoPOSIX_riscv32::GetRegisterInfoCount(
+ const lldb_private::ArchSpec &target_arch) {
+ switch (target_arch.GetMachine()) {
+ case llvm::Triple::riscv32:
+ return static_cast<uint32_t>(sizeof(g_register_infos_riscv32_le) /
+ sizeof(g_register_infos_riscv32_le[0]));
+ default:
+ assert(false && "Unhandled target architecture.");
+ return 0;
+ }
+}
+
+// Number of register sets provided by this context.
+enum {
+ k_num_gpr_registers = gpr_last_riscv - gpr_first_riscv + 1,
+ k_num_fpr_registers = fpr_last_riscv - fpr_first_riscv + 1,
+ k_num_register_sets = 2
+};
+
+// RISC-V32 general purpose registers.
+static const uint32_t g_gpr_regnums_riscv32[] = {
+ gpr_pc_riscv, gpr_ra_riscv, gpr_sp_riscv, gpr_x3_riscv,
+ gpr_x4_riscv, gpr_x5_riscv, gpr_x6_riscv, gpr_x7_riscv,
+ gpr_fp_riscv, gpr_x9_riscv, gpr_x10_riscv, gpr_x11_riscv,
+ gpr_x12_riscv, gpr_x13_riscv, gpr_x14_riscv, gpr_x15_riscv,
+ gpr_x16_riscv, gpr_x17_riscv, gpr_x18_riscv, gpr_x19_riscv,
+ gpr_x20_riscv, gpr_x21_riscv, gpr_x22_riscv, gpr_x23_riscv,
+ gpr_x24_riscv, gpr_x25_riscv, gpr_x26_riscv, gpr_x27_riscv,
+ gpr_x28_riscv, gpr_x29_riscv, gpr_x30_riscv, gpr_x31_riscv,
+ gpr_x0_riscv, LLDB_INVALID_REGNUM};
+
+static_assert(((sizeof g_gpr_regnums_riscv32 /
+ sizeof g_gpr_regnums_riscv32[0]) -
+ 1) == k_num_gpr_registers,
+ "g_gpr_regnums_riscv32 has wrong number of register infos");
+
+// RISC-V32 floating point registers.
+static const uint32_t g_fpr_regnums_riscv32[] = {
+ fpr_f0_riscv, fpr_f1_riscv, fpr_f2_riscv, fpr_f3_riscv,
+ fpr_f4_riscv, fpr_f5_riscv, fpr_f6_riscv, fpr_f7_riscv,
+ fpr_f8_riscv, fpr_f9_riscv, fpr_f10_riscv, fpr_f11_riscv,
+ fpr_f12_riscv, fpr_f13_riscv, fpr_f14_riscv, fpr_f15_riscv,
+ fpr_f16_riscv, fpr_f17_riscv, fpr_f18_riscv, fpr_f19_riscv,
+ fpr_f20_riscv, fpr_f21_riscv, fpr_f22_riscv, fpr_f23_riscv,
+ fpr_f24_riscv, fpr_f25_riscv, fpr_f26_riscv, fpr_f27_riscv,
+ fpr_f28_riscv, fpr_f29_riscv, fpr_f30_riscv, fpr_f31_riscv,
+ fpr_fcsr_riscv, LLDB_INVALID_REGNUM};
+
+static_assert(((sizeof g_fpr_regnums_riscv32 /
+ sizeof g_fpr_regnums_riscv32[0]) -
+ 1) == k_num_fpr_registers,
+ "g_fpr_regnums_riscv32 has wrong number of register infos");
+
+// Register sets for RISC-V32.
+static const lldb_private::RegisterSet g_reg_sets_riscv32[k_num_register_sets] =
+ {{"General Purpose Registers", "gpr", k_num_gpr_registers,
+ g_gpr_regnums_riscv32},
+ {"Floating Point Registers", "fpr", k_num_fpr_registers,
+ g_fpr_regnums_riscv32}};
+
+RegisterInfoPOSIX_riscv32::RegisterInfoPOSIX_riscv32(
+ const lldb_private::ArchSpec &target_arch, lldb_private::Flags opt_regsets)
+ : lldb_private::RegisterInfoAndSetInterface(target_arch),
+ m_register_info_p(GetRegisterInfoPtr(target_arch)),
+ m_register_info_count(GetRegisterInfoCount(target_arch)),
+ m_opt_regsets(opt_regsets) {}
+
+uint32_t RegisterInfoPOSIX_riscv32::GetRegisterCount() const {
+ return m_register_info_count;
+}
+
+size_t RegisterInfoPOSIX_riscv32::GetGPRSize() const {
+ return sizeof(struct RegisterInfoPOSIX_riscv32::GPR);
+}
+
+size_t RegisterInfoPOSIX_riscv32::GetFPRSize() const {
+ return sizeof(struct RegisterInfoPOSIX_riscv32::FPR);
+}
+
+const lldb_private::RegisterInfo *
+RegisterInfoPOSIX_riscv32::GetRegisterInfo() const {
+ return m_register_info_p;
+}
+
+size_t RegisterInfoPOSIX_riscv32::GetRegisterSetCount() const {
+ return k_num_register_sets;
+}
+
+size_t RegisterInfoPOSIX_riscv32::GetRegisterSetFromRegisterIndex(
+ uint32_t reg_index) const {
+ // coverity[unsigned_compare]
+ if (reg_index >= gpr_first_riscv && reg_index <= gpr_last_riscv)
+ return eRegsetMaskDefault;
+ if (reg_index >= fpr_first_riscv && reg_index <= fpr_last_riscv)
+ return eRegsetMaskFP;
+ return LLDB_INVALID_REGNUM;
+}
+
+const lldb_private::RegisterSet *
+RegisterInfoPOSIX_riscv32::GetRegisterSet(size_t set_index) const {
+ if (set_index < GetRegisterSetCount())
+ return &g_reg_sets_riscv32[set_index];
+ return nullptr;
+}
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv32.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv32.h
new file mode 100644
index 0000000000000..f8d85f9e72893
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv32.h
@@ -0,0 +1,76 @@
+//===-- RegisterInfoPOSIX_riscv32.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_UTILITY_REGISTERINFOPOSIX_RISCV32_H
+#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_RISCV32_H
+
+#include "RegisterInfoAndSetInterface.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Utility/Flags.h"
+#include "lldb/lldb-private.h"
+
+#include <map>
+
+class RegisterInfoPOSIX_riscv32
+ : public lldb_private::RegisterInfoAndSetInterface {
+public:
+ static const lldb_private::RegisterInfo *
+ GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch);
+ static uint32_t
+ GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch);
+
+public:
+ // RISC-V32 register set mask value
+ enum {
+ eRegsetMaskDefault = 0,
+ eRegsetMaskFP = 1,
+ eRegsetMaskAll = -1,
+ };
+
+ struct GPR {
+ // note: gpr[0] is pc, not x0
+ uint32_t gpr[32];
+ };
+
+ struct FPR {
+ uint32_t fpr[32];
+ uint32_t fcsr;
+ };
+
+ struct VPR {
+ // The size should be VLEN*32 in bits, but we don't have VLEN here.
+ void *vpr;
+ };
+
+ RegisterInfoPOSIX_riscv32(const lldb_private::ArchSpec &target_arch,
+ lldb_private::Flags flags);
+
+ size_t GetGPRSize() const override;
+
+ size_t GetFPRSize() const override;
+
+ const lldb_private::RegisterInfo *GetRegisterInfo() const override;
+
+ uint32_t GetRegisterCount() const override;
+
+ const lldb_private::RegisterSet *
+ GetRegisterSet(size_t reg_set) const override;
+
+ size_t GetRegisterSetCount() const override;
+
+ size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
+
+ bool IsFPPresent() const { return m_opt_regsets.AnySet(eRegsetMaskFP); }
+
+private:
+ const lldb_private::RegisterInfo *m_register_info_p;
+ uint32_t m_register_info_count;
+ lldb_private::Flags m_opt_regsets;
+};
+
+#endif
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.cpp
index 4a3737795848e..a0be54fc76cd5 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.cpp
@@ -6,14 +6,13 @@
//
//===---------------------------------------------------------------------===//
-#include <cassert>
-#include <lldb/Utility/Flags.h>
-#include <stddef.h>
-
+#include "RegisterInfoPOSIX_riscv64.h"
+#include "lldb/Utility/Flags.h"
#include "lldb/lldb-defines.h"
#include "llvm/Support/Compiler.h"
-#include "RegisterInfoPOSIX_riscv64.h"
+#include <cassert>
+#include <stddef.h>
#define GPR_OFFSET(idx) ((idx)*8 + 0)
#define FPR_OFFSET(idx) ((idx)*8 + sizeof(RegisterInfoPOSIX_riscv64::GPR))
diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_riscv32.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_riscv32.h
new file mode 100644
index 0000000000000..ab6fec829bbce
--- /dev/null
+++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_riscv32.h
@@ -0,0 +1,185 @@
+//===-- RegisterInfos_riscv32.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
+//
+//===----------------------------------------------------------------------===//
+
+#ifdef DECLARE_REGISTER_INFOS_RISCV32_STRUCT
+
+#include "Utility/RISCV_DWARF_Registers.h"
+#include "lldb-riscv-register-enums.h"
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-private.h"
+
+#include <stddef.h>
+
+#ifndef GPR_OFFSET
+#error GPR_OFFSET must be defined before including this header file
+#endif
+
+#ifndef FPR_OFFSET
+#error FPR_OFFSET must be defined before including this header file
+#endif
+
+using namespace riscv_dwarf;
+
+// clang-format off
+
+// I suppose EHFrame and DWARF are the same.
+#define KIND_HELPER(reg, generic_kind) \
+ { \
+ riscv_dwarf::dwarf_##reg, riscv_dwarf::dwarf_##reg, generic_kind, \
+ LLDB_INVALID_REGNUM, reg##_riscv \
+ }
+
+// Generates register kinds array for vector registers
+#define GPR32_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind)
+
+// FPR register kinds array for vector registers
+#define FPR32_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind)
+
+// VPR register kinds array for vector registers
+#define VPR_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind)
+
+// Defines a 32-bit general purpose register
+#define DEFINE_GPR32(reg, generic_kind) DEFINE_GPR32_ALT(reg, reg, generic_kind)
+
+// Defines a 32-bit general purpose register
+#define DEFINE_GPR32_ALT(reg, alt, generic_kind) \
+ { \
+ #reg, #alt, 4, GPR_OFFSET(gpr_##reg##_riscv - gpr_first_riscv), \
+ lldb::eEncodingUint, lldb::eFormatHex, \
+ GPR32_KIND(gpr_##reg, generic_kind), nullptr, nullptr, nullptr, \
+ }
+
+#define DEFINE_FPR32(reg, generic_kind) DEFINE_FPR32_ALT(reg, reg, generic_kind)
+
+#define DEFINE_FPR32_ALT(reg, alt, generic_kind) DEFINE_FPR_ALT(reg, alt, 4, generic_kind)
+
+#define DEFINE_FPR_ALT(reg, alt, size, generic_kind) \
+ { \
+ #reg, #alt, size, FPR_OFFSET(fpr_##reg##_riscv - fpr_first_riscv), \
+ lldb::eEncodingUint, lldb::eFormatHex, \
+ FPR32_KIND(fpr_##reg, generic_kind), nullptr, nullptr, nullptr, \
+ }
+
+#define DEFINE_VPR(reg, generic_kind) DEFINE_VPR_ALT(reg, reg, generic_kind)
+
+// Defines a scalable vector register, with default size 128 bits
+// The byte offset 0 is a placeholder, which should be corrected at runtime.
+#define DEFINE_VPR_ALT(reg, alt, generic_kind) \
+ { \
+ #reg, #alt, 16, 0, lldb::eEncodingVector, lldb::eFormatVectorOfUInt8, \
+ VPR_KIND(vpr_##reg, generic_kind), nullptr, nullptr, nullptr \
+ }
+
+// clang-format on
+
+static lldb_private::RegisterInfo g_register_infos_riscv32_le[] = {
+ // DEFINE_GPR32(name, GENERIC KIND)
+ DEFINE_GPR32(pc, LLDB_REGNUM_GENERIC_PC),
+ DEFINE_GPR32_ALT(ra, x1, LLDB_REGNUM_GENERIC_RA),
+ DEFINE_GPR32_ALT(sp, x2, LLDB_REGNUM_GENERIC_SP),
+ DEFINE_GPR32_ALT(gp, x3, LLDB_INVALID_REGNUM),
+ DEFINE_GPR32_ALT(tp, x4, LLDB_INVALID_REGNUM),
+ DEFINE_GPR32_ALT(t0, x5, LLDB_INVALID_REGNUM),
+ DEFINE_GPR32_ALT(t1, x6, LLDB_INVALID_REGNUM),
+ DEFINE_GPR32_ALT(t2, x7, LLDB_INVALID_REGNUM),
+ DEFINE_GPR32_ALT(fp, x8, LLDB_REGNUM_GENERIC_FP),
+ DEFINE_GPR32_ALT(s1, x9, LLDB_INVALID_REGNUM),
+ DEFINE_GPR32_ALT(a0, x10, LLDB_REGNUM_GENERIC_ARG1),
+ DEFINE_GPR32_ALT(a1, x11, LLDB_REGNUM_GENERIC_ARG2),
+ DEFINE_GPR32_ALT(a2, x12, LLDB_REGNUM_GENERIC_ARG3),
+ DEFINE_GPR32_ALT(a3, x13, LLDB_REGNUM_GENERIC_ARG4),
+ DEFINE_GPR32_ALT(a4, x14, LLDB_REGNUM_GENERIC_ARG5),
+ DEFINE_GPR32_ALT(a5, x15, LLDB_REGNUM_GENERIC_ARG6),
+ DEFINE_GPR32_ALT(a6, x16, LLDB_REGNUM_GENERIC_ARG7),
+ DEFINE_GPR32_ALT(a7, x17, LLDB_REGNUM_GENERIC_ARG8),
+ DEFINE_GPR32_ALT(s2, x18, LLDB_INVALID_REGNUM),
+ DEFINE_GPR32_ALT(s3, x19, LLDB_INVALID_REGNUM),
+ DEFINE_GPR32_...
[truncated]
|
uint32_t fcsr; | ||
}; | ||
|
||
struct VPR { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see why we're including data store for the VPR vector register, or adding the register definitions below. There are no read or write accesses to these, and it'd prob be less confusing if they weren't listed at all.
It may be a "if we had VPR register data in a corefile, we'd store it here" and the read/write methods are TBD, that's fine in that case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ISTR the 64-bit has some mentions of the vector registers but we don't actually support them yet.
But I agree, leave them out until they are supposed to be useable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me, straightforward corefile impl of these registers.
DEFINE_GPR32_ALT(t4, x29, LLDB_INVALID_REGNUM), | ||
DEFINE_GPR32_ALT(t5, x30, LLDB_INVALID_REGNUM), | ||
DEFINE_GPR32_ALT(t6, x31, LLDB_INVALID_REGNUM), | ||
DEFINE_GPR32_ALT(zero, x0, LLDB_INVALID_REGNUM), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand defining x0/zero here, the GPR object doesn't have any place for the $x0 value to be stored (fine - it's zero). It seems like the ReadRegister
method needs to explicitly check to see if x0 is being read, and return a UInt32 0 value for that reg. I'm pretty sure this code as written will access 4 bytes past the end of the GPR object when someone asks for the value of $x0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this scheme was copied somewhat from RegisterInfoPOSIX_riscv64
and RegisterInfos_riscv64.h
and I have to wonder if that class shares the same problem with $x0. The GPR object is 32 64-bit entries, and $zero / $x0 has an offset past the end of the struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jasonmolenda I had the same thought when we were internally implementing 32 bit core dumps, and realized that the zero register can be another "register" that the dumper uses to communicate interesting data. I know our internal team that wanted this plans to use it for something (I don't know what).
lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv32.h
Outdated
Show resolved
Hide resolved
uint32_t fcsr; | ||
}; | ||
|
||
struct VPR { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ISTR the 64-bit has some mentions of the vector registers but we don't actually support them yet.
But I agree, leave them out until they are supposed to be useable.
@JDevlieghere, to get coredump file I've used make-core.sh script on the target H/W. Generated file should be minimal as possible. On of the way to do this - is to restrict the the number of unnecessary mappings written to the corefile by setting Unfortunately, I have only RISC-V 64 target (with Kernel & rootfs) in my access, so I am not sure whether I could easily generate core-file to you for RISC-V 32 target. |
You could adapt commands from https://github.com/llvm/llvm-project/tree/main/lldb/scripts/lldb-test-qemu, if you have an existing Ubuntu system of some other architecture. |
Support riscv32 ELF corefiles.
I see the latest update includes the necessary changes to ThreadElfCore, that looks good. I'm still curious what this code does when reading x0. The RegisterContext GPR struct defines 32 elements, pc + x1-x31, and the offset of x0 would be the 33rd element. But instead of using that GPR struct, this PR points into the corefile byte range where the GPRs are stored -- I'm assuming the elf file stores pc in the 0th position just like the RegisterContext does. Is the GPR register file in an rv32 corefile 32 elements long or 33? Are we reading past the end of the 32-element GPR registers when we read x0 and it happens to just be value 0, or maybe it's undefined and no one really read x0 so they don't notice? I still wonder about having |
@jasonmolenda Yes, my understanding is that the GPRs are 338=264 bytes for riscv64 and 334=132 bytes for riscv32. The FPR start at offset 132. |
|
Intentional insofar that I cannot share the core files I tested this against, and that I don't know/have a way to generate one that I can check in.
I can add a release note 👍 |
@asb might have a RISC-V Linux system handy to generate a core file from.
If @asb can generate them I think @JDevlieghere can update the tests without needing access to the system itself. |
Add support for riscv32 ELF corefiles.
Add support for riscv32 ELF corefiles.
Add support for riscv32 ELF corefiles.