Author: Liu An Date: 2024-10-21T10:04:55+01:00 New Revision: 911a6f2fcc719c46b5b392823473ba0bb5b1f4e1
URL: https://github.com/llvm/llvm-project/commit/911a6f2fcc719c46b5b392823473ba0bb5b1f4e1 DIFF: https://github.com/llvm/llvm-project/commit/911a6f2fcc719c46b5b392823473ba0bb5b1f4e1.diff LOG: [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. Added: lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.cpp lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.h lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.core lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.out Modified: lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp lldb/source/Plugins/Process/elf-core/CMakeLists.txt lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py Removed: ################################################################################ diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp index a48a58f28f7aad..49f371fb949b7b 100644 --- a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp +++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp @@ -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 * diff --git a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt index 72925c835b5c89..7473fa8d41ccb3 100644 --- a/lldb/source/Plugins/Process/elf-core/CMakeLists.txt +++ b/lldb/source/Plugins/Process/elf-core/CMakeLists.txt @@ -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 diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.cpp b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.cpp new file mode 100644 index 00000000000000..f0500948a6ab22 --- /dev/null +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.cpp @@ -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; +} diff --git a/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.h b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.h new file mode 100644 index 00000000000000..7bb53bd642030a --- /dev/null +++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.h @@ -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 diff --git a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp index 52b96052bdbeca..f2838087298efb 100644 --- a/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp +++ b/lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp @@ -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); diff --git a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py index 7e8531c88bf34c..376d6492d83b60 100644 --- a/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py +++ b/lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py @@ -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 @@ 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,106 @@ def test_riscv64_regs_gpr_only(self): 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. diff --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.core b/lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.core new file mode 100644 index 00000000000000..8738950b8e08dc Binary files /dev/null and b/lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.core diff er diff --git a/lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.out b/lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.out new file mode 100755 index 00000000000000..ea3c61ac5bae7c Binary files /dev/null and b/lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.out diff er _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits