mirror of
https://github.com/intel/llvm.git
synced 2026-01-26 12:26:52 +08:00
[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.
This commit is contained in:
@@ -58,7 +58,7 @@ RegisterContextPOSIX_loongarch64::GetRegisterInfoAtIndex(size_t reg) {
|
||||
}
|
||||
|
||||
size_t RegisterContextPOSIX_loongarch64::GetRegisterSetCount() {
|
||||
return m_register_info_up->GetRegisterCount();
|
||||
return m_register_info_up->GetRegisterSetCount();
|
||||
}
|
||||
|
||||
const lldb_private::RegisterSet *
|
||||
|
||||
@@ -10,6 +10,7 @@ add_lldb_library(lldbPluginProcessElfCore PLUGIN
|
||||
RegisterContextPOSIXCore_s390x.cpp
|
||||
RegisterContextPOSIXCore_x86_64.cpp
|
||||
RegisterContextPOSIXCore_riscv64.cpp
|
||||
RegisterContextPOSIXCore_loongarch64.cpp
|
||||
RegisterUtilities.cpp
|
||||
|
||||
LINK_LIBS
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
//===-- 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
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "RegisterContextLinuxCore_x86_64.h"
|
||||
#include "RegisterContextPOSIXCore_arm.h"
|
||||
#include "RegisterContextPOSIXCore_arm64.h"
|
||||
#include "RegisterContextPOSIXCore_loongarch64.h"
|
||||
#include "RegisterContextPOSIXCore_mips64.h"
|
||||
#include "RegisterContextPOSIXCore_powerpc.h"
|
||||
#include "RegisterContextPOSIXCore_ppc64le.h"
|
||||
@@ -171,6 +172,7 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
|
||||
|
||||
if (!reg_interface && arch.GetMachine() != llvm::Triple::aarch64 &&
|
||||
arch.GetMachine() != llvm::Triple::arm &&
|
||||
arch.GetMachine() != llvm::Triple::loongarch64 &&
|
||||
arch.GetMachine() != llvm::Triple::riscv64) {
|
||||
LLDB_LOGF(log, "elf-core::%s:: Architecture(%d) or OS(%d) not supported",
|
||||
__FUNCTION__, arch.GetMachine(), arch.GetTriple().getOS());
|
||||
@@ -187,6 +189,10 @@ ThreadElfCore::CreateRegisterContextForFrame(StackFrame *frame) {
|
||||
*this, std::make_unique<RegisterInfoPOSIX_arm>(arch), m_gpregset_data,
|
||||
m_notes);
|
||||
break;
|
||||
case llvm::Triple::loongarch64:
|
||||
m_thread_reg_ctx_sp = RegisterContextCorePOSIX_loongarch64::Create(
|
||||
*this, 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);
|
||||
|
||||
@@ -23,6 +23,7 @@ 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
|
||||
@@ -30,6 +31,7 @@ class LinuxCoreTestCase(TestBase):
|
||||
_s390x_regions = 2
|
||||
_ppc64le_regions = 2
|
||||
_riscv64_regions = 4
|
||||
_loongarch64_regions = 4
|
||||
|
||||
@skipIfLLVMTargetMissing("AArch64")
|
||||
def test_aarch64(self):
|
||||
@@ -82,6 +84,16 @@ class LinuxCoreTestCase(TestBase):
|
||||
"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,106 @@ class LinuxCoreTestCase(TestBase):
|
||||
substrs=["registers were unavailable"],
|
||||
)
|
||||
|
||||
@skipIfLLVMTargetMissing("LoongArch")
|
||||
def test_loongarch64_regs(self):
|
||||
# check registers using 64 bit LoongArch core file containing GP and FP registers
|
||||
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"] = "0x00000000"
|
||||
|
||||
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.
|
||||
|
||||
Binary file not shown.
BIN
lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.out
Executable file
BIN
lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.out
Executable file
Binary file not shown.
Reference in New Issue
Block a user