Skip to content

Commit 911a6f2

Browse files
authored
[lldb][LoongArch64] Add support for LoongArch64 in elf-core for lldb (#112296)
When using the lldb command 'target create --core' on the LoongArch64 architecture, this part of the code is required.
1 parent 6360652 commit 911a6f2

File tree

8 files changed

+262
-1
lines changed

8 files changed

+262
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ RegisterContextPOSIX_loongarch64::GetRegisterInfoAtIndex(size_t reg) {
5858
}
5959

6060
size_t RegisterContextPOSIX_loongarch64::GetRegisterSetCount() {
61-
return m_register_info_up->GetRegisterCount();
61+
return m_register_info_up->GetRegisterSetCount();
6262
}
6363

6464
const lldb_private::RegisterSet *

lldb/source/Plugins/Process/elf-core/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ add_lldb_library(lldbPluginProcessElfCore PLUGIN
1010
RegisterContextPOSIXCore_s390x.cpp
1111
RegisterContextPOSIXCore_x86_64.cpp
1212
RegisterContextPOSIXCore_riscv64.cpp
13+
RegisterContextPOSIXCore_loongarch64.cpp
1314
RegisterUtilities.cpp
1415

1516
LINK_LIBS
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//===-- RegisterContextPOSIXCore_loongarch64.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 "RegisterContextPOSIXCore_loongarch64.h"
10+
11+
#include "lldb/Utility/DataBufferHeap.h"
12+
13+
using namespace lldb_private;
14+
15+
std::unique_ptr<RegisterContextCorePOSIX_loongarch64>
16+
RegisterContextCorePOSIX_loongarch64::Create(Thread &thread,
17+
const ArchSpec &arch,
18+
const DataExtractor &gpregset,
19+
llvm::ArrayRef<CoreNote> notes) {
20+
return std::unique_ptr<RegisterContextCorePOSIX_loongarch64>(
21+
new RegisterContextCorePOSIX_loongarch64(
22+
thread,
23+
std::make_unique<RegisterInfoPOSIX_loongarch64>(arch, Flags()),
24+
gpregset, notes));
25+
}
26+
27+
RegisterContextCorePOSIX_loongarch64::RegisterContextCorePOSIX_loongarch64(
28+
Thread &thread,
29+
std::unique_ptr<RegisterInfoPOSIX_loongarch64> register_info,
30+
const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes)
31+
: RegisterContextPOSIX_loongarch64(thread, std::move(register_info)) {
32+
33+
m_gpr.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
34+
gpregset.GetByteSize()));
35+
m_gpr.SetByteOrder(gpregset.GetByteOrder());
36+
37+
ArchSpec arch = m_register_info_up->GetTargetArchitecture();
38+
DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc);
39+
m_fpr.SetData(std::make_shared<DataBufferHeap>(fpregset.GetDataStart(),
40+
fpregset.GetByteSize()));
41+
m_fpr.SetByteOrder(fpregset.GetByteOrder());
42+
}
43+
44+
RegisterContextCorePOSIX_loongarch64::~RegisterContextCorePOSIX_loongarch64() =
45+
default;
46+
47+
bool RegisterContextCorePOSIX_loongarch64::ReadGPR() { return true; }
48+
49+
bool RegisterContextCorePOSIX_loongarch64::ReadFPR() { return true; }
50+
51+
bool RegisterContextCorePOSIX_loongarch64::WriteGPR() {
52+
assert(false && "Writing registers is not allowed for core dumps");
53+
return false;
54+
}
55+
56+
bool RegisterContextCorePOSIX_loongarch64::WriteFPR() {
57+
assert(false && "Writing registers is not allowed for core dumps");
58+
return false;
59+
}
60+
61+
bool RegisterContextCorePOSIX_loongarch64::ReadRegister(
62+
const RegisterInfo *reg_info, RegisterValue &value) {
63+
const uint8_t *src = nullptr;
64+
lldb::offset_t offset = reg_info->byte_offset;
65+
66+
if (IsGPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
67+
src = m_gpr.GetDataStart();
68+
} else if (IsFPR(reg_info->kinds[lldb::eRegisterKindLLDB])) {
69+
src = m_fpr.GetDataStart();
70+
offset -= GetGPRSize();
71+
} else {
72+
return false;
73+
}
74+
75+
Status error;
76+
value.SetFromMemoryData(*reg_info, src + offset, reg_info->byte_size,
77+
lldb::eByteOrderLittle, error);
78+
return error.Success();
79+
}
80+
81+
bool RegisterContextCorePOSIX_loongarch64::WriteRegister(
82+
const RegisterInfo *reg_info, const RegisterValue &value) {
83+
return false;
84+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
//===-- RegisterContextPOSIXCore_loongarch64.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_ELF_CORE_REGISTERCONTEXTPOSIXCORE_LOONGARCH64_H
10+
#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_LOONGARCH64_H
11+
12+
#include "Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.h"
13+
#include "Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h"
14+
15+
#include "Plugins/Process/elf-core/RegisterUtilities.h"
16+
#include "lldb/Target/Thread.h"
17+
#include "lldb/Utility/DataExtractor.h"
18+
#include "lldb/Utility/RegisterValue.h"
19+
20+
#include <memory>
21+
22+
class RegisterContextCorePOSIX_loongarch64
23+
: public RegisterContextPOSIX_loongarch64 {
24+
public:
25+
static std::unique_ptr<RegisterContextCorePOSIX_loongarch64>
26+
Create(lldb_private::Thread &thread, const lldb_private::ArchSpec &arch,
27+
const lldb_private::DataExtractor &gpregset,
28+
llvm::ArrayRef<lldb_private::CoreNote> notes);
29+
30+
~RegisterContextCorePOSIX_loongarch64() override;
31+
32+
bool ReadRegister(const lldb_private::RegisterInfo *reg_info,
33+
lldb_private::RegisterValue &value) override;
34+
35+
bool WriteRegister(const lldb_private::RegisterInfo *reg_info,
36+
const lldb_private::RegisterValue &value) override;
37+
38+
protected:
39+
RegisterContextCorePOSIX_loongarch64(
40+
lldb_private::Thread &thread,
41+
std::unique_ptr<RegisterInfoPOSIX_loongarch64> register_info,
42+
const lldb_private::DataExtractor &gpregset,
43+
llvm::ArrayRef<lldb_private::CoreNote> notes);
44+
45+
bool ReadGPR() override;
46+
47+
bool ReadFPR() override;
48+
49+
bool WriteGPR() override;
50+
51+
bool WriteFPR() override;
52+
53+
private:
54+
lldb_private::DataExtractor m_gpr;
55+
lldb_private::DataExtractor m_fpr;
56+
};
57+
58+
#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_LOONGARCH64_H

lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "RegisterContextLinuxCore_x86_64.h"
3434
#include "RegisterContextPOSIXCore_arm.h"
3535
#include "RegisterContextPOSIXCore_arm64.h"
36+
#include "RegisterContextPOSIXCore_loongarch64.h"
3637
#include "RegisterContextPOSIXCore_mips64.h"
3738
#include "RegisterContextPOSIXCore_powerpc.h"
3839
#include "RegisterContextPOSIXCore_ppc64le.h"
@@ -171,6 +172,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
171172

172173
if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64 &&
173174
arch.GetMachine() != llvm::Triple::arm &&
175+
arch.GetMachine() != llvm::Triple::loongarch64 &&
174176
arch.GetMachine() != llvm::Triple::riscv64) {
175177
LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported",
176178
__FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
@@ -187,6 +189,10 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
187189
*this, std::make_unique<RegisterInfoPOSIX_arm>(arch), m_gpregset_data,
188190
m_notes);
189191
break;
192+
case llvm::Triple::loongarch64:
193+
m_thread_reg_ctx_sp = RegisterContextCorePOSIX_loongarch64::Create(
194+
*this, arch, m_gpregset_data, m_notes);
195+
break;
190196
case llvm::Triple::riscv64:
191197
m_thread_reg_ctx_sp = RegisterContextCorePOSIX_riscv64::Create(
192198
*this, arch, m_gpregset_data, m_notes);

lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ class LinuxCoreTestCase(TestBase):
2323
_ppc64le_pid = 28147
2424
_riscv64_gpr_fpr_pid = 1089
2525
_riscv64_gpr_only_pid = 97
26+
_loongarch64_pid = 456735
2627

2728
_aarch64_regions = 4
2829
_i386_regions = 4
2930
_x86_64_regions = 5
3031
_s390x_regions = 2
3132
_ppc64le_regions = 2
3233
_riscv64_regions = 4
34+
_loongarch64_regions = 4
3335

3436
@skipIfLLVMTargetMissing("AArch64")
3537
def test_aarch64(self):
@@ -82,6 +84,16 @@ def test_riscv64_gpr_only(self):
8284
"a.out",
8385
)
8486

87+
@skipIfLLVMTargetMissing("LoongArch")
88+
def test_loongarch64(self):
89+
"""Test that lldb can read the process information from an loongarch64 linux core file."""
90+
self.do_test(
91+
"linux-loongarch64",
92+
self._loongarch64_pid,
93+
self._loongarch64_regions,
94+
"a.out",
95+
)
96+
8597
@skipIfLLVMTargetMissing("X86")
8698
def test_same_pid_running(self):
8799
"""Test that we read the information from the core correctly even if we have a running
@@ -833,6 +845,106 @@ def test_riscv64_regs_gpr_only(self):
833845
substrs=["registers were unavailable"],
834846
)
835847

848+
@skipIfLLVMTargetMissing("LoongArch")
849+
def test_loongarch64_regs(self):
850+
# check registers using 64 bit LoongArch core file containing GP and FP registers
851+
target = self.dbg.CreateTarget(None)
852+
self.assertTrue(target, VALID_TARGET)
853+
process = target.LoadCore("linux-loongarch64.core")
854+
855+
values = {}
856+
values["r0"] = "0x0000000000000000"
857+
values["r1"] = "0x000000012000016c"
858+
values["r2"] = "0x0000000000000000"
859+
values["r3"] = "0x00007ffffb8249e0"
860+
values["r4"] = "0x0000000000000000"
861+
values["r5"] = "0x000000012000010c"
862+
values["r6"] = "0x0000000000000000"
863+
values["r7"] = "0x0000000000000000"
864+
values["r8"] = "0x0000000000000000"
865+
values["r9"] = "0x0000000000000000"
866+
values["r10"] = "0x0000000000000000"
867+
values["r11"] = "0x00000000000000dd"
868+
values["r12"] = "0x0000000000000000"
869+
values["r13"] = "0x000000000000002f"
870+
values["r14"] = "0x0000000000000000"
871+
values["r15"] = "0x0000000000000000"
872+
values["r16"] = "0x0000000000000000"
873+
values["r17"] = "0x0000000000000000"
874+
values["r18"] = "0x0000000000000000"
875+
values["r19"] = "0x0000000000000000"
876+
values["r20"] = "0x0000000000000000"
877+
values["r21"] = "0x0000000000000000"
878+
values["r22"] = "0x00007ffffb824a10"
879+
values["r23"] = "0x0000000000000000"
880+
values["r24"] = "0x0000000000000000"
881+
values["r25"] = "0x0000000000000000"
882+
values["r26"] = "0x0000000000000000"
883+
values["r27"] = "0x0000000000000000"
884+
values["r28"] = "0x0000000000000000"
885+
values["r29"] = "0x0000000000000000"
886+
values["r30"] = "0x0000000000000000"
887+
values["r31"] = "0x0000000000000000"
888+
values["orig_a0"] = "0x0000555556b62d50"
889+
values["pc"] = "0x000000012000012c"
890+
891+
fpr_values = {}
892+
fpr_values["f0"] = "0x00000000ffffff05"
893+
fpr_values["f1"] = "0x2525252525252525"
894+
fpr_values["f2"] = "0x2525252525560005"
895+
fpr_values["f3"] = "0x000000000000ffff"
896+
fpr_values["f4"] = "0x0000000000000000"
897+
fpr_values["f5"] = "0x0000000000000008"
898+
fpr_values["f6"] = "0x0f0e0d0c0b0a0908"
899+
fpr_values["f7"] = "0xffffffffffffffff"
900+
fpr_values["f8"] = "0x6261747563657845"
901+
fpr_values["f9"] = "0x766173206562206c"
902+
fpr_values["f10"] = "0xffffffffffffffff"
903+
fpr_values["f11"] = "0xffffffffffffffff"
904+
fpr_values["f12"] = "0xffffffffffffffff"
905+
fpr_values["f13"] = "0xffffffffffffffff"
906+
fpr_values["f14"] = "0xffffffffffffffff"
907+
fpr_values["f15"] = "0xffffffffffffffff"
908+
fpr_values["f16"] = "0xffffffffffffffff"
909+
fpr_values["f17"] = "0xffffffffffffffff"
910+
fpr_values["f18"] = "0xffffffffffffffff"
911+
fpr_values["f19"] = "0xffffffffffffffff"
912+
fpr_values["f20"] = "0xffffffffffffffff"
913+
fpr_values["f21"] = "0xffffffffffffffff"
914+
fpr_values["f22"] = "0xffffffffffffffff"
915+
fpr_values["f23"] = "0xffffffffffffffff"
916+
fpr_values["f24"] = "0xffffffffffffffff"
917+
fpr_values["f25"] = "0xffffffffffffffff"
918+
fpr_values["f26"] = "0xffffffffffffffff"
919+
fpr_values["f27"] = "0xffffffffffffffff"
920+
fpr_values["f28"] = "0xffffffffffffffff"
921+
fpr_values["f29"] = "0xffffffffffffffff"
922+
fpr_values["f30"] = "0xffffffffffffffff"
923+
fpr_values["f31"] = "0xffffffffffffffff"
924+
fpr_values["fcc0"] = "0x01"
925+
fpr_values["fcc1"] = "0x00"
926+
fpr_values["fcc2"] = "0x01"
927+
fpr_values["fcc3"] = "0x01"
928+
fpr_values["fcc4"] = "0x01"
929+
fpr_values["fcc5"] = "0x01"
930+
fpr_values["fcc6"] = "0x00"
931+
fpr_values["fcc7"] = "0x01"
932+
fpr_values["fcsr"] = "0x00000000"
933+
934+
for regname, value in values.items():
935+
self.expect(
936+
"register read {}".format(regname),
937+
substrs=["{} = {}".format(regname, value)],
938+
)
939+
940+
for regname, value in fpr_values.items():
941+
self.expect(
942+
"register read {}".format(regname),
943+
substrs=["{} = {}".format(regname, value)],
944+
)
945+
946+
self.expect("register read --all")
947+
836948
def test_get_core_file_api(self):
837949
"""
838950
Test SBProcess::GetCoreFile() API can successfully get the core file.
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)