lh03061238 updated this revision to Diff 480297.
lh03061238 edited the summary of this revision.
lh03061238 added a comment.
(1) Use sort alphabetically in the following file
lldb/source/Plugins/Instruction/CMakeLists.txt
lldb/source/Plugins/Instruction/LoongArch/CMakeLists.txt
lldb/tools/lldb-server/CMakeLists.txt
lldb/tools/lldb-server/SystemInitializerLLGS.cpp
(2) Use ALL_CAPS for include guard symbol
(3) Modify the following functions
SupportsThisInstructionType(InstructionType inst_type)
GetOpcodeForInstruction(uint32_t inst)
EvaluateInstruction(uint32_t options)
CreateInstance(const ArchSpec &arch,InstructionType inst_type)
(4) Added TODO description in GetOpcodeForInstruction(uint32_t inst)
(5) Use #if defined(__loongarch__) in
lldb/tools/lldb-server/SystemInitializerLLGS.cpp
(6) Remove the example from commit message
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D139158/new/
https://reviews.llvm.org/D139158
Files:
lldb/source/Plugins/Instruction/CMakeLists.txt
lldb/source/Plugins/Instruction/LoongArch/CMakeLists.txt
lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp
lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h
lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
lldb/tools/lldb-server/CMakeLists.txt
lldb/tools/lldb-server/SystemInitializerLLGS.cpp
Index: lldb/tools/lldb-server/SystemInitializerLLGS.cpp
===================================================================
--- lldb/tools/lldb-server/SystemInitializerLLGS.cpp
+++ lldb/tools/lldb-server/SystemInitializerLLGS.cpp
@@ -29,6 +29,11 @@
#include "Plugins/Instruction/ARM/EmulateInstructionARM.h"
#endif
+#if defined(__loongarch__)
+#define LLDB_TARGET_LoongArch
+#include "Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h"
+#endif
+
#if defined(__mips64__) || defined(mips64) || defined(__mips64) || \
defined(__MIPS64__) || defined(_M_MIPS64)
#define LLDB_TARGET_MIPS64
@@ -57,6 +62,9 @@
#if defined(LLDB_TARGET_ARM) || defined(LLDB_TARGET_ARM64)
EmulateInstructionARM::Initialize();
#endif
+#if defined(LLDB_TARGET_LoongArch)
+ EmulateInstructionLoongArch::Initialize();
+#endif
#if defined(LLDB_TARGET_MIPS) || defined(LLDB_TARGET_MIPS64)
EmulateInstructionMIPS::Initialize();
#endif
@@ -76,6 +84,9 @@
#if defined(LLDB_TARGET_ARM) || defined(LLDB_TARGET_ARM64)
EmulateInstructionARM::Terminate();
#endif
+#if defined(LLDB_TARGET_LoongArch)
+ EmulateInstructionLoongArch::Terminate();
+#endif
#if defined(LLDB_TARGET_MIPS) || defined(LLDB_TARGET_MIPS64)
EmulateInstructionMIPS::Terminate();
#endif
Index: lldb/tools/lldb-server/CMakeLists.txt
===================================================================
--- lldb/tools/lldb-server/CMakeLists.txt
+++ lldb/tools/lldb-server/CMakeLists.txt
@@ -51,6 +51,7 @@
lldbVersion
${LLDB_PLUGINS}
lldbPluginInstructionARM
+ lldbPluginInstructionLoongArch
lldbPluginInstructionMIPS
lldbPluginInstructionMIPS64
lldbPluginInstructionRISCV
Index: lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
===================================================================
--- lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
+++ lldb/source/Plugins/Process/Utility/NativeProcessSoftwareSingleStep.cpp
@@ -168,7 +168,7 @@
size_hint = 4;
}
} else if (arch.IsMIPS() || arch.GetTriple().isPPC64() ||
- arch.GetTriple().isRISCV())
+ arch.GetTriple().isRISCV() || arch.GetTriple().isLoongArch())
size_hint = 4;
error = process.SetBreakpoint(next_pc, size_hint, /*hardware=*/false);
Index: lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
===================================================================
--- lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -883,7 +883,7 @@
bool NativeProcessLinux::SupportHardwareSingleStepping() const {
if (m_arch.IsMIPS() || m_arch.GetMachine() == llvm::Triple::arm ||
- m_arch.GetTriple().isRISCV())
+ m_arch.GetTriple().isRISCV() || m_arch.GetTriple().isLoongArch())
return false;
return true;
}
Index: lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h
@@ -0,0 +1,76 @@
+//===---EmulateInstructionLoongArch.h--------------------------------------===//
+//
+// 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_INSTRUCTION_LOONGARCH_EMULATEINSTRUCTIONLOONGARCH_H
+#define LLDB_SOURCE_PLUGINS_INSTRUCTION_LOONGARCH_EMULATEINSTRUCTIONLOONGARCH_H
+
+#include "lldb/Core/EmulateInstruction.h"
+#include "lldb/Interpreter/OptionValue.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/Status.h"
+
+namespace lldb_private {
+
+class EmulateInstructionLoongArch : public EmulateInstruction {
+public:
+ static llvm::StringRef GetPluginNameStatic() { return "LoongArch"; }
+
+ static llvm::StringRef GetPluginDescriptionStatic() {
+ return "Emulate instructions for the LoongArch architecture.";
+ }
+
+ static bool SupportsThisInstructionType(InstructionType inst_type) {
+ return inst_type == eInstructionTypePCModifying;
+ }
+
+ static bool SupportsThisArch(const ArchSpec &arch);
+
+ static lldb_private::EmulateInstruction *
+ CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type);
+
+ static void Initialize();
+
+ static void Terminate();
+
+public:
+ EmulateInstructionLoongArch(const ArchSpec &arch)
+ : EmulateInstruction(arch) {}
+
+ llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
+
+ bool SupportsEmulatingInstructionsOfType(InstructionType inst_type) override {
+ return SupportsThisInstructionType(inst_type);
+ }
+
+ bool SetTargetTriple(const ArchSpec &arch) override;
+ bool ReadInstruction() override;
+ bool EvaluateInstruction(uint32_t options) override;
+ bool TestEmulation(Stream *out_stream, ArchSpec &arch,
+ OptionValueDictionary *test_data) override;
+
+ llvm::Optional<RegisterInfo> GetRegisterInfo(lldb::RegisterKind reg_kind,
+ uint32_t reg_num) override;
+ lldb::addr_t ReadPC(bool *success);
+ bool WritePC(lldb::addr_t pc);
+
+private:
+ struct Opcode {
+ uint32_t mask;
+ uint32_t value;
+ bool (EmulateInstructionLoongArch::*callback)(uint32_t opcode);
+ const char *name;
+ };
+
+ Opcode *GetOpcodeForInstruction(uint32_t inst);
+
+ bool EmulateNonJMP(uint32_t inst);
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_LOONGARCH_EMULATEINSTRUCTIONLOONGARCH_H
Index: lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp
@@ -0,0 +1,181 @@
+//===---EmulateInstructionLoongArch.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 <cstdlib>
+
+#include "EmulateInstructionLoongArch.h"
+#include "Plugins/Process/Utility/InstructionUtils.h"
+#include "Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h"
+#include "Plugins/Process/Utility/lldb-loongarch-register-enums.h"
+#include "lldb/Core/Address.h"
+#include "lldb/Core/PluginManager.h"
+#include "lldb/Interpreter/OptionValueArray.h"
+#include "lldb/Interpreter/OptionValueDictionary.h"
+#include "lldb/Symbol/UnwindPlan.h"
+#include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/RegisterValue.h"
+#include "lldb/Utility/Stream.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/MathExtras.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+LLDB_PLUGIN_DEFINE_ADV(EmulateInstructionLoongArch, InstructionLoongArch)
+
+namespace lldb_private {
+
+EmulateInstructionLoongArch::Opcode *
+EmulateInstructionLoongArch::GetOpcodeForInstruction(uint32_t inst) {
+ // TODO: Add the mask of jump instruction.
+ static EmulateInstructionLoongArch::Opcode g_opcodes[] = {
+ {0x00000000, 0x00000000, &EmulateInstructionLoongArch::EmulateNonJMP,
+ "NonJMP"}};
+ static const size_t num_loongarch_opcodes = std::size(g_opcodes);
+
+ for (size_t i = 0; i < num_loongarch_opcodes; ++i)
+ if ((g_opcodes[i].mask & inst) == g_opcodes[i].value)
+ return &g_opcodes[i];
+ return nullptr;
+}
+
+bool EmulateInstructionLoongArch::EvaluateInstruction(uint32_t options) {
+ uint32_t inst_size = m_opcode.GetByteSize();
+ uint32_t inst = m_opcode.GetOpcode32();
+ bool increase_pc = options & eEmulateInstructionOptionAutoAdvancePC;
+ bool success = false;
+
+ Opcode *opcode_data = GetOpcodeForInstruction(inst);
+ if (!opcode_data)
+ return false;
+
+ lldb::addr_t old_pc = 0;
+ if (increase_pc) {
+ old_pc = ReadPC(&success);
+ if (!success)
+ return false;
+ }
+
+ // Call the Emulate... function.
+ if (!(this->*opcode_data->callback)(inst))
+ return false;
+
+ if (increase_pc) {
+ lldb::addr_t new_pc = ReadPC(&success);
+ if (!success)
+ return false;
+
+ if (new_pc == old_pc && !WritePC(old_pc + inst_size))
+ return false;
+ }
+ return true;
+}
+
+bool EmulateInstructionLoongArch::ReadInstruction() {
+ bool success = false;
+ m_addr = ReadPC(&success);
+ if (!success) {
+ m_addr = LLDB_INVALID_ADDRESS;
+ return false;
+ }
+
+ Context ctx;
+ ctx.type = eContextReadOpcode;
+ ctx.SetNoArgs();
+ uint32_t inst = (uint32_t)ReadMemoryUnsigned(ctx, m_addr, 4, 0, &success);
+ m_opcode.SetOpcode32(inst, GetByteOrder());
+
+ return true;
+}
+
+lldb::addr_t EmulateInstructionLoongArch::ReadPC(bool *success) {
+ return ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
+ LLDB_INVALID_ADDRESS, success);
+}
+
+bool EmulateInstructionLoongArch::WritePC(lldb::addr_t pc) {
+ EmulateInstruction::Context ctx;
+ ctx.type = eContextAdvancePC;
+ ctx.SetNoArgs();
+ return WriteRegisterUnsigned(ctx, eRegisterKindGeneric,
+ LLDB_REGNUM_GENERIC_PC, pc);
+}
+
+llvm::Optional<RegisterInfo>
+EmulateInstructionLoongArch::GetRegisterInfo(lldb::RegisterKind reg_kind,
+ uint32_t reg_index) {
+ if (reg_kind == eRegisterKindGeneric) {
+ switch (reg_index) {
+ case LLDB_REGNUM_GENERIC_PC:
+ reg_kind = eRegisterKindLLDB;
+ reg_index = gpr_pc_loongarch;
+ break;
+ case LLDB_REGNUM_GENERIC_SP:
+ reg_kind = eRegisterKindLLDB;
+ reg_index = gpr_sp_loongarch;
+ break;
+ case LLDB_REGNUM_GENERIC_FP:
+ reg_kind = eRegisterKindLLDB;
+ reg_index = gpr_fp_loongarch;
+ break;
+ case LLDB_REGNUM_GENERIC_RA:
+ reg_kind = eRegisterKindLLDB;
+ reg_index = gpr_ra_loongarch;
+ break;
+ // We may handle LLDB_REGNUM_GENERIC_ARGx when more instructions are
+ // supported.
+ default:
+ llvm_unreachable("unsupported register");
+ }
+ }
+
+ const RegisterInfo *array =
+ RegisterInfoPOSIX_loongarch64::GetRegisterInfoPtr(m_arch);
+ const uint32_t length =
+ RegisterInfoPOSIX_loongarch64::GetRegisterInfoCount(m_arch);
+
+ if (reg_index >= length || reg_kind != eRegisterKindLLDB)
+ return {};
+ return array[reg_index];
+}
+
+bool EmulateInstructionLoongArch::SetTargetTriple(const ArchSpec &arch) {
+ return SupportsThisArch(arch);
+}
+
+bool EmulateInstructionLoongArch::TestEmulation(
+ Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) {
+ return false;
+}
+
+void EmulateInstructionLoongArch::Initialize() {
+ PluginManager::RegisterPlugin(GetPluginNameStatic(),
+ GetPluginDescriptionStatic(), CreateInstance);
+}
+
+void EmulateInstructionLoongArch::Terminate() {
+ PluginManager::UnregisterPlugin(CreateInstance);
+}
+
+lldb_private::EmulateInstruction *
+EmulateInstructionLoongArch::CreateInstance(const ArchSpec &arch,
+ InstructionType inst_type) {
+ if (EmulateInstructionLoongArch::SupportsThisInstructionType(inst_type) &&
+ SupportsThisArch(arch))
+ return new EmulateInstructionLoongArch(arch);
+ return nullptr;
+}
+
+bool EmulateInstructionLoongArch::SupportsThisArch(const ArchSpec &arch) {
+ return arch.GetTriple().isLoongArch();
+}
+
+bool EmulateInstructionLoongArch::EmulateNonJMP(uint32_t inst) { return false; }
+
+} // namespace lldb_private
Index: lldb/source/Plugins/Instruction/LoongArch/CMakeLists.txt
===================================================================
--- /dev/null
+++ lldb/source/Plugins/Instruction/LoongArch/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_lldb_library(lldbPluginInstructionLoongArch PLUGIN
+ EmulateInstructionLoongArch.cpp
+
+ LINK_LIBS
+ lldbCore
+ lldbInterpreter
+ lldbPluginProcessUtility
+ lldbSymbol
+ LINK_COMPONENTS
+ Support
+ )
Index: lldb/source/Plugins/Instruction/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/Instruction/CMakeLists.txt
+++ lldb/source/Plugins/Instruction/CMakeLists.txt
@@ -1,5 +1,6 @@
add_subdirectory(ARM)
add_subdirectory(ARM64)
+add_subdirectory(LoongArch)
add_subdirectory(MIPS)
add_subdirectory(MIPS64)
add_subdirectory(PPC64)
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits