Skip to content

Commit dfabd61

Browse files
authored
[lldb] Support riscv32 ELF corefiles (#115408)
Add support for riscv32 ELF corefiles.
1 parent 050e49a commit dfabd61

11 files changed

+693
-6
lines changed

lldb/source/Plugins/Process/Utility/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ add_lldb_library(lldbPluginProcessUtility
4343
RegisterContextPOSIX_arm64.cpp
4444
RegisterContextPOSIX_loongarch64.cpp
4545
RegisterContextPOSIX_mips64.cpp
46+
RegisterContextPOSIX_riscv32.cpp
4647
RegisterContextPOSIX_powerpc.cpp
4748
RegisterContextPOSIX_ppc64le.cpp
4849
RegisterContextPOSIX_riscv64.cpp
@@ -57,6 +58,7 @@ add_lldb_library(lldbPluginProcessUtility
5758
RegisterInfoPOSIX_arm64.cpp
5859
RegisterInfoPOSIX_loongarch64.cpp
5960
RegisterInfoPOSIX_ppc64le.cpp
61+
RegisterInfoPOSIX_riscv32.cpp
6062
RegisterInfoPOSIX_riscv64.cpp
6163
StopInfoMachException.cpp
6264
ThreadMemory.cpp
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
//===-- RegisterContextPOSIX_riscv32.cpp ------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "RegisterContextPOSIX_riscv32.h"
10+
#include "lldb/Target/Process.h"
11+
#include "lldb/Target/Target.h"
12+
#include "lldb/Target/Thread.h"
13+
#include "lldb/Utility/DataBufferHeap.h"
14+
#include "lldb/Utility/DataExtractor.h"
15+
#include "lldb/Utility/Endian.h"
16+
#include "lldb/Utility/RegisterValue.h"
17+
#include "lldb/Utility/Scalar.h"
18+
#include "llvm/Support/Compiler.h"
19+
20+
using namespace lldb;
21+
using namespace lldb_private;
22+
23+
RegisterContextPOSIX_riscv32::RegisterContextPOSIX_riscv32(
24+
lldb_private::Thread &thread,
25+
std::unique_ptr<RegisterInfoPOSIX_riscv32> register_info)
26+
: lldb_private::RegisterContext(thread, 0),
27+
m_register_info_up(std::move(register_info)) {}
28+
29+
RegisterContextPOSIX_riscv32::~RegisterContextPOSIX_riscv32() = default;
30+
31+
void RegisterContextPOSIX_riscv32::invalidate() {}
32+
33+
void RegisterContextPOSIX_riscv32::InvalidateAllRegisters() {}
34+
35+
size_t RegisterContextPOSIX_riscv32::GetRegisterCount() {
36+
return m_register_info_up->GetRegisterCount();
37+
}
38+
39+
size_t RegisterContextPOSIX_riscv32::GetGPRSize() {
40+
return m_register_info_up->GetGPRSize();
41+
}
42+
43+
unsigned RegisterContextPOSIX_riscv32::GetRegisterSize(unsigned int reg) {
44+
return m_register_info_up->GetRegisterInfo()[reg].byte_size;
45+
}
46+
47+
unsigned RegisterContextPOSIX_riscv32::GetRegisterOffset(unsigned int reg) {
48+
return m_register_info_up->GetRegisterInfo()[reg].byte_offset;
49+
}
50+
51+
const lldb_private::RegisterInfo *
52+
RegisterContextPOSIX_riscv32::GetRegisterInfoAtIndex(size_t reg) {
53+
if (reg < GetRegisterCount())
54+
return &GetRegisterInfo()[reg];
55+
56+
return nullptr;
57+
}
58+
59+
size_t RegisterContextPOSIX_riscv32::GetRegisterSetCount() {
60+
return m_register_info_up->GetRegisterCount();
61+
}
62+
63+
const lldb_private::RegisterSet *
64+
RegisterContextPOSIX_riscv32::GetRegisterSet(size_t set) {
65+
return m_register_info_up->GetRegisterSet(set);
66+
}
67+
68+
const lldb_private::RegisterInfo *
69+
RegisterContextPOSIX_riscv32::GetRegisterInfo() {
70+
return m_register_info_up->GetRegisterInfo();
71+
}
72+
73+
bool RegisterContextPOSIX_riscv32::IsGPR(unsigned int reg) {
74+
return m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
75+
RegisterInfoPOSIX_riscv32::eRegsetMaskDefault;
76+
}
77+
78+
bool RegisterContextPOSIX_riscv32::IsFPR(unsigned int reg) {
79+
return m_register_info_up->GetRegisterSetFromRegisterIndex(reg) ==
80+
RegisterInfoPOSIX_riscv32::eRegsetMaskFP;
81+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//===-- RegisterContextPOSIX_riscv32.h --------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_RISCV32_H
10+
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_RISCV32_H
11+
12+
#include "RegisterInfoInterface.h"
13+
#include "RegisterInfoPOSIX_riscv32.h"
14+
#include "lldb-riscv-register-enums.h"
15+
#include "lldb/Target/RegisterContext.h"
16+
#include "lldb/Utility/Log.h"
17+
18+
class RegisterContextPOSIX_riscv32 : public lldb_private::RegisterContext {
19+
public:
20+
RegisterContextPOSIX_riscv32(
21+
lldb_private::Thread &thread,
22+
std::unique_ptr<RegisterInfoPOSIX_riscv32> register_info);
23+
24+
~RegisterContextPOSIX_riscv32() override;
25+
26+
void invalidate();
27+
28+
void InvalidateAllRegisters() override;
29+
30+
size_t GetRegisterCount() override;
31+
32+
virtual size_t GetGPRSize();
33+
34+
virtual unsigned GetRegisterSize(unsigned reg);
35+
36+
virtual unsigned GetRegisterOffset(unsigned reg);
37+
38+
const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override;
39+
40+
size_t GetRegisterSetCount() override;
41+
42+
const lldb_private::RegisterSet *GetRegisterSet(size_t set) override;
43+
44+
protected:
45+
std::unique_ptr<RegisterInfoPOSIX_riscv32> m_register_info_up;
46+
47+
virtual const lldb_private::RegisterInfo *GetRegisterInfo();
48+
49+
bool IsGPR(unsigned reg);
50+
51+
bool IsFPR(unsigned reg);
52+
53+
size_t GetFPRSize() { return sizeof(RegisterInfoPOSIX_riscv32::FPR); }
54+
55+
uint32_t GetRegNumFCSR() const { return fpr_fcsr_riscv; }
56+
57+
virtual bool ReadGPR() = 0;
58+
virtual bool ReadFPR() = 0;
59+
virtual bool WriteGPR() = 0;
60+
virtual bool WriteFPR() = 0;
61+
};
62+
63+
#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_RISCV32_H
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
//===-- RegisterInfoPOSIX_riscv32.cpp -------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===---------------------------------------------------------------------===//
8+
9+
#include "RegisterInfoPOSIX_riscv32.h"
10+
#include "lldb/Utility/Flags.h"
11+
#include "lldb/lldb-defines.h"
12+
#include "llvm/Support/Compiler.h"
13+
14+
#include <cassert>
15+
#include <stddef.h>
16+
17+
#define GPR_OFFSET(idx) ((idx) * 4 + 0)
18+
#define FPR_OFFSET(idx) ((idx) * 4 + sizeof(RegisterInfoPOSIX_riscv32::GPR))
19+
20+
#define REG_CONTEXT_SIZE \
21+
(sizeof(RegisterInfoPOSIX_riscv32::GPR) + \
22+
sizeof(RegisterInfoPOSIX_riscv32::FPR))
23+
24+
#define DECLARE_REGISTER_INFOS_RISCV32_STRUCT
25+
#include "RegisterInfos_riscv32.h"
26+
#undef DECLARE_REGISTER_INFOS_RISCV32_STRUCT
27+
28+
const lldb_private::RegisterInfo *RegisterInfoPOSIX_riscv32::GetRegisterInfoPtr(
29+
const lldb_private::ArchSpec &target_arch) {
30+
switch (target_arch.GetMachine()) {
31+
case llvm::Triple::riscv32:
32+
return g_register_infos_riscv32_le;
33+
default:
34+
assert(false && "Unhandled target architecture.");
35+
return nullptr;
36+
}
37+
}
38+
39+
uint32_t RegisterInfoPOSIX_riscv32::GetRegisterInfoCount(
40+
const lldb_private::ArchSpec &target_arch) {
41+
switch (target_arch.GetMachine()) {
42+
case llvm::Triple::riscv32:
43+
return static_cast<uint32_t>(sizeof(g_register_infos_riscv32_le) /
44+
sizeof(g_register_infos_riscv32_le[0]));
45+
default:
46+
assert(false && "Unhandled target architecture.");
47+
return 0;
48+
}
49+
}
50+
51+
// Number of register sets provided by this context.
52+
enum {
53+
k_num_gpr_registers = gpr_last_riscv - gpr_first_riscv + 1,
54+
k_num_fpr_registers = fpr_last_riscv - fpr_first_riscv + 1,
55+
k_num_register_sets = 2
56+
};
57+
58+
// RISC-V32 general purpose registers.
59+
static const uint32_t g_gpr_regnums_riscv32[] = {
60+
gpr_pc_riscv, gpr_ra_riscv, gpr_sp_riscv, gpr_x3_riscv,
61+
gpr_x4_riscv, gpr_x5_riscv, gpr_x6_riscv, gpr_x7_riscv,
62+
gpr_fp_riscv, gpr_x9_riscv, gpr_x10_riscv, gpr_x11_riscv,
63+
gpr_x12_riscv, gpr_x13_riscv, gpr_x14_riscv, gpr_x15_riscv,
64+
gpr_x16_riscv, gpr_x17_riscv, gpr_x18_riscv, gpr_x19_riscv,
65+
gpr_x20_riscv, gpr_x21_riscv, gpr_x22_riscv, gpr_x23_riscv,
66+
gpr_x24_riscv, gpr_x25_riscv, gpr_x26_riscv, gpr_x27_riscv,
67+
gpr_x28_riscv, gpr_x29_riscv, gpr_x30_riscv, gpr_x31_riscv,
68+
gpr_x0_riscv, LLDB_INVALID_REGNUM};
69+
70+
static_assert(((sizeof g_gpr_regnums_riscv32 /
71+
sizeof g_gpr_regnums_riscv32[0]) -
72+
1) == k_num_gpr_registers,
73+
"g_gpr_regnums_riscv32 has wrong number of register infos");
74+
75+
// RISC-V32 floating point registers.
76+
static const uint32_t g_fpr_regnums_riscv32[] = {
77+
fpr_f0_riscv, fpr_f1_riscv, fpr_f2_riscv, fpr_f3_riscv,
78+
fpr_f4_riscv, fpr_f5_riscv, fpr_f6_riscv, fpr_f7_riscv,
79+
fpr_f8_riscv, fpr_f9_riscv, fpr_f10_riscv, fpr_f11_riscv,
80+
fpr_f12_riscv, fpr_f13_riscv, fpr_f14_riscv, fpr_f15_riscv,
81+
fpr_f16_riscv, fpr_f17_riscv, fpr_f18_riscv, fpr_f19_riscv,
82+
fpr_f20_riscv, fpr_f21_riscv, fpr_f22_riscv, fpr_f23_riscv,
83+
fpr_f24_riscv, fpr_f25_riscv, fpr_f26_riscv, fpr_f27_riscv,
84+
fpr_f28_riscv, fpr_f29_riscv, fpr_f30_riscv, fpr_f31_riscv,
85+
fpr_fcsr_riscv, LLDB_INVALID_REGNUM};
86+
87+
static_assert(((sizeof g_fpr_regnums_riscv32 /
88+
sizeof g_fpr_regnums_riscv32[0]) -
89+
1) == k_num_fpr_registers,
90+
"g_fpr_regnums_riscv32 has wrong number of register infos");
91+
92+
// Register sets for RISC-V32.
93+
static const lldb_private::RegisterSet g_reg_sets_riscv32[k_num_register_sets] =
94+
{{"General Purpose Registers", "gpr", k_num_gpr_registers,
95+
g_gpr_regnums_riscv32},
96+
{"Floating Point Registers", "fpr", k_num_fpr_registers,
97+
g_fpr_regnums_riscv32}};
98+
99+
RegisterInfoPOSIX_riscv32::RegisterInfoPOSIX_riscv32(
100+
const lldb_private::ArchSpec &target_arch, lldb_private::Flags opt_regsets)
101+
: lldb_private::RegisterInfoAndSetInterface(target_arch),
102+
m_register_info_p(GetRegisterInfoPtr(target_arch)),
103+
m_register_info_count(GetRegisterInfoCount(target_arch)),
104+
m_opt_regsets(opt_regsets) {}
105+
106+
uint32_t RegisterInfoPOSIX_riscv32::GetRegisterCount() const {
107+
return m_register_info_count;
108+
}
109+
110+
size_t RegisterInfoPOSIX_riscv32::GetGPRSize() const {
111+
return sizeof(struct RegisterInfoPOSIX_riscv32::GPR);
112+
}
113+
114+
size_t RegisterInfoPOSIX_riscv32::GetFPRSize() const {
115+
return sizeof(struct RegisterInfoPOSIX_riscv32::FPR);
116+
}
117+
118+
const lldb_private::RegisterInfo *
119+
RegisterInfoPOSIX_riscv32::GetRegisterInfo() const {
120+
return m_register_info_p;
121+
}
122+
123+
size_t RegisterInfoPOSIX_riscv32::GetRegisterSetCount() const {
124+
return k_num_register_sets;
125+
}
126+
127+
size_t RegisterInfoPOSIX_riscv32::GetRegisterSetFromRegisterIndex(
128+
uint32_t reg_index) const {
129+
// coverity[unsigned_compare]
130+
if (reg_index >= gpr_first_riscv && reg_index <= gpr_last_riscv)
131+
return eRegsetMaskDefault;
132+
if (reg_index >= fpr_first_riscv && reg_index <= fpr_last_riscv)
133+
return eRegsetMaskFP;
134+
return LLDB_INVALID_REGNUM;
135+
}
136+
137+
const lldb_private::RegisterSet *
138+
RegisterInfoPOSIX_riscv32::GetRegisterSet(size_t set_index) const {
139+
if (set_index < GetRegisterSetCount())
140+
return &g_reg_sets_riscv32[set_index];
141+
return nullptr;
142+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
//===-- RegisterInfoPOSIX_riscv32.h -----------------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_RISCV32_H
10+
#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_RISCV32_H
11+
12+
#include "RegisterInfoAndSetInterface.h"
13+
#include "lldb/Target/RegisterContext.h"
14+
#include "lldb/Utility/Flags.h"
15+
#include "lldb/lldb-private.h"
16+
17+
#include <map>
18+
19+
class RegisterInfoPOSIX_riscv32
20+
: public lldb_private::RegisterInfoAndSetInterface {
21+
public:
22+
static const lldb_private::RegisterInfo *
23+
GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch);
24+
static uint32_t
25+
GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch);
26+
27+
public:
28+
// RISC-V32 register set mask value
29+
enum {
30+
eRegsetMaskDefault = 0,
31+
eRegsetMaskFP = 1,
32+
eRegsetMaskAll = -1,
33+
};
34+
35+
struct GPR {
36+
// gpr[0] is pc, not x0, which is the zero register.
37+
uint32_t gpr[32];
38+
};
39+
40+
struct FPR {
41+
uint32_t fpr[32];
42+
uint32_t fcsr;
43+
};
44+
45+
RegisterInfoPOSIX_riscv32(const lldb_private::ArchSpec &target_arch,
46+
lldb_private::Flags flags);
47+
48+
size_t GetGPRSize() const override;
49+
50+
size_t GetFPRSize() const override;
51+
52+
const lldb_private::RegisterInfo *GetRegisterInfo() const override;
53+
54+
uint32_t GetRegisterCount() const override;
55+
56+
const lldb_private::RegisterSet *
57+
GetRegisterSet(size_t reg_set) const override;
58+
59+
size_t GetRegisterSetCount() const override;
60+
61+
size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override;
62+
63+
bool IsFPPresent() const { return m_opt_regsets.AnySet(eRegsetMaskFP); }
64+
65+
private:
66+
const lldb_private::RegisterInfo *m_register_info_p;
67+
uint32_t m_register_info_count;
68+
lldb_private::Flags m_opt_regsets;
69+
};
70+
71+
#endif

lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_riscv64.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66
//
77
//===---------------------------------------------------------------------===//
88

9-
#include <cassert>
10-
#include <lldb/Utility/Flags.h>
11-
#include <stddef.h>
12-
9+
#include "RegisterInfoPOSIX_riscv64.h"
10+
#include "lldb/Utility/Flags.h"
1311
#include "lldb/lldb-defines.h"
1412
#include "llvm/Support/Compiler.h"
1513

16-
#include "RegisterInfoPOSIX_riscv64.h"
14+
#include <cassert>
15+
#include <stddef.h>
1716

1817
#define GPR_OFFSET(idx) ((idx)*8 + 0)
1918
#define FPR_OFFSET(idx) ((idx)*8 + sizeof(RegisterInfoPOSIX_riscv64::GPR))

0 commit comments

Comments
 (0)