-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[lldb][LoongArch64] Add support for LoongArch64 in elf-core for lldb #112296
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
Changes from 3 commits
ba485de
355442e
2cce5e7
bd8409d
884a82d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
//===-- RegisterContextPOSIXCore_loongarch64.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_loongarch64.h" | ||
|
||
#include "lldb/Utility/DataBufferHeap.h" | ||
|
||
using namespace lldb_private; | ||
|
||
std::unique_ptr<RegisterContextCorePOSIX_loongarch64> | ||
RegisterContextCorePOSIX_loongarch64::Create(Thread &thread, | ||
const ArchSpec &arch, | ||
const DataExtractor &gpregset, | ||
llvm::ArrayRef<CoreNote> notes) { | ||
return std::unique_ptr<RegisterContextCorePOSIX_loongarch64>( | ||
new RegisterContextCorePOSIX_loongarch64( | ||
thread, | ||
std::make_unique<RegisterInfoPOSIX_loongarch64>(arch, Flags()), | ||
gpregset, notes)); | ||
} | ||
|
||
RegisterContextCorePOSIX_loongarch64::RegisterContextCorePOSIX_loongarch64( | ||
Thread &thread, | ||
std::unique_ptr<RegisterInfoPOSIX_loongarch64> register_info, | ||
const DataExtractor &gpregset, llvm::ArrayRef<CoreNote> notes) | ||
: RegisterContextPOSIX_loongarch64(thread, std::move(register_info)) { | ||
|
||
m_gpr.SetData(std::make_shared<DataBufferHeap>(gpregset.GetDataStart(), | ||
gpregset.GetByteSize())); | ||
m_gpr.SetByteOrder(gpregset.GetByteOrder()); | ||
|
||
ArchSpec arch = m_register_info_up->GetTargetArchitecture(); | ||
DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc); | ||
m_fpr.SetData(std::make_shared<DataBufferHeap>(fpregset.GetDataStart(), | ||
fpregset.GetByteSize())); | ||
m_fpr.SetByteOrder(fpregset.GetByteOrder()); | ||
} | ||
|
||
RegisterContextCorePOSIX_loongarch64::~RegisterContextCorePOSIX_loongarch64() = | ||
default; | ||
|
||
bool RegisterContextCorePOSIX_loongarch64::ReadGPR() { return true; } | ||
|
||
bool RegisterContextCorePOSIX_loongarch64::ReadFPR() { return true; } | ||
|
||
bool RegisterContextCorePOSIX_loongarch64::WriteGPR() { | ||
assert(false && "Writing registers is not allowed for core dumps"); | ||
return false; | ||
} | ||
|
||
bool RegisterContextCorePOSIX_loongarch64::WriteFPR() { | ||
assert(false && "Writing registers is not allowed for core dumps"); | ||
return false; | ||
} | ||
|
||
bool RegisterContextCorePOSIX_loongarch64::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_loongarch64::WriteRegister( | ||
const RegisterInfo *reg_info, const RegisterValue &value) { | ||
return false; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
//===-- RegisterContextPOSIXCore_loongarch64.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_LOONGARCH64_H | ||
#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_LOONGARCH64_H | ||
|
||
#include "Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.h" | ||
#include "Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.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_loongarch64 : public RegisterContextPOSIX_loongarch64 { | ||
public: | ||
static std::unique_ptr<RegisterContextCorePOSIX_loongarch64> | ||
Create(lldb_private::Thread &thread, const lldb_private::ArchSpec &arch, | ||
const lldb_private::DataExtractor &gpregset, | ||
llvm::ArrayRef<lldb_private::CoreNote> notes); | ||
|
||
~RegisterContextCorePOSIX_loongarch64() 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_loongarch64( | ||
lldb_private::Thread &thread, | ||
std::unique_ptr<RegisterInfoPOSIX_loongarch64> 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_private::DataExtractor m_gpr; | ||
lldb_private::DataExtractor m_fpr; | ||
}; | ||
|
||
#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERCONTEXTPOSIXCORE_LOONGARCH64_H |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,13 +23,15 @@ class LinuxCoreTestCase(TestBase): | |
_ppc64le_pid = 28147 | ||
_riscv64_gpr_fpr_pid = 1089 | ||
_riscv64_gpr_only_pid = 97 | ||
_loongarch64_pid = 456735 | ||
|
||
_aarch64_regions = 4 | ||
_i386_regions = 4 | ||
_x86_64_regions = 5 | ||
_s390x_regions = 2 | ||
_ppc64le_regions = 2 | ||
_riscv64_regions = 4 | ||
_loongarch64_regions = 4 | ||
|
||
@skipIfLLVMTargetMissing("AArch64") | ||
def test_aarch64(self): | ||
|
@@ -82,6 +84,16 @@ def test_riscv64_gpr_only(self): | |
"a.out", | ||
) | ||
|
||
@skipIfLLVMTargetMissing("LoongArch") | ||
def test_loongarch64(self): | ||
"""Test that lldb can read the process information from an loongarch64 linux core file.""" | ||
self.do_test( | ||
"linux-loongarch64", | ||
self._loongarch64_pid, | ||
self._loongarch64_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 | ||
|
@@ -833,6 +845,107 @@ def test_riscv64_regs_gpr_only(self): | |
substrs=["registers were unavailable"], | ||
) | ||
|
||
@skipIfLLVMTargetMissing("LoongArch") | ||
def test_loongarch64_regs(self): | ||
# check registers using 64 bit LoongArch64 core file containing GP-registers only | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this is a terminology difference. To me GP register would mean "general purpose" and not include floating point registers. But perhaps you always have an FPU so they are kinda general in that they always exist. I'd just change it to "GP and FP registers" to prevent any confusion. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is confusion, I will revise it later. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is confusion, I will revise it later. |
||
target = self.dbg.CreateTarget(None) | ||
self.assertTrue(target, VALID_TARGET) | ||
process = target.LoadCore("linux-loongarch64.core") | ||
|
||
values = {} | ||
values["r0"] = "0x0000000000000000" | ||
values["r1"] = "0x000000012000016c" | ||
values["r2"] = "0x0000000000000000" | ||
values["r3"] = "0x00007ffffb8249e0" | ||
values["r4"] = "0x0000000000000000" | ||
values["r5"] = "0x000000012000010c" | ||
values["r6"] = "0x0000000000000000" | ||
values["r7"] = "0x0000000000000000" | ||
values["r8"] = "0x0000000000000000" | ||
values["r9"] = "0x0000000000000000" | ||
values["r10"] = "0x0000000000000000" | ||
values["r11"] = "0x00000000000000dd" | ||
values["r12"] = "0x0000000000000000" | ||
values["r13"] = "0x000000000000002f" | ||
values["r14"] = "0x0000000000000000" | ||
values["r15"] = "0x0000000000000000" | ||
values["r16"] = "0x0000000000000000" | ||
values["r17"] = "0x0000000000000000" | ||
values["r18"] = "0x0000000000000000" | ||
values["r19"] = "0x0000000000000000" | ||
values["r20"] = "0x0000000000000000" | ||
values["r21"] = "0x0000000000000000" | ||
values["r22"] = "0x00007ffffb824a10" | ||
values["r23"] = "0x0000000000000000" | ||
values["r24"] = "0x0000000000000000" | ||
values["r25"] = "0x0000000000000000" | ||
values["r26"] = "0x0000000000000000" | ||
values["r27"] = "0x0000000000000000" | ||
values["r28"] = "0x0000000000000000" | ||
values["r29"] = "0x0000000000000000" | ||
values["r30"] = "0x0000000000000000" | ||
values["r31"] = "0x0000000000000000" | ||
values["orig_a0"] = "0x0000555556b62d50" | ||
values["pc"] = "0x000000012000012c" | ||
|
||
fpr_values = {} | ||
fpr_values["f0"] = "0x00000000ffffff05" | ||
fpr_values["f1"] = "0x2525252525252525" | ||
fpr_values["f2"] = "0x2525252525560005" | ||
fpr_values["f3"] = "0x000000000000ffff" | ||
fpr_values["f4"] = "0x0000000000000000" | ||
fpr_values["f5"] = "0x0000000000000008" | ||
fpr_values["f6"] = "0x0f0e0d0c0b0a0908" | ||
fpr_values["f7"] = "0xffffffffffffffff" | ||
fpr_values["f8"] = "0x6261747563657845" | ||
fpr_values["f9"] = "0x766173206562206c" | ||
fpr_values["f10"] = "0xffffffffffffffff" | ||
fpr_values["f11"] = "0xffffffffffffffff" | ||
fpr_values["f12"] = "0xffffffffffffffff" | ||
fpr_values["f13"] = "0xffffffffffffffff" | ||
fpr_values["f14"] = "0xffffffffffffffff" | ||
fpr_values["f15"] = "0xffffffffffffffff" | ||
fpr_values["f16"] = "0xffffffffffffffff" | ||
fpr_values["f17"] = "0xffffffffffffffff" | ||
fpr_values["f18"] = "0xffffffffffffffff" | ||
fpr_values["f19"] = "0xffffffffffffffff" | ||
fpr_values["f20"] = "0xffffffffffffffff" | ||
fpr_values["f21"] = "0xffffffffffffffff" | ||
fpr_values["f22"] = "0xffffffffffffffff" | ||
fpr_values["f23"] = "0xffffffffffffffff" | ||
fpr_values["f24"] = "0xffffffffffffffff" | ||
fpr_values["f25"] = "0xffffffffffffffff" | ||
fpr_values["f26"] = "0xffffffffffffffff" | ||
fpr_values["f27"] = "0xffffffffffffffff" | ||
fpr_values["f28"] = "0xffffffffffffffff" | ||
fpr_values["f29"] = "0xffffffffffffffff" | ||
fpr_values["f30"] = "0xffffffffffffffff" | ||
fpr_values["f31"] = "0xffffffffffffffff" | ||
fpr_values["fcc0"] = "0x01" | ||
fpr_values["fcc1"] = "0x00" | ||
fpr_values["fcc2"] = "0x01" | ||
fpr_values["fcc3"] = "0x01" | ||
fpr_values["fcc4"] = "0x01" | ||
fpr_values["fcc5"] = "0x01" | ||
fpr_values["fcc6"] = "0x00" | ||
fpr_values["fcc7"] = "0x01" | ||
fpr_values["fcsr"] = "0x00" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these 8 bit registers? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. fcc* is 8 bit . fcsr is 4 byte. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not like fcc registers, fcsr is 32bit.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
|
||
for regname, value in values.items(): | ||
self.expect( | ||
"register read {}".format(regname), | ||
substrs=["{} = {}".format(regname, value)], | ||
) | ||
|
||
for regname, value in fpr_values.items(): | ||
self.expect( | ||
"register read {}".format(regname), | ||
substrs=["{} = {}".format(regname, value)], | ||
) | ||
|
||
self.expect("register read --all") | ||
|
||
|
||
def test_get_core_file_api(self): | ||
""" | ||
Test SBProcess::GetCoreFile() API can successfully get the core file. | ||
|
DavidSpickett marked this conversation as resolved.
Show resolved
Hide resolved
|
Uh oh!
There was an error while loading. Please reload this page.