-
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
Conversation
Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the LLVM GitHub User Guide. You can also ask questions in a comment on this PR, on the LLVM Discord or on the forums. |
@llvm/pr-subscribers-lldb Author: Liu An (lawn123) ChangesWhen using the lldb command 'target create -- core' on the LoongArch64 architecture, this part of the code is required. Full diff: https://github.com/llvm/llvm-project/pull/112296.diff 4 Files Affected:
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..af192ecbe01e1b
--- /dev/null
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.cpp
@@ -0,0 +1,87 @@
+//===-- 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_buffer = std::make_shared<DataBufferHeap>(gpregset.GetDataStart(),
+ gpregset.GetByteSize());
+ m_gpr.SetData(m_gpr_buffer);
+ m_gpr.SetByteOrder(gpregset.GetByteOrder());
+
+ ArchSpec arch = m_register_info_up->GetTargetArchitecture();
+ DataExtractor fpregset = getRegset(notes, arch.GetTriple(), FPR_Desc);
+ m_fpr_buffer = std::make_shared<DataBufferHeap>(fpregset.GetDataStart(),
+ fpregset.GetByteSize());
+ m_fpr.SetData(m_fpr_buffer);
+ 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..44ee44badc5961
--- /dev/null
+++ b/lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.h
@@ -0,0 +1,62 @@
+//===-- 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::DataBufferSP m_gpr_buffer;
+ lldb::DataBufferSP m_fpr_buffer;
+
+ 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);
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wangleiat may take a look.
@@ -0,0 +1,87 @@ | |||
//===-- RegisterContextPOSIXCore_loongarch64.cpp | |||
//------------------------------===// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
format
@@ -0,0 +1,62 @@ | |||
//===-- RegisterContextPOSIXCore_loongarch64.h ----------------------*- C++ | |||
//-*-===// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
Do you mean |
Yes. use ' target create --core' to load dump files |
I don't see any tests yet, I think If you need more functionality to get to the point you can add tests, please add that to this PR or explain your plan for getting to a point where testing is possible (I'm not aware of the current status of LoongArch in LLDB). |
bool WriteFPR() override; | ||
|
||
private: | ||
lldb::DataBufferSP m_gpr_buffer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems we only need to define them as local variables before using it. No need to be class-member-variables.
Seems we the same |
|
fpr_values["fcc3"] = "0x01" | ||
fpr_values["fcc4"] = "0x01" | ||
fpr_values["fcc5"] = "0x01" | ||
fpr_values["fcc6"] = "0x0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto.
fpr_values["f30"] = "0xffffffffffffffff" | ||
fpr_values["f31"] = "0xffffffffffffffff" | ||
fpr_values["fcc0"] = "0x01" | ||
fpr_values["fcc1"] = "0x0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be 0x00
? Otherwise 0x01
can also match the expect.
fpr_values["fcc5"] = "0x01" | ||
fpr_values["fcc6"] = "0x0" | ||
fpr_values["fcc7"] = "0x01" | ||
fpr_values["fcsr"] = "0x0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0x00000000
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0x00000000
Other formatting issues have been corrected. Here, only 0x01 and 0x00 are allowed. Otherwise, the test will not pass
values["r11"] = "0x00000000000000dd" | ||
values["r12"] = "0x0" | ||
values["r13"] = "0x000000000000002f" | ||
values["r14"] = "0x0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we use full encoding (i.e. 8bytes)?
@@ -0,0 +1,84 @@ | |||
//===-- RegisterContextPOSIXCore_loongarch64.cpp ------------------------------===// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally one line has 80 characters at most.
@DavidSpickett General debugging commands can be used on LoongArch with some known issues to be addressed. Here is a summary #109394. For this PR, I have checked locally. I can confirm core dump file could be debugged with this change. |
@@ -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 comment
The 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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
There is confusion, I will revise it later.
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 comment
The 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 comment
The reason will be displayed to describe this comment to others. Learn more.
fcc* is 8 bit . fcsr is 4 byte.
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 comment
The reason will be displayed to describe this comment to others. Learn more.
Not like fcc registers, fcsr is 32bit.
(lldb) register read fcsr
fcsr = 0x00000000
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
For RISC-V I have been using #55383 as the tracking issue for overall support. If you want to, you could open a similar issue and write out what currently works, and I'll link to it from the main lldb page. Not a requirement, just if you have the time. |
✅ With the latest revision this PR passed the Python code formatter. |
✅ With the latest revision this PR passed the C/C++ code formatter. |
lldb/test/API/functionalities/postmortem/elf-core/linux-loongarch64.core
Outdated
Show resolved
Hide resolved
Thanks. I just filed #112693. |
Not sure what's going on with the register formatting. It might be that because we do a substring comparison, So I would recommend loading the core file manually and just copying whatever Other than that I don't have any objections here, seems like @SixWeining is the architecture expert so they can give the final approval. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me once the code_formatter
CI fail and fcsr format issues are addressed.
fpr_values["fcc5"] = "0x01" | ||
fpr_values["fcc6"] = "0x00" | ||
fpr_values["fcc7"] = "0x01" | ||
fpr_values["fcsr"] = "0x0000" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(lldb) register read fcsr
fcsr = 0x00000000
@DavidSpickett @SixWeining I have fix CI fail and fcsr format issues |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM and thanks!
@lawn123 Congratulations on having your first Pull Request (PR) merged into the LLVM Project! Your changes will be combined with recent changes from other authors, then tested by our build bots. If there is a problem with a build, you may receive a report in an email or a comment on this PR. Please check whether problems have been caused by your change specifically, as the builds can include changes from many authors. It is not uncommon for your change to be included in a build that fails due to someone else's changes, or infrastructure issues. How to do this, and the rest of the post-merge process, is covered in detail here. If your change does cause a problem, it may be reverted, or you can revert it yourself. This is a normal part of LLVM development. You can fix your changes and open a new PR to merge them again. If you don't get any reports, no action is required from you. Your changes are working as expected, well done! |
When using the lldb command 'target create --core' on the LoongArch64 architecture, this part of the code is required.