Skip to content

[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

Merged
merged 5 commits into from
Oct 21, 2024

Conversation

lawn123
Copy link
Contributor

@lawn123 lawn123 commented Oct 15, 2024

When using the lldb command 'target create --core' on the LoongArch64 architecture, this part of the code is required.

@lawn123 lawn123 requested a review from JDevlieghere as a code owner October 15, 2024 03:20
Copy link

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 @ followed by their GitHub username.

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.

@llvmbot llvmbot added the lldb label Oct 15, 2024
@llvmbot
Copy link
Member

llvmbot commented Oct 15, 2024

@llvm/pr-subscribers-lldb

Author: Liu An (lawn123)

Changes

When 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:

  • (modified) lldb/source/Plugins/Process/elf-core/CMakeLists.txt (+1)
  • (added) lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.cpp (+87)
  • (added) lldb/source/Plugins/Process/elf-core/RegisterContextPOSIXCore_loongarch64.h (+62)
  • (modified) lldb/source/Plugins/Process/elf-core/ThreadElfCore.cpp (+6)
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);

@lawn123
Copy link
Contributor Author

lawn123 commented Oct 15, 2024

@shushanhf

@shushanhf
Copy link

@shushanhf

@SixWeining

Copy link
Contributor

@SixWeining SixWeining left a 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
//------------------------------===//
Copy link
Contributor

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++
//-*-===//
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

@SixWeining
Copy link
Contributor

When using the lldb command 'target create -- core' on the LoongArch64 architecture, this part of the code is required.

Do you mean --core but not -- core?

@lawn123
Copy link
Contributor Author

lawn123 commented Oct 15, 2024

When using the lldb command 'target create -- core' on the LoongArch64 architecture, this part of the code is required.

Do you mean --core but not -- core?

Yes. use ' target create --core' to load dump files

@DavidSpickett DavidSpickett changed the title [LoongArch64]: Add support for LoongArch64 in elf-core for lldb [lldb][LoongArch64] Add support for LoongArch64 in elf-core for lldb Oct 15, 2024
@DavidSpickett
Copy link
Collaborator

I don't see any tests yet, I think lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py will be the place for those. There is a template program file you can use in that folder.

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;
Copy link
Contributor

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.

@SixWeining
Copy link
Contributor

Seems we the same GetRegisterSetCount misprint issue as #93297.

@lawn123
Copy link
Contributor Author

lawn123 commented Oct 17, 2024

I don't see any tests yet, I think lldb/test/API/functionalities/postmortem/elf-core/TestLinuxCore.py will be the place for those. There is a template program file you can use in that folder.
@DavidSpickett @SixWeining I have added two test cases to TestLinuxCore. py and modified the format as well as the issue with GetRegisterSetCount

fpr_values["fcc3"] = "0x01"
fpr_values["fcc4"] = "0x01"
fpr_values["fcc5"] = "0x01"
fpr_values["fcc6"] = "0x0"
Copy link
Contributor

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"
Copy link
Contributor

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"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0x00000000

Copy link
Contributor Author

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"
Copy link
Contributor

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 ------------------------------===//
Copy link
Contributor

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.

@SixWeining
Copy link
Contributor

I'm not aware of the current status of LoongArch in LLDB

@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
Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Copy link
Contributor Author

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"
Copy link
Collaborator

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?

Copy link
Contributor Author

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"
Copy link
Contributor

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@DavidSpickett
Copy link
Collaborator

@DavidSpickett General debugging commands can be used on LoongArch with some known issues to be addressed. Here is a summary #109394.

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.

Copy link

github-actions bot commented Oct 17, 2024

✅ With the latest revision this PR passed the Python code formatter.

Copy link

github-actions bot commented Oct 17, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@SixWeining
Copy link
Contributor

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.

Thanks. I just filed #112693.

@DavidSpickett
Copy link
Collaborator

Not sure what's going on with the register formatting. It might be that because we do a substring comparison, foo = 0x00 is found in foo = 0x00000000.

So I would recommend loading the core file manually and just copying whatever register read shows. If the formatting is still off, potentially you need to update the register sizes or formatting style, but I don't think you need to do that in this PR. It can be a follow up to do just that.

Other than that I don't have any objections here, seems like @SixWeining is the architecture expert so they can give the final approval.

Copy link
Contributor

@SixWeining SixWeining left a 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"
Copy link
Contributor

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

@lawn123
Copy link
Contributor Author

lawn123 commented Oct 21, 2024

@DavidSpickett @SixWeining I have fix CI fail and fcsr format issues

Copy link
Contributor

@SixWeining SixWeining left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM and thanks!

@DavidSpickett DavidSpickett merged commit 911a6f2 into llvm:main Oct 21, 2024
7 checks passed
Copy link

@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!

@lawn123 lawn123 deleted the loongarch_lldb branch October 23, 2024 07:59
@SixWeining SixWeining mentioned this pull request Nov 1, 2024
7 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants