From d938b331ef903aef3bc078c7c1ce0b2f14f6ffa0 Mon Sep 17 00:00:00 2001 From: herengui Date: Wed, 30 Aug 2023 17:19:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=BE=99=E8=8A=AF=E6=9E=B6?= =?UTF-8?q?=E6=9E=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: herengui --- ...-loongarch-support-upstream-modified.patch | 444 ++++ 1001-add-loongarch-support-upstream-new.patch | 2138 +++++++++++++++++ lldb.spec | 8 +- 3 files changed, 2589 insertions(+), 1 deletion(-) create mode 100644 1000-add-loongarch-support-upstream-modified.patch create mode 100644 1001-add-loongarch-support-upstream-new.patch diff --git a/1000-add-loongarch-support-upstream-modified.patch b/1000-add-loongarch-support-upstream-modified.patch new file mode 100644 index 0000000..c4b85b9 --- /dev/null +++ b/1000-add-loongarch-support-upstream-modified.patch @@ -0,0 +1,444 @@ +From 41d770db46367b40e013f2989040369a3a950821 Mon Sep 17 00:00:00 2001 +From: herengui +Date: Wed, 30 Aug 2023 17:16:13 +0800 +Subject: [PATCH 1000/1001] add loongarch support upstream modified + +Signed-off-by: herengui +--- + include/lldb/Utility/ArchSpec.h | 9 ++ + source/Host/common/HostInfoBase.cpp | 1 + + source/Host/common/NativeProcessProtocol.cpp | 8 + + source/Plugins/Instruction/CMakeLists.txt | 1 + + source/Plugins/ObjectFile/ELF/ELFHeader.cpp | 3 + + .../Plugins/ObjectFile/ELF/ObjectFileELF.cpp | 147 +++++++++++++----- + source/Plugins/Process/Linux/CMakeLists.txt | 1 + + .../Process/Linux/NativeProcessLinux.cpp | 3 +- + source/Plugins/Process/Utility/CMakeLists.txt | 2 + + source/Target/Platform.cpp | 8 + + source/Utility/ArchSpec.cpp | 11 ++ + tools/lldb-server/CMakeLists.txt | 1 + + tools/lldb-server/SystemInitializerLLGS.cpp | 11 ++ + 13 files changed, 164 insertions(+), 42 deletions(-) + +diff --git a/lldb/include/lldb/Utility/ArchSpec.h b/lldb/include/lldb/Utility/ArchSpec.h +index fdfe6ac..4b2f85f 100644 +--- a/lldb/include/lldb/Utility/ArchSpec.h ++++ b/lldb/include/lldb/Utility/ArchSpec.h +@@ -98,6 +98,12 @@ public: + eRISCVSubType_riscv64, + }; + ++ enum LoongArchSubType { ++ eLoongArchSubType_unknown, ++ eLoongArchSubType_loongarch32, ++ eLoongArchSubType_loongarch64, ++ }; ++ + enum Core { + eCore_arm_generic, + eCore_arm_armv4, +@@ -194,6 +200,9 @@ public: + eCore_riscv32, + eCore_riscv64, + ++ eCore_loongarch32, ++ eCore_loongarch64, ++ + eCore_uknownMach32, + eCore_uknownMach64, + +diff --git a/lldb/source/Host/common/HostInfoBase.cpp b/lldb/source/Host/common/HostInfoBase.cpp +index 333137a..9edce1b 100644 +--- a/lldb/source/Host/common/HostInfoBase.cpp ++++ b/lldb/source/Host/common/HostInfoBase.cpp +@@ -335,6 +335,7 @@ void HostInfoBase::ComputeHostArchitectureSupport(ArchSpec &arch_32, + case llvm::Triple::ppc64: + case llvm::Triple::ppc64le: + case llvm::Triple::x86_64: ++ case llvm::Triple::loongarch64: + arch_64.SetTriple(triple); + arch_32.SetTriple(triple.get32BitArchVariant()); + break; +diff --git a/lldb/source/Host/common/NativeProcessProtocol.cpp b/lldb/source/Host/common/NativeProcessProtocol.cpp +index 493e14c..925798b 100644 +--- a/lldb/source/Host/common/NativeProcessProtocol.cpp ++++ b/lldb/source/Host/common/NativeProcessProtocol.cpp +@@ -523,6 +523,8 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) { + static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00}; + static const uint8_t g_s390x_opcode[] = {0x00, 0x01}; + static const uint8_t g_ppc64le_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap ++ static const uint8_t g_loongarch_opcode[] = {0x05, 0x00, 0x2a, ++ 0x00}; // break 0x5 + + switch (GetArchitecture().GetMachine()) { + case llvm::Triple::aarch64: +@@ -547,6 +549,10 @@ NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) { + case llvm::Triple::ppc64le: + return llvm::makeArrayRef(g_ppc64le_opcode); + ++ case llvm::Triple::loongarch32: ++ case llvm::Triple::loongarch64: ++ return llvm::makeArrayRef(g_loongarch_opcode); ++ + default: + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "CPU type not supported!"); +@@ -569,6 +575,8 @@ size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() { + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::ppc64le: ++ case llvm::Triple::loongarch32: ++ case llvm::Triple::loongarch64: + // On these architectures the PC doesn't get updated for breakpoint hits. + return 0; + +diff --git a/lldb/source/Plugins/Instruction/CMakeLists.txt b/lldb/source/Plugins/Instruction/CMakeLists.txt +index 89771e8..19973dd 100644 +--- a/lldb/source/Plugins/Instruction/CMakeLists.txt ++++ b/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) +diff --git a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +index f0496be..4201aab 100644 +--- a/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp ++++ b/lldb/source/Plugins/ObjectFile/ELF/ELFHeader.cpp +@@ -208,6 +208,9 @@ unsigned ELFHeader::GetRelocationJumpSlotType() const { + case EM_S390: + slot = R_390_JMP_SLOT; + break; ++ case EM_LOONGARCH: ++ slot = R_LARCH_JUMP_SLOT; ++ break; + } + + return slot; +diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +index cad9ce2..70369f7 100644 +--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp ++++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp +@@ -308,11 +308,25 @@ static uint32_t riscvVariantFromElfFlags(const elf::ELFHeader &header) { + } + } + ++static uint32_t loongarchVariantFromElfFlags(const elf::ELFHeader &header) { ++ uint32_t fileclass = header.e_ident[EI_CLASS]; ++ switch (fileclass) { ++ case llvm::ELF::ELFCLASS32: ++ return ArchSpec::eLoongArchSubType_loongarch32; ++ case llvm::ELF::ELFCLASS64: ++ return ArchSpec::eLoongArchSubType_loongarch64; ++ default: ++ return ArchSpec::eLoongArchSubType_unknown; ++ } ++} ++ + static uint32_t subTypeFromElfHeader(const elf::ELFHeader &header) { + if (header.e_machine == llvm::ELF::EM_MIPS) + return mipsVariantFromElfFlags(header); + else if (header.e_machine == llvm::ELF::EM_RISCV) + return riscvVariantFromElfFlags(header); ++ else if (header.e_machine == llvm::ELF::EM_LOONGARCH) ++ return loongarchVariantFromElfFlags(header); + + return LLDB_INVALID_CPUTYPE; + } +@@ -2562,6 +2576,44 @@ ObjectFileELF::ParseTrampolineSymbols(Symtab *symbol_table, user_id_t start_id, + rel_data, symtab_data, strtab_data); + } + ++static void ApplyELF64ABS64Relocation(Symtab *symtab, ELFRelocation &rel, ++ DataExtractor &debug_data, ++ Section *rel_section) { ++ Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel)); ++ if (symbol) { ++ addr_t value = symbol->GetAddressRef().GetFileAddress(); ++ DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); ++ uint64_t *dst = reinterpret_cast( ++ data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ++ ELFRelocation::RelocOffset64(rel)); ++ uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel); ++ memcpy(dst, &val_offset, sizeof(uint64_t)); ++ } ++} ++ ++static void ApplyELF64ABS32Relocation(Symtab *symtab, ELFRelocation &rel, ++ DataExtractor &debug_data, ++ Section *rel_section, bool is_signed) { ++ Symbol *symbol = symtab->FindSymbolByID(ELFRelocation::RelocSymbol64(rel)); ++ if (symbol) { ++ addr_t value = symbol->GetAddressRef().GetFileAddress(); ++ value += ELFRelocation::RelocAddend32(rel); ++ if ((!is_signed && (value > UINT32_MAX)) || ++ (is_signed && ++ ((int64_t)value > INT32_MAX || (int64_t)value < INT32_MIN))) { ++ Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); ++ LLDB_LOGF(log, "Failed to apply debug info relocations"); ++ return; ++ } ++ uint32_t truncated_addr = (value & 0xFFFFFFFF); ++ DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); ++ uint32_t *dst = reinterpret_cast( ++ data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ++ ELFRelocation::RelocOffset32(rel)); ++ memcpy(dst, &truncated_addr, sizeof(uint32_t)); ++ } ++} ++ + unsigned ObjectFileELF::ApplyRelocations( + Symtab *symtab, const ELFHeader *hdr, const ELFSectionHeader *rel_hdr, + const ELFSectionHeader *symtab_hdr, const ELFSectionHeader *debug_hdr, +@@ -2604,50 +2656,63 @@ unsigned ObjectFileELF::ApplyRelocations( + assert(false && "unexpected relocation type"); + } + } else { +- switch (reloc_type(rel)) { +- case R_AARCH64_ABS64: +- case R_X86_64_64: { +- symbol = symtab->FindSymbolByID(reloc_symbol(rel)); +- if (symbol) { +- addr_t value = symbol->GetAddressRef().GetFileAddress(); +- DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); +- uint64_t *dst = reinterpret_cast( +- data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + +- ELFRelocation::RelocOffset64(rel)); +- uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel); +- memcpy(dst, &val_offset, sizeof(uint64_t)); ++ if (hdr->e_machine == llvm::ELF::EM_LOONGARCH) { ++ switch (reloc_type(rel)) { ++ case R_LARCH_64: ++ ApplyELF64ABS64Relocation(symtab, rel, debug_data, rel_section); ++ break; ++ case R_LARCH_32: ++ ApplyELF64ABS32Relocation(symtab, rel, debug_data, rel_section, true); ++ break; ++ default: ++ assert(false && "unexpected relocation type"); + } +- break; +- } +- case R_X86_64_32: +- case R_X86_64_32S: +- case R_AARCH64_ABS32: { +- symbol = symtab->FindSymbolByID(reloc_symbol(rel)); +- if (symbol) { +- addr_t value = symbol->GetAddressRef().GetFileAddress(); +- value += ELFRelocation::RelocAddend32(rel); +- if ((reloc_type(rel) == R_X86_64_32 && (value > UINT32_MAX)) || +- (reloc_type(rel) == R_X86_64_32S && +- ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) || +- (reloc_type(rel) == R_AARCH64_ABS32 && +- ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) { +- Log *log = +- lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); +- LLDB_LOGF(log, "Failed to apply debug info relocations"); +- break; ++ } else { ++ switch (reloc_type(rel)) { ++ case R_AARCH64_ABS64: ++ case R_X86_64_64: { ++ symbol = symtab->FindSymbolByID(reloc_symbol(rel)); ++ if (symbol) { ++ addr_t value = symbol->GetAddressRef().GetFileAddress(); ++ DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); ++ uint64_t *dst = reinterpret_cast( ++ data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ++ ELFRelocation::RelocOffset64(rel)); ++ uint64_t val_offset = value + ELFRelocation::RelocAddend64(rel); ++ memcpy(dst, &val_offset, sizeof(uint64_t)); + } +- uint32_t truncated_addr = (value & 0xFFFFFFFF); +- DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); +- uint32_t *dst = reinterpret_cast( +- data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + +- ELFRelocation::RelocOffset32(rel)); +- memcpy(dst, &truncated_addr, sizeof(uint32_t)); ++ break; ++ } ++ case R_X86_64_32: ++ case R_X86_64_32S: ++ case R_AARCH64_ABS32: { ++ symbol = symtab->FindSymbolByID(reloc_symbol(rel)); ++ if (symbol) { ++ addr_t value = symbol->GetAddressRef().GetFileAddress(); ++ value += ELFRelocation::RelocAddend32(rel); ++ if ((reloc_type(rel) == R_X86_64_32 && (value > UINT32_MAX)) || ++ (reloc_type(rel) == R_X86_64_32S && ++ ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN)) || ++ (reloc_type(rel) == R_AARCH64_ABS32 && ++ ((int64_t)value > INT32_MAX && (int64_t)value < INT32_MIN))) { ++ Log *log = ++ lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_MODULES); ++ LLDB_LOGF(log, "Failed to apply debug info relocations"); ++ break; ++ } ++ uint32_t truncated_addr = (value & 0xFFFFFFFF); ++ DataBufferSP &data_buffer_sp = debug_data.GetSharedDataBuffer(); ++ uint32_t *dst = reinterpret_cast( ++ data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ++ ELFRelocation::RelocOffset32(rel)); ++ memcpy(dst, &truncated_addr, sizeof(uint32_t)); ++ } ++ break; ++ } ++ case R_X86_64_PC32: ++ default: ++ assert(false && "unexpected relocation type"); + } +- break; +- } +- case R_X86_64_PC32: +- default: +- assert(false && "unexpected relocation type"); + } + } + } +diff --git a/lldb/source/Plugins/Process/Linux/CMakeLists.txt b/lldb/source/Plugins/Process/Linux/CMakeLists.txt +index dd2a889..9e3877b 100644 +--- a/lldb/source/Plugins/Process/Linux/CMakeLists.txt ++++ b/lldb/source/Plugins/Process/Linux/CMakeLists.txt +@@ -3,6 +3,7 @@ add_lldb_library(lldbPluginProcessLinux + NativeRegisterContextLinux.cpp + NativeRegisterContextLinux_arm.cpp + NativeRegisterContextLinux_arm64.cpp ++ NativeRegisterContextLinux_loongarch64.cpp + NativeRegisterContextLinux_mips64.cpp + NativeRegisterContextLinux_ppc64le.cpp + NativeRegisterContextLinux_s390x.cpp +diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +index e07d763..b4d48c8 100644 +--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp ++++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp +@@ -1024,7 +1024,8 @@ NativeProcessLinux::SetupSoftwareSingleStepping(NativeThreadLinux &thread) { + } + + bool NativeProcessLinux::SupportHardwareSingleStepping() const { +- if (m_arch.GetMachine() == llvm::Triple::arm || m_arch.IsMIPS()) ++ if (m_arch.GetMachine() == llvm::Triple::arm || m_arch.IsMIPS() || ++ m_arch.GetTriple().isLoongArch()) + return false; + return true; + } +diff --git a/lldb/source/Plugins/Process/Utility/CMakeLists.txt b/lldb/source/Plugins/Process/Utility/CMakeLists.txt +index 9965d89..9615170 100644 +--- a/lldb/source/Plugins/Process/Utility/CMakeLists.txt ++++ b/lldb/source/Plugins/Process/Utility/CMakeLists.txt +@@ -38,6 +38,7 @@ add_lldb_library(lldbPluginProcessUtility + RegisterContextOpenBSD_x86_64.cpp + RegisterContextPOSIX_arm.cpp + RegisterContextPOSIX_arm64.cpp ++ RegisterContextPOSIX_loongarch64.cpp + RegisterContextPOSIX_mips64.cpp + RegisterContextPOSIX_powerpc.cpp + RegisterContextPOSIX_ppc64le.cpp +@@ -48,6 +49,7 @@ add_lldb_library(lldbPluginProcessUtility + RegisterContextWindows_x86_64.cpp + RegisterInfoPOSIX_arm.cpp + RegisterInfoPOSIX_arm64.cpp ++ RegisterInfoPOSIX_loongarch64.cpp + RegisterInfoPOSIX_ppc64le.cpp + StopInfoMachException.cpp + ThreadMemory.cpp +diff --git a/lldb/source/Target/Platform.cpp b/lldb/source/Target/Platform.cpp +index a77ecdd..d913e88 100644 +--- a/lldb/source/Target/Platform.cpp ++++ b/lldb/source/Target/Platform.cpp +@@ -1970,6 +1970,14 @@ size_t Platform::GetSoftwareBreakpointTrapOpcode(Target &target, + trap_opcode_size = sizeof(g_i386_opcode); + } break; + ++ case llvm::Triple::loongarch32: ++ case llvm::Triple::loongarch64: { ++ static const uint8_t g_loongarch_opcode[] = {0x05, 0x00, 0x2a, ++ 0x00}; // break 0x5 ++ trap_opcode = g_loongarch_opcode; ++ trap_opcode_size = sizeof(g_loongarch_opcode); ++ } break; ++ + default: + return 0; + } +diff --git a/lldb/source/Utility/ArchSpec.cpp b/lldb/source/Utility/ArchSpec.cpp +index c13e238..8ab5d04 100644 +--- a/lldb/source/Utility/ArchSpec.cpp ++++ b/lldb/source/Utility/ArchSpec.cpp +@@ -219,6 +219,11 @@ static const CoreDefinition g_core_definitions[] = { + {eByteOrderLittle, 8, 2, 4, llvm::Triple::riscv64, ArchSpec::eCore_riscv64, + "riscv64"}, + ++ {eByteOrderLittle, 4, 4, 4, llvm::Triple::loongarch32, ++ ArchSpec::eCore_loongarch32, "loongarch32"}, ++ {eByteOrderLittle, 8, 4, 4, llvm::Triple::loongarch64, ++ ArchSpec::eCore_loongarch64, "loongarch64"}, ++ + {eByteOrderLittle, 4, 4, 4, llvm::Triple::UnknownArch, + ArchSpec::eCore_uknownMach32, "unknown-mach-32"}, + {eByteOrderLittle, 8, 4, 4, llvm::Triple::UnknownArch, +@@ -405,6 +410,12 @@ static const ArchDefinitionEntry g_elf_arch_entries[] = { + ArchSpec::eRISCVSubType_riscv32, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv32 + {ArchSpec::eCore_riscv64, llvm::ELF::EM_RISCV, + ArchSpec::eRISCVSubType_riscv64, 0xFFFFFFFFu, 0xFFFFFFFFu}, // riscv64 ++ {ArchSpec::eCore_loongarch32, llvm::ELF::EM_LOONGARCH, ++ ArchSpec::eLoongArchSubType_loongarch32, 0xFFFFFFFFu, ++ 0xFFFFFFFFu}, // loongarch32 ++ {ArchSpec::eCore_loongarch64, llvm::ELF::EM_LOONGARCH, ++ ArchSpec::eLoongArchSubType_loongarch64, 0xFFFFFFFFu, ++ 0xFFFFFFFFu}, // loongarch64 + }; + + static const ArchDefinition g_elf_arch_def = { +diff --git a/lldb/tools/lldb-server/CMakeLists.txt b/lldb/tools/lldb-server/CMakeLists.txt +index 930c327..d40c025 100644 +--- a/lldb/tools/lldb-server/CMakeLists.txt ++++ b/lldb/tools/lldb-server/CMakeLists.txt +@@ -53,6 +53,7 @@ add_lldb_tool(lldb-server + lldbInitialization + ${LLDB_PLUGINS} + lldbPluginInstructionARM ++ lldbPluginInstructionLoongArch + lldbPluginInstructionMIPS + lldbPluginInstructionMIPS64 + ${LLDB_SYSTEM_LIBS} +diff --git a/lldb/tools/lldb-server/SystemInitializerLLGS.cpp b/lldb/tools/lldb-server/SystemInitializerLLGS.cpp +index b93e6b4..581c43b 100644 +--- a/lldb/tools/lldb-server/SystemInitializerLLGS.cpp ++++ b/lldb/tools/lldb-server/SystemInitializerLLGS.cpp +@@ -29,6 +29,11 @@ using HostObjectFile = ObjectFileELF; + #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 +@@ -52,6 +57,9 @@ llvm::Error SystemInitializerLLGS::Initialize() { + #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 +@@ -68,6 +76,9 @@ void SystemInitializerLLGS::Terminate() { + #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 +-- +2.41.0 + diff --git a/1001-add-loongarch-support-upstream-new.patch b/1001-add-loongarch-support-upstream-new.patch new file mode 100644 index 0000000..577cdcf --- /dev/null +++ b/1001-add-loongarch-support-upstream-new.patch @@ -0,0 +1,2138 @@ +From 9e54416dbfc3098d49665751e18def3270b1a5fb Mon Sep 17 00:00:00 2001 +From: herengui +Date: Wed, 30 Aug 2023 17:16:20 +0800 +Subject: [PATCH 1001/1001] add loongarch support upstream new + +Signed-off-by: herengui +--- + .../Instruction/LoongArch/CMakeLists.txt | 11 + + .../LoongArch/EmulateInstructionLoongArch.cpp | 545 ++++++++++++++++++ + .../LoongArch/EmulateInstructionLoongArch.h | 112 ++++ + ...NativeRegisterContextLinux_loongarch64.cpp | 328 +++++++++++ + .../NativeRegisterContextLinux_loongarch64.h | 92 +++ + .../RegisterContextPOSIX_loongarch64.cpp | 82 +++ + .../RegisterContextPOSIX_loongarch64.h | 63 ++ + .../Utility/RegisterInfoPOSIX_loongarch64.cpp | 158 +++++ + .../Utility/RegisterInfoPOSIX_loongarch64.h | 68 +++ + .../Utility/RegisterInfos_loongarch64.h | 171 ++++++ + .../Utility/lldb-loongarch-register-enums.h | 178 ++++++ + source/Utility/LoongArch_DWARF_Registers.h | 177 ++++++ + test/Shell/ObjectFile/ELF/loongarch-arch.yaml | 24 + + 13 files changed, 2009 insertions(+) + create mode 100644 source/Plugins/Instruction/LoongArch/CMakeLists.txt + create mode 100644 source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp + create mode 100644 source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h + create mode 100644 source/Plugins/Process/Linux/NativeRegisterContextLinux_loongarch64.cpp + create mode 100644 source/Plugins/Process/Linux/NativeRegisterContextLinux_loongarch64.h + create mode 100644 source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp + create mode 100644 source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.h + create mode 100644 source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.cpp + create mode 100644 source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h + create mode 100644 source/Plugins/Process/Utility/RegisterInfos_loongarch64.h + create mode 100644 source/Plugins/Process/Utility/lldb-loongarch-register-enums.h + create mode 100644 source/Utility/LoongArch_DWARF_Registers.h + create mode 100644 test/Shell/ObjectFile/ELF/loongarch-arch.yaml + +diff --git a/lldb/source/Plugins/Instruction/LoongArch/CMakeLists.txt b/lldb/source/Plugins/Instruction/LoongArch/CMakeLists.txt +new file mode 100644 +index 0000000..7ff87b6 +--- /dev/null ++++ b/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 ++ ) +\ No newline at end of file +diff --git a/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp b/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp +new file mode 100644 +index 0000000..5223bdb +--- /dev/null ++++ b/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.cpp +@@ -0,0 +1,545 @@ ++//===---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 ++ ++#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/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 for other instruction. ++ static EmulateInstructionLoongArch::Opcode g_opcodes[] = { ++ {0xfc000000, 0x40000000, &EmulateInstructionLoongArch::EmulateBEQZ, ++ "beqz rj, offs21"}, ++ {0xfc000000, 0x44000000, &EmulateInstructionLoongArch::EmulateBNEZ, ++ "bnez rj, offs21"}, ++ {0xfc000300, 0x48000000, &EmulateInstructionLoongArch::EmulateBCEQZ, ++ "bceqz cj, offs21"}, ++ {0xfc000300, 0x48000100, &EmulateInstructionLoongArch::EmulateBCNEZ, ++ "bcnez cj, offs21"}, ++ {0xfc000000, 0x4c000000, &EmulateInstructionLoongArch::EmulateJIRL, ++ "jirl rd, rj, offs16"}, ++ {0xfc000000, 0x50000000, &EmulateInstructionLoongArch::EmulateB, ++ " b offs26"}, ++ {0xfc000000, 0x54000000, &EmulateInstructionLoongArch::EmulateBL, ++ "bl offs26"}, ++ {0xfc000000, 0x58000000, &EmulateInstructionLoongArch::EmulateBEQ, ++ "beq rj, rd, offs16"}, ++ {0xfc000000, 0x5c000000, &EmulateInstructionLoongArch::EmulateBNE, ++ "bne rj, rd, offs16"}, ++ {0xfc000000, 0x60000000, &EmulateInstructionLoongArch::EmulateBLT, ++ "blt rj, rd, offs16"}, ++ {0xfc000000, 0x64000000, &EmulateInstructionLoongArch::EmulateBGE, ++ "bge rj, rd, offs16"}, ++ {0xfc000000, 0x68000000, &EmulateInstructionLoongArch::EmulateBLTU, ++ "bltu rj, rd, offs16"}, ++ {0xfc000000, 0x6c000000, &EmulateInstructionLoongArch::EmulateBGEU, ++ "bgeu rj, rd, offs16"}, ++ {0x00000000, 0x00000000, &EmulateInstructionLoongArch::EmulateNonJMP, ++ "NonJMP"}}; ++ static const size_t num_loongarch_opcodes = llvm::array_lengthof(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::TestExecute(uint32_t inst) { ++ Opcode *opcode_data = GetOpcodeForInstruction(inst); ++ if (!opcode_data) ++ return false; ++ // Call the Emulate... function. ++ if (!(this->*opcode_data->callback)(inst)) ++ return false; ++ return true; ++} ++ ++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); ++} ++ ++bool ++EmulateInstructionLoongArch::GetRegisterInfo(lldb::RegisterKind reg_kind, ++ uint32_t reg_index, ++ RegisterInfo ®_info) { ++ 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: ++ return false; ++ } ++ } ++ ++ 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 false; ++ ++ reg_info = array[reg_index]; ++ return true; ++} ++ ++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); ++} ++ ++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::EmulateBEQZ(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBEQZ64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateBNEZ(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBNEZ64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateBCEQZ(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBCEQZ64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateBCNEZ(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBCNEZ64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateJIRL(uint32_t inst) { ++ return IsLoongArch64() ? EmulateJIRL64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateB(uint32_t inst) { ++ return IsLoongArch64() ? EmulateB64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateBL(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBL64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateBEQ(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBEQ64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateBNE(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBNE64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateBLT(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBLT64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateBGE(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBGE64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateBLTU(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBLTU64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateBGEU(uint32_t inst) { ++ return IsLoongArch64() ? EmulateBGEU64(inst) : false; ++} ++ ++bool EmulateInstructionLoongArch::EmulateNonJMP(uint32_t inst) { return false; } ++ ++// beqz rj, offs21 ++// if GR[rj] == 0: ++// PC = PC + SignExtend({offs21, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBEQZ64(uint32_t inst) { ++ bool success = false; ++ uint32_t rj = Bits32(inst, 9, 5); ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ uint32_t offs21 = Bits32(inst, 25, 10) + (Bits32(inst, 4, 0) << 16); ++ uint64_t rj_val = ReadRegisterUnsigned(eRegisterKindLLDB, rj, 0, &success); ++ if (!success) ++ return false; ++ if (rj_val == 0) { ++ uint64_t next_pc = pc + llvm::SignExtend64<23>(offs21 << 2); ++ return WritePC(next_pc); ++ } else ++ return WritePC(pc + 4); ++} ++ ++// bnez rj, offs21 ++// if GR[rj] != 0: ++// PC = PC + SignExtend({offs21, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBNEZ64(uint32_t inst) { ++ bool success = false; ++ uint32_t rj = Bits32(inst, 9, 5); ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ uint32_t offs21 = Bits32(inst, 25, 10) + (Bits32(inst, 4, 0) << 16); ++ uint64_t rj_val = ReadRegisterUnsigned(eRegisterKindLLDB, rj, 0, &success); ++ if (!success) ++ return false; ++ if (rj_val != 0) { ++ uint64_t next_pc = pc + llvm::SignExtend64<23>(offs21 << 2); ++ return WritePC(next_pc); ++ } else ++ return WritePC(pc + 4); ++} ++ ++// bceqz cj, offs21 ++// if CFR[cj] == 0: ++// PC = PC + SignExtend({offs21, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBCEQZ64(uint32_t inst) { ++ bool success = false; ++ uint32_t cj = Bits32(inst, 7, 5) + fpr_fcc0_loongarch; ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ uint32_t offs21 = Bits32(inst, 25, 10) + (Bits32(inst, 4, 0) << 16); ++ uint8_t cj_val = ++ (uint8_t)ReadRegisterUnsigned(eRegisterKindLLDB, cj, 0, &success); ++ if (!success) ++ return false; ++ if (cj_val == 0) { ++ uint64_t next_pc = pc + llvm::SignExtend64<23>(offs21 << 2); ++ return WritePC(next_pc); ++ } else ++ return WritePC(pc + 4); ++ return false; ++} ++ ++// bcnez cj, offs21 ++// if CFR[cj] != 0: ++// PC = PC + SignExtend({offs21, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBCNEZ64(uint32_t inst) { ++ bool success = false; ++ uint32_t cj = Bits32(inst, 7, 5) + fpr_fcc0_loongarch; ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ uint32_t offs21 = Bits32(inst, 25, 10) + (Bits32(inst, 4, 0) << 16); ++ uint8_t cj_val = ++ (uint8_t)ReadRegisterUnsigned(eRegisterKindLLDB, cj, 0, &success); ++ if (!success) ++ return false; ++ if (cj_val != 0) { ++ uint64_t next_pc = pc + llvm::SignExtend64<23>(offs21 << 2); ++ return WritePC(next_pc); ++ } else ++ return WritePC(pc + 4); ++ return false; ++} ++ ++// jirl rd, rj, offs16 ++// GR[rd] = PC + 4 ++// PC = GR[rj] + SignExtend({offs16, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateJIRL64(uint32_t inst) { ++ uint32_t rj = Bits32(inst, 9, 5); ++ uint32_t rd = Bits32(inst, 4, 0); ++ bool success = false; ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ EmulateInstruction::Context ctx; ++ if (!WriteRegisterUnsigned(ctx, eRegisterKindLLDB, rd, pc + 4)) ++ return false; ++ uint64_t rj_val = ReadRegisterUnsigned(eRegisterKindLLDB, rj, 0, &success); ++ if (!success) ++ return false; ++ uint64_t next_pc = rj_val + llvm::SignExtend64<18>(Bits32(inst, 25, 10) << 2); ++ return WritePC(next_pc); ++} ++ ++// b offs26 ++// PC = PC + SignExtend({offs26, 2' b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateB64(uint32_t inst) { ++ bool success = false; ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ uint32_t offs26 = Bits32(inst, 25, 10) + (Bits32(inst, 9, 0) << 16); ++ uint64_t next_pc = pc + llvm::SignExtend64<28>(offs26 << 2); ++ return WritePC(next_pc); ++} ++ ++// bl offs26 ++// GR[1] = PC + 4 ++// PC = PC + SignExtend({offs26, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBL64(uint32_t inst) { ++ bool success = false; ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ EmulateInstruction::Context ctx; ++ if (!WriteRegisterUnsigned(ctx, eRegisterKindLLDB, gpr_r1_loongarch, pc + 4)) ++ return false; ++ uint32_t offs26 = Bits32(inst, 25, 10) + (Bits32(inst, 9, 0) << 16); ++ uint64_t next_pc = pc + llvm::SignExtend64<28>(offs26 << 2); ++ return WritePC(next_pc); ++} ++ ++// beq rj, rd, offs16 ++// if GR[rj] == GR[rd]: ++// PC = PC + SignExtend({offs16, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBEQ64(uint32_t inst) { ++ bool success = false; ++ uint32_t rj = Bits32(inst, 9, 5); ++ uint32_t rd = Bits32(inst, 4, 0); ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ uint64_t rj_val = ReadRegisterUnsigned(eRegisterKindLLDB, rj, 0, &success); ++ if (!success) ++ return false; ++ uint64_t rd_val = ReadRegisterUnsigned(eRegisterKindLLDB, rd, 0, &success); ++ if (!success) ++ return false; ++ if (rj_val == rd_val) { ++ uint64_t next_pc = pc + llvm::SignExtend64<18>(Bits32(inst, 25, 10) << 2); ++ return WritePC(next_pc); ++ } else ++ return WritePC(pc + 4); ++} ++ ++// bne rj, rd, offs16 ++// if GR[rj] != GR[rd]: ++// PC = PC + SignExtend({offs16, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBNE64(uint32_t inst) { ++ bool success = false; ++ uint32_t rj = Bits32(inst, 9, 5); ++ uint32_t rd = Bits32(inst, 4, 0); ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ uint64_t rj_val = ReadRegisterUnsigned(eRegisterKindLLDB, rj, 0, &success); ++ if (!success) ++ return false; ++ uint64_t rd_val = ReadRegisterUnsigned(eRegisterKindLLDB, rd, 0, &success); ++ if (!success) ++ return false; ++ if (rj_val != rd_val) { ++ uint64_t next_pc = pc + llvm::SignExtend64<18>(Bits32(inst, 25, 10) << 2); ++ return WritePC(next_pc); ++ } else ++ return WritePC(pc + 4); ++} ++ ++// blt rj, rd, offs16 ++// if signed(GR[rj]) < signed(GR[rd]): ++// PC = PC + SignExtend({offs16, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBLT64(uint32_t inst) { ++ bool success = false; ++ uint32_t rj = Bits32(inst, 9, 5); ++ uint32_t rd = Bits32(inst, 4, 0); ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ int64_t rj_val = ++ (int64_t)ReadRegisterUnsigned(eRegisterKindLLDB, rj, 0, &success); ++ if (!success) ++ return false; ++ int64_t rd_val = ++ (int64_t)ReadRegisterUnsigned(eRegisterKindLLDB, rd, 0, &success); ++ if (!success) ++ return false; ++ if (rj_val < rd_val) { ++ uint64_t next_pc = pc + llvm::SignExtend64<18>(Bits32(inst, 25, 10) << 2); ++ return WritePC(next_pc); ++ } else ++ return WritePC(pc + 4); ++} ++ ++// bge rj, rd, offs16 ++// if signed(GR[rj]) >= signed(GR[rd]): ++// PC = PC + SignExtend({offs16, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBGE64(uint32_t inst) { ++ bool success = false; ++ uint32_t rj = Bits32(inst, 9, 5); ++ uint32_t rd = Bits32(inst, 4, 0); ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ int64_t rj_val = ++ (int64_t)ReadRegisterUnsigned(eRegisterKindLLDB, rj, 0, &success); ++ if (!success) ++ return false; ++ int64_t rd_val = ++ (int64_t)ReadRegisterUnsigned(eRegisterKindLLDB, rd, 0, &success); ++ if (!success) ++ return false; ++ if (rj_val >= rd_val) { ++ uint64_t next_pc = pc + llvm::SignExtend64<18>(Bits32(inst, 25, 10) << 2); ++ return WritePC(next_pc); ++ } else ++ return WritePC(pc + 4); ++} ++ ++// bltu rj, rd, offs16 ++// if unsigned(GR[rj]) < unsigned(GR[rd]): ++// PC = PC + SignExtend({offs16, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBLTU64(uint32_t inst) { ++ bool success = false; ++ uint32_t rj = Bits32(inst, 9, 5); ++ uint32_t rd = Bits32(inst, 4, 0); ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ uint64_t rj_val = ReadRegisterUnsigned(eRegisterKindLLDB, rj, 0, &success); ++ if (!success) ++ return false; ++ uint64_t rd_val = ReadRegisterUnsigned(eRegisterKindLLDB, rd, 0, &success); ++ if (!success) ++ return false; ++ if (rj_val < rd_val) { ++ uint64_t next_pc = pc + llvm::SignExtend64<18>(Bits32(inst, 25, 10) << 2); ++ return WritePC(next_pc); ++ } else ++ return WritePC(pc + 4); ++} ++ ++// bgeu rj, rd, offs16 ++// if unsigned(GR[rj]) >= unsigned(GR[rd]): ++// PC = PC + SignExtend({offs16, 2'b0}, GRLEN) ++bool EmulateInstructionLoongArch::EmulateBGEU64(uint32_t inst) { ++ bool success = false; ++ uint32_t rj = Bits32(inst, 9, 5); ++ uint32_t rd = Bits32(inst, 4, 0); ++ uint64_t pc = ReadPC(&success); ++ if (!success) ++ return false; ++ uint64_t rj_val = ReadRegisterUnsigned(eRegisterKindLLDB, rj, 0, &success); ++ if (!success) ++ return false; ++ uint64_t rd_val = ReadRegisterUnsigned(eRegisterKindLLDB, rd, 0, &success); ++ if (!success) ++ return false; ++ if (rj_val >= rd_val) { ++ uint64_t next_pc = pc + llvm::SignExtend64<18>(Bits32(inst, 25, 10) << 2); ++ return WritePC(next_pc); ++ } else ++ return WritePC(pc + 4); ++} ++ ++} // namespace lldb_private +\ No newline at end of file +diff --git a/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h b/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h +new file mode 100644 +index 0000000..873022f +--- /dev/null ++++ b/lldb/source/Plugins/Instruction/LoongArch/EmulateInstructionLoongArch.h +@@ -0,0 +1,112 @@ ++//===---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/Status.h" ++ ++namespace lldb_private { ++ ++class EmulateInstructionLoongArch : public EmulateInstruction { ++public: ++ static lldb_private::ConstString GetPluginNameStatic() { ++ ConstString g_plugin_name("lldb.emulate-instruction.LoongArch"); ++ return g_plugin_name; ++ } ++ ++ static const char * 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); ++ ++ uint32_t GetPluginVersion() override { return 1; } ++ ++ static void Initialize(); ++ ++ static void Terminate(); ++ ++public: ++ EmulateInstructionLoongArch(const lldb_private::ArchSpec &arch) ++ : EmulateInstruction(arch) { ++ m_arch_subtype = arch.GetMachine(); ++ } ++ ++ lldb_private::ConstString 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; ++ ++ bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num, ++ lldb_private::RegisterInfo ®_info) override; ++ lldb::addr_t ReadPC(bool *success); ++ bool WritePC(lldb::addr_t pc); ++ bool IsLoongArch64() { return m_arch_subtype == llvm::Triple::loongarch64; } ++ bool TestExecute(uint32_t inst); ++ ++private: ++ struct Opcode { ++ uint32_t mask; ++ uint32_t value; ++ bool (EmulateInstructionLoongArch::*callback)(uint32_t opcode); ++ const char *name; ++ }; ++ ++ llvm::Triple::ArchType m_arch_subtype; ++ Opcode *GetOpcodeForInstruction(uint32_t inst); ++ ++ bool EmulateBEQZ(uint32_t inst); ++ bool EmulateBNEZ(uint32_t inst); ++ bool EmulateBCEQZ(uint32_t inst); ++ bool EmulateBCNEZ(uint32_t inst); ++ bool EmulateJIRL(uint32_t inst); ++ bool EmulateB(uint32_t inst); ++ bool EmulateBL(uint32_t inst); ++ bool EmulateBEQ(uint32_t inst); ++ bool EmulateBNE(uint32_t inst); ++ bool EmulateBLT(uint32_t inst); ++ bool EmulateBGE(uint32_t inst); ++ bool EmulateBLTU(uint32_t inst); ++ bool EmulateBGEU(uint32_t inst); ++ bool EmulateNonJMP(uint32_t inst); ++ ++ bool EmulateBEQZ64(uint32_t inst); ++ bool EmulateBNEZ64(uint32_t inst); ++ bool EmulateBCEQZ64(uint32_t inst); ++ bool EmulateBCNEZ64(uint32_t inst); ++ bool EmulateJIRL64(uint32_t inst); ++ bool EmulateB64(uint32_t inst); ++ bool EmulateBL64(uint32_t inst); ++ bool EmulateBEQ64(uint32_t inst); ++ bool EmulateBNE64(uint32_t inst); ++ bool EmulateBLT64(uint32_t inst); ++ bool EmulateBGE64(uint32_t inst); ++ bool EmulateBLTU64(uint32_t inst); ++ bool EmulateBGEU64(uint32_t inst); ++}; ++ ++} // namespace lldb_private ++ ++#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_LOONGARCH_EMULATEINSTRUCTIONLOONGARCH_H +\ No newline at end of file +diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_loongarch64.cpp b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_loongarch64.cpp +new file mode 100644 +index 0000000..4f62f9b +--- /dev/null ++++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_loongarch64.cpp +@@ -0,0 +1,328 @@ ++//===-- NativeRegisterContextLinux_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 ++// ++//===----------------------------------------------------------------------===// ++ ++#if defined(__loongarch__) && __loongarch_grlen == 64 ++ ++#include "NativeRegisterContextLinux_loongarch64.h" ++ ++#include "lldb/Host/HostInfo.h" ++#include "lldb/Utility/DataBufferHeap.h" ++#include "lldb/Utility/Log.h" ++#include "lldb/Utility/RegisterValue.h" ++#include "lldb/Utility/Status.h" ++ ++#include "Plugins/Process/Linux/NativeProcessLinux.h" ++#include "Plugins/Process/Linux/Procfs.h" ++#include "Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h" ++#include "Plugins/Process/Utility/lldb-loongarch-register-enums.h" ++ ++// NT_PRSTATUS and NT_FPREGSET definition ++#include ++// struct iovec definition ++#include ++ ++#define REG_CONTEXT_SIZE (GetGPRSize() + GetFPRSize()) ++ ++using namespace lldb; ++using namespace lldb_private; ++using namespace lldb_private::process_linux; ++ ++std::unique_ptr ++NativeRegisterContextLinux::CreateHostNativeRegisterContextLinux( ++ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) { ++ switch (target_arch.GetMachine()) { ++ case llvm::Triple::loongarch64: { ++ return std::make_unique( ++ target_arch, native_thread); ++ } ++ default: ++ llvm_unreachable("have no register context for architecture"); ++ } ++} ++ ++NativeRegisterContextLinux_loongarch64::NativeRegisterContextLinux_loongarch64( ++ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) ++ : NativeRegisterContextRegisterInfo(native_thread, ++ new RegisterInfoPOSIX_loongarch64(target_arch)) { ++ ::memset(&m_fpr, 0, sizeof(m_fpr)); ++ ::memset(&m_gpr, 0, sizeof(m_gpr)); ++ ++ m_gpr_is_valid = false; ++ m_fpu_is_valid = false; ++} ++ ++const RegisterInfoPOSIX_loongarch64 & ++NativeRegisterContextLinux_loongarch64::GetRegisterInfo() const { ++ return static_cast( ++ NativeRegisterContextRegisterInfo::GetRegisterInfoInterface()); ++} ++ ++uint32_t NativeRegisterContextLinux_loongarch64::GetRegisterSetCount() const { ++ return GetRegisterInfo().GetRegisterSetCount(); ++} ++ ++const RegisterSet *NativeRegisterContextLinux_loongarch64::GetRegisterSet( ++ uint32_t set_index) const { ++ return GetRegisterInfo().GetRegisterSet(set_index); ++} ++ ++uint32_t NativeRegisterContextLinux_loongarch64::GetUserRegisterCount() const { ++ uint32_t count = 0; ++ for (uint32_t set_index = 0; set_index < GetRegisterSetCount(); ++set_index) ++ count += GetRegisterSet(set_index)->num_registers; ++ return count; ++} ++ ++Status NativeRegisterContextLinux_loongarch64::ReadRegister( ++ const RegisterInfo *reg_info, RegisterValue ®_value) { ++ Status error; ++ ++ if (!reg_info) { ++ error.SetErrorString("reg_info NULL"); ++ return error; ++ } ++ ++ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; ++ ++ if (reg == LLDB_INVALID_REGNUM) ++ return Status("no lldb regnum for %s", reg_info && reg_info->name ++ ? reg_info->name ++ : ""); ++ ++ uint8_t *src = nullptr; ++ uint32_t offset = LLDB_INVALID_INDEX32; ++ ++ if (IsGPR(reg)) { ++ error = ReadGPR(); ++ if (error.Fail()) ++ return error; ++ ++ offset = reg_info->byte_offset; ++ assert(offset < GetGPRSize()); ++ src = (uint8_t *)GetGPRBuffer() + offset; ++ ++ } else if (IsFPR(reg)) { ++ error = ReadFPR(); ++ if (error.Fail()) ++ return error; ++ ++ offset = CalculateFprOffset(reg_info); ++ assert(offset < GetFPRSize()); ++ src = (uint8_t *)GetFPRBuffer() + offset; ++ } else ++ return Status("failed - register wasn't recognized to be a GPR or an FPR, " ++ "write strategy unknown"); ++ ++ reg_value.SetFromMemoryData(reg_info, src, reg_info->byte_size, ++ eByteOrderLittle, error); ++ ++ return error; ++} ++ ++Status NativeRegisterContextLinux_loongarch64::WriteRegister( ++ const RegisterInfo *reg_info, const RegisterValue ®_value) { ++ Status error; ++ ++ if (!reg_info) ++ return Status("reg_info NULL"); ++ ++ const uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB]; ++ ++ if (reg == LLDB_INVALID_REGNUM) ++ return Status("no lldb regnum for %s", reg_info->name != nullptr ++ ? reg_info->name ++ : ""); ++ ++ uint8_t *dst = nullptr; ++ uint32_t offset = LLDB_INVALID_INDEX32; ++ ++ if (IsGPR(reg)) { ++ error = ReadGPR(); ++ if (error.Fail()) ++ return error; ++ ++ assert(reg_info->byte_offset < GetGPRSize()); ++ dst = (uint8_t *)GetGPRBuffer() + reg_info->byte_offset; ++ ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size); ++ ++ return WriteGPR(); ++ } else if (IsFPR(reg)) { ++ error = ReadFPR(); ++ if (error.Fail()) ++ return error; ++ ++ offset = CalculateFprOffset(reg_info); ++ assert(offset < GetFPRSize()); ++ dst = (uint8_t *)GetFPRBuffer() + offset; ++ ::memcpy(dst, reg_value.GetBytes(), reg_info->byte_size); ++ ++ return WriteFPR(); ++ } ++ ++ return Status("Failed to write register value"); ++} ++ ++Status NativeRegisterContextLinux_loongarch64::ReadAllRegisterValues( ++ lldb::DataBufferSP &data_sp) { ++ Status error; ++ ++ data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0)); ++ ++ error = ReadGPR(); ++ if (error.Fail()) ++ return error; ++ ++ error = ReadFPR(); ++ if (error.Fail()) ++ return error; ++ ++ uint8_t *dst = data_sp->GetBytes(); ++ ::memcpy(dst, GetGPRBuffer(), GetGPRSize()); ++ dst += GetGPRSize(); ++ ::memcpy(dst, GetFPRBuffer(), GetFPRSize()); ++ ++ return error; ++} ++ ++Status NativeRegisterContextLinux_loongarch64::WriteAllRegisterValues( ++ const lldb::DataBufferSP &data_sp) { ++ Status error; ++ ++ if (!data_sp) { ++ error.SetErrorStringWithFormat( ++ "NativeRegisterContextLinux_loongarch64::%s invalid data_sp provided", ++ __FUNCTION__); ++ return error; ++ } ++ ++ if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) { ++ error.SetErrorStringWithFormat( ++ "NativeRegisterContextLinux_loongarch64::%s data_sp contained " ++ "mismatched data size, expected %" PRIu64 ", actual %" PRIu64, ++ __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize()); ++ return error; ++ } ++ ++ const uint8_t *src = data_sp->GetBytes(); ++ if (src == nullptr) { ++ error.SetErrorStringWithFormat("NativeRegisterContextLinux_loongarch64::%s " ++ "DataBuffer::GetBytes() returned a null " ++ "pointer", ++ __FUNCTION__); ++ return error; ++ } ++ ::memcpy(GetGPRBuffer(), src, GetRegisterInfoInterface().GetGPRSize()); ++ ++ error = WriteGPR(); ++ if (error.Fail()) ++ return error; ++ ++ src += GetRegisterInfoInterface().GetGPRSize(); ++ ::memcpy(GetFPRBuffer(), src, GetFPRSize()); ++ ++ error = WriteFPR(); ++ if (error.Fail()) ++ return error; ++ ++ return error; ++} ++ ++bool NativeRegisterContextLinux_loongarch64::IsGPR(unsigned reg) const { ++ return GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) == ++ RegisterInfoPOSIX_loongarch64::GPRegSet; ++} ++ ++bool NativeRegisterContextLinux_loongarch64::IsFPR(unsigned reg) const { ++ return GetRegisterInfo().GetRegisterSetFromRegisterIndex(reg) == ++ RegisterInfoPOSIX_loongarch64::FPRegSet; ++} ++ ++Status NativeRegisterContextLinux_loongarch64::ReadGPR() { ++ Status error; ++ ++ if (m_gpr_is_valid) ++ return error; ++ ++ struct iovec ioVec; ++ ioVec.iov_base = GetGPRBuffer(); ++ ioVec.iov_len = GetGPRSize(); ++ ++ error = ReadRegisterSet(&ioVec, GetGPRSize(), NT_PRSTATUS); ++ ++ if (error.Success()) ++ m_gpr_is_valid = true; ++ ++ return error; ++} ++ ++Status NativeRegisterContextLinux_loongarch64::WriteGPR() { ++ Status error = ReadGPR(); ++ if (error.Fail()) ++ return error; ++ ++ struct iovec ioVec; ++ ioVec.iov_base = GetGPRBuffer(); ++ ioVec.iov_len = GetGPRSize(); ++ ++ m_gpr_is_valid = false; ++ ++ return WriteRegisterSet(&ioVec, GetGPRSize(), NT_PRSTATUS); ++} ++ ++Status NativeRegisterContextLinux_loongarch64::ReadFPR() { ++ Status error; ++ ++ if (m_fpu_is_valid) ++ return error; ++ ++ struct iovec ioVec; ++ ioVec.iov_base = GetFPRBuffer(); ++ ioVec.iov_len = GetFPRSize(); ++ ++ error = ReadRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET); ++ ++ if (error.Success()) ++ m_fpu_is_valid = true; ++ ++ return error; ++} ++ ++Status NativeRegisterContextLinux_loongarch64::WriteFPR() { ++ Status error = ReadFPR(); ++ if (error.Fail()) ++ return error; ++ ++ struct iovec ioVec; ++ ioVec.iov_base = GetFPRBuffer(); ++ ioVec.iov_len = GetFPRSize(); ++ ++ m_fpu_is_valid = false; ++ ++ return WriteRegisterSet(&ioVec, GetFPRSize(), NT_FPREGSET); ++} ++ ++void NativeRegisterContextLinux_loongarch64::InvalidateAllRegisters() { ++ m_gpr_is_valid = false; ++ m_fpu_is_valid = false; ++} ++ ++uint32_t NativeRegisterContextLinux_loongarch64::CalculateFprOffset( ++ const RegisterInfo *reg_info) const { ++ return reg_info->byte_offset - GetGPRSize(); ++} ++ ++std::vector ++NativeRegisterContextLinux_loongarch64::GetExpeditedRegisters( ++ ExpeditedRegs expType) const { ++ std::vector expedited_reg_nums = ++ NativeRegisterContext::GetExpeditedRegisters(expType); ++ ++ return expedited_reg_nums; ++} ++ ++#endif // defined(__loongarch__) && __loongarch_grlen == 64 +\ No newline at end of file +diff --git a/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_loongarch64.h b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_loongarch64.h +new file mode 100644 +index 0000000..10b2850 +--- /dev/null ++++ b/lldb/source/Plugins/Process/Linux/NativeRegisterContextLinux_loongarch64.h +@@ -0,0 +1,92 @@ ++//===-- NativeRegisterContextLinux_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 ++// ++//===----------------------------------------------------------------------===// ++ ++#if defined(__loongarch__) && __loongarch_grlen == 64 ++ ++#ifndef lldb_NativeRegisterContextLinux_loongarch64_h ++#define lldb_NativeRegisterContextLinux_loongarch64_h ++ ++#include "Plugins/Process/Linux/NativeRegisterContextLinux.h" ++#include "Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h" ++ ++#include ++ ++namespace lldb_private { ++namespace process_linux { ++ ++class NativeProcessLinux; ++ ++class NativeRegisterContextLinux_loongarch64 ++ : public NativeRegisterContextLinux { ++public: ++ NativeRegisterContextLinux_loongarch64( ++ const ArchSpec &target_arch, NativeThreadProtocol &native_thread); ++ ++ uint32_t GetRegisterSetCount() const override; ++ ++ uint32_t GetUserRegisterCount() const override; ++ ++ const RegisterSet *GetRegisterSet(uint32_t set_index) const override; ++ ++ Status ReadRegister(const RegisterInfo *reg_info, ++ RegisterValue ®_value) override; ++ ++ Status WriteRegister(const RegisterInfo *reg_info, ++ const RegisterValue ®_value) override; ++ ++ Status ReadAllRegisterValues(lldb::DataBufferSP &data_sp) override; ++ ++ Status WriteAllRegisterValues(const lldb::DataBufferSP &data_sp) override; ++ ++ void InvalidateAllRegisters() override; ++ ++ std::vector ++ GetExpeditedRegisters(ExpeditedRegs expType) const override; ++ ++ bool RegisterOffsetIsDynamic() const override { return true; } ++ ++protected: ++ Status ReadGPR() override; ++ ++ Status WriteGPR() override; ++ ++ Status ReadFPR() override; ++ ++ Status WriteFPR() override; ++ ++ void *GetGPRBuffer() override { return &m_gpr; } ++ ++ void *GetFPRBuffer() override { return &m_fpr; } ++ ++ size_t GetGPRSize() const override { return GetRegisterInfo().GetGPRSize(); } ++ ++ size_t GetFPRSize() override { return GetRegisterInfo().GetFPRSize(); } ++ ++private: ++ bool m_gpr_is_valid; ++ bool m_fpu_is_valid; ++ ++ RegisterInfoPOSIX_loongarch64::GPR m_gpr; ++ ++ RegisterInfoPOSIX_loongarch64::FPR m_fpr; ++ ++ bool IsGPR(unsigned reg) const; ++ ++ bool IsFPR(unsigned reg) const; ++ ++ uint32_t CalculateFprOffset(const RegisterInfo *reg_info) const; ++ ++ const RegisterInfoPOSIX_loongarch64 &GetRegisterInfo() const; ++}; ++ ++} // namespace process_linux ++} // namespace lldb_private ++ ++#endif // #ifndef lldb_NativeRegisterContextLinux_loongarch64_h ++ ++#endif // defined(__loongarch__) && __loongarch_grlen == 64 +\ No newline at end of file +diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp +new file mode 100644 +index 0000000..3ba7dae +--- /dev/null ++++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.cpp +@@ -0,0 +1,82 @@ ++//===-- RegisterContextPOSIX_loongarch64.cpp --------------------*- 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 ++// ++//===----------------------------------------------------------------------===// ++ ++#include "lldb/Target/Process.h" ++#include "lldb/Target/Target.h" ++#include "lldb/Target/Thread.h" ++#include "lldb/Utility/DataBufferHeap.h" ++#include "lldb/Utility/DataExtractor.h" ++#include "lldb/Utility/Endian.h" ++#include "lldb/Utility/RegisterValue.h" ++#include "lldb/Utility/Scalar.h" ++#include "llvm/Support/Compiler.h" ++ ++#include "RegisterContextPOSIX_loongarch64.h" ++ ++using namespace lldb; ++using namespace lldb_private; ++ ++RegisterContextPOSIX_loongarch64::RegisterContextPOSIX_loongarch64( ++ lldb_private::Thread &thread, ++ std::unique_ptr register_info) ++ : lldb_private::RegisterContext(thread, 0), ++ m_register_info_up(std::move(register_info)) {} ++ ++RegisterContextPOSIX_loongarch64::~RegisterContextPOSIX_loongarch64() = default; ++ ++void RegisterContextPOSIX_loongarch64::invalidate() {} ++ ++void RegisterContextPOSIX_loongarch64::InvalidateAllRegisters() {} ++ ++size_t RegisterContextPOSIX_loongarch64::GetRegisterCount() { ++ return m_register_info_up->GetRegisterCount(); ++} ++ ++size_t RegisterContextPOSIX_loongarch64::GetGPRSize() { ++ return m_register_info_up->GetGPRSize(); ++} ++ ++unsigned RegisterContextPOSIX_loongarch64::GetRegisterSize(unsigned int reg) { ++ return m_register_info_up->GetRegisterInfo()[reg].byte_size; ++} ++ ++unsigned RegisterContextPOSIX_loongarch64::GetRegisterOffset(unsigned int reg) { ++ return m_register_info_up->GetRegisterInfo()[reg].byte_offset; ++} ++ ++const lldb_private::RegisterInfo * ++RegisterContextPOSIX_loongarch64::GetRegisterInfoAtIndex(size_t reg) { ++ if (reg < GetRegisterCount()) ++ return &GetRegisterInfo()[reg]; ++ ++ return nullptr; ++} ++ ++size_t RegisterContextPOSIX_loongarch64::GetRegisterSetCount() { ++ return m_register_info_up->GetRegisterCount(); ++} ++ ++const lldb_private::RegisterSet * ++RegisterContextPOSIX_loongarch64::GetRegisterSet(size_t set) { ++ return m_register_info_up->GetRegisterSet(set); ++} ++ ++const lldb_private::RegisterInfo * ++RegisterContextPOSIX_loongarch64::GetRegisterInfo() { ++ return m_register_info_up->GetRegisterInfo(); ++} ++ ++bool RegisterContextPOSIX_loongarch64::IsGPR(unsigned int reg) { ++ return m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == ++ RegisterInfoPOSIX_loongarch64::GPRegSet; ++} ++ ++bool RegisterContextPOSIX_loongarch64::IsFPR(unsigned int reg) { ++ return m_register_info_up->GetRegisterSetFromRegisterIndex(reg) == ++ RegisterInfoPOSIX_loongarch64::FPRegSet; ++} +\ No newline at end of file +diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.h b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.h +new file mode 100644 +index 0000000..e0a58ff +--- /dev/null ++++ b/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_loongarch64.h +@@ -0,0 +1,63 @@ ++//===-- RegisterContextPOSIX_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_UTILITY_REGISTERCONTEXTPOSIX_LOONGARCH64_H ++#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_LOONGARCH64_H ++ ++#include "RegisterInfoInterface.h" ++#include "RegisterInfoPOSIX_loongarch64.h" ++#include "lldb-loongarch-register-enums.h" ++#include "lldb/Target/RegisterContext.h" ++#include "lldb/Utility/Log.h" ++ ++class RegisterContextPOSIX_loongarch64 : public lldb_private::RegisterContext { ++public: ++ RegisterContextPOSIX_loongarch64( ++ lldb_private::Thread &thread, ++ std::unique_ptr register_info); ++ ++ ~RegisterContextPOSIX_loongarch64() override; ++ ++ void invalidate(); ++ ++ void InvalidateAllRegisters() override; ++ ++ size_t GetRegisterCount() override; ++ ++ virtual size_t GetGPRSize(); ++ ++ virtual unsigned GetRegisterSize(unsigned reg); ++ ++ virtual unsigned GetRegisterOffset(unsigned reg); ++ ++ const lldb_private::RegisterInfo *GetRegisterInfoAtIndex(size_t reg) override; ++ ++ size_t GetRegisterSetCount() override; ++ ++ const lldb_private::RegisterSet *GetRegisterSet(size_t set) override; ++ ++protected: ++ std::unique_ptr m_register_info_up; ++ ++ virtual const lldb_private::RegisterInfo *GetRegisterInfo(); ++ ++ bool IsGPR(unsigned reg); ++ ++ bool IsFPR(unsigned reg); ++ ++ size_t GetFPRSize() { return sizeof(RegisterInfoPOSIX_loongarch64::FPR); } ++ ++ uint32_t GetRegNumFCSR() const { return fpr_fcsr_loongarch; } ++ ++ virtual bool ReadGPR() = 0; ++ virtual bool ReadFPR() = 0; ++ virtual bool WriteGPR() = 0; ++ virtual bool WriteFPR() = 0; ++}; ++ ++#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERCONTEXTPOSIX_LOONGARCH64_H +\ No newline at end of file +diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.cpp b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.cpp +new file mode 100644 +index 0000000..4d7545e +--- /dev/null ++++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.cpp +@@ -0,0 +1,158 @@ ++//===-- RegisterInfoPOSIX_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 ++#include ++#include ++ ++#include "lldb/lldb-defines.h" ++#include "llvm/Support/Compiler.h" ++ ++#include "RegisterInfoPOSIX_loongarch64.h" ++ ++#define GPR_OFFSET(idx) ((idx)*8 + 0) ++#define FPR_OFFSET(idx) ((idx)*8 + sizeof(RegisterInfoPOSIX_loongarch64::GPR)) ++#define FCC_OFFSET(idx) ((idx)*1 + 32 * 8 + sizeof(RegisterInfoPOSIX_loongarch64::GPR)) ++#define FCSR_OFFSET (8 * 1 + 32 * 8 + sizeof(RegisterInfoPOSIX_loongarch64::GPR)) ++ ++#define REG_CONTEXT_SIZE \ ++ (sizeof(RegisterInfoPOSIX_loongarch64::GPR) + \ ++ sizeof(RegisterInfoPOSIX_loongarch64::FPR)) ++ ++#define DECLARE_REGISTER_INFOS_LOONGARCH64_STRUCT ++#include "RegisterInfos_loongarch64.h" ++#undef DECLARE_REGISTER_INFOS_LOONGARCH64_STRUCT ++ ++const lldb_private::RegisterInfo * ++RegisterInfoPOSIX_loongarch64::GetRegisterInfoPtr( ++ const lldb_private::ArchSpec &target_arch) { ++ switch (target_arch.GetMachine()) { ++ case llvm::Triple::loongarch64: ++ return g_register_infos_loongarch64; ++ default: ++ assert(false && "Unhandled target architecture."); ++ return nullptr; ++ } ++} ++ ++uint32_t RegisterInfoPOSIX_loongarch64::GetRegisterInfoCount( ++ const lldb_private::ArchSpec &target_arch) { ++ switch (target_arch.GetMachine()) { ++ case llvm::Triple::loongarch64: ++ return static_cast(sizeof(g_register_infos_loongarch64) / ++ sizeof(g_register_infos_loongarch64[0])); ++ default: ++ assert(false && "Unhandled target architecture."); ++ return 0; ++ } ++} ++ ++// Number of register sets provided by this context. ++enum { ++ k_num_gpr_registers = gpr_last_loongarch - gpr_first_loongarch + 1, ++ k_num_fpr_registers = fpr_last_loongarch - fpr_first_loongarch + 1, ++ k_num_register_sets = 2 ++}; ++ ++// LoongArch64 general purpose registers. ++static const uint32_t g_gpr_regnums_loongarch64[] = { ++ gpr_r0_loongarch, gpr_r1_loongarch, gpr_r2_loongarch, ++ gpr_r3_loongarch, gpr_r4_loongarch, gpr_r5_loongarch, ++ gpr_r6_loongarch, gpr_r7_loongarch, gpr_r8_loongarch, ++ gpr_r9_loongarch, gpr_r10_loongarch, gpr_r11_loongarch, ++ gpr_r12_loongarch, gpr_r13_loongarch, gpr_r14_loongarch, ++ gpr_r15_loongarch, gpr_r16_loongarch, gpr_r17_loongarch, ++ gpr_r18_loongarch, gpr_r19_loongarch, gpr_r20_loongarch, ++ gpr_r21_loongarch, gpr_r22_loongarch, gpr_r23_loongarch, ++ gpr_r24_loongarch, gpr_r25_loongarch, gpr_r26_loongarch, ++ gpr_r27_loongarch, gpr_r28_loongarch, gpr_r29_loongarch, ++ gpr_r30_loongarch, gpr_r31_loongarch, gpr_orig_a0_loongarch, ++ gpr_pc_loongarch, gpr_badv_loongarch, gpr_reserved0_loongarch, ++ gpr_reserved1_loongarch, gpr_reserved2_loongarch, gpr_reserved3_loongarch, ++ gpr_reserved4_loongarch, gpr_reserved5_loongarch, gpr_reserved6_loongarch, ++ gpr_reserved7_loongarch, gpr_reserved8_loongarch, gpr_reserved9_loongarch, ++ LLDB_INVALID_REGNUM}; ++ ++static_assert(((sizeof g_gpr_regnums_loongarch64 / ++ sizeof g_gpr_regnums_loongarch64[0]) - ++ 1) == k_num_gpr_registers, ++ "g_gpr_regnums_loongarch64 has wrong number of register infos"); ++ ++// LoongArch64 floating point registers. ++static const uint32_t g_fpr_regnums_loongarch64[] = { ++ fpr_f0_loongarch, fpr_f1_loongarch, fpr_f2_loongarch, ++ fpr_f3_loongarch, fpr_f4_loongarch, fpr_f5_loongarch, ++ fpr_f6_loongarch, fpr_f7_loongarch, fpr_f8_loongarch, ++ fpr_f9_loongarch, fpr_f10_loongarch, fpr_f11_loongarch, ++ fpr_f12_loongarch, fpr_f13_loongarch, fpr_f14_loongarch, ++ fpr_f15_loongarch, fpr_f16_loongarch, fpr_f17_loongarch, ++ fpr_f18_loongarch, fpr_f19_loongarch, fpr_f20_loongarch, ++ fpr_f21_loongarch, fpr_f22_loongarch, fpr_f23_loongarch, ++ fpr_f24_loongarch, fpr_f25_loongarch, fpr_f26_loongarch, ++ fpr_f27_loongarch, fpr_f28_loongarch, fpr_f29_loongarch, ++ fpr_f30_loongarch, fpr_f31_loongarch, fpr_fcc0_loongarch, ++ fpr_fcc1_loongarch, fpr_fcc2_loongarch, fpr_fcc3_loongarch, ++ fpr_fcc4_loongarch, fpr_fcc5_loongarch, fpr_fcc6_loongarch, ++ fpr_fcc7_loongarch, fpr_fcsr_loongarch, LLDB_INVALID_REGNUM}; ++ ++static_assert(((sizeof g_fpr_regnums_loongarch64 / ++ sizeof g_fpr_regnums_loongarch64[0]) - ++ 1) == k_num_fpr_registers, ++ "g_fpr_regnums_loongarch64 has wrong number of register infos"); ++ ++// Register sets for LoongArch64. ++static const lldb_private::RegisterSet ++ g_reg_sets_loongarch64[k_num_register_sets] = { ++ {"General Purpose Registers", "gpr", k_num_gpr_registers, ++ g_gpr_regnums_loongarch64}, ++ {"Floating Point Registers", "fpr", k_num_fpr_registers, ++ g_fpr_regnums_loongarch64}}; ++ ++RegisterInfoPOSIX_loongarch64::RegisterInfoPOSIX_loongarch64( ++ const lldb_private::ArchSpec &target_arch) ++ : lldb_private::RegisterInfoAndSetInterface(target_arch), ++ m_register_info_p(GetRegisterInfoPtr(target_arch)), ++ m_register_info_count(GetRegisterInfoCount(target_arch)) {} ++ ++uint32_t RegisterInfoPOSIX_loongarch64::GetRegisterCount() const { ++ return m_register_info_count; ++} ++ ++size_t RegisterInfoPOSIX_loongarch64::GetGPRSize() const { ++ return sizeof(struct RegisterInfoPOSIX_loongarch64::GPR); ++} ++ ++size_t RegisterInfoPOSIX_loongarch64::GetFPRSize() const { ++ return sizeof(struct RegisterInfoPOSIX_loongarch64::FPR); ++} ++ ++const lldb_private::RegisterInfo * ++RegisterInfoPOSIX_loongarch64::GetRegisterInfo() const { ++ return m_register_info_p; ++} ++ ++size_t RegisterInfoPOSIX_loongarch64::GetRegisterSetCount() const { ++ return k_num_register_sets; ++} ++ ++size_t RegisterInfoPOSIX_loongarch64::GetRegisterSetFromRegisterIndex( ++ uint32_t reg_index) const { ++ // coverity[unsigned_compare] ++ if (reg_index >= gpr_first_loongarch && reg_index <= gpr_last_loongarch) ++ return GPRegSet; ++ if (reg_index >= fpr_first_loongarch && reg_index <= fpr_last_loongarch) ++ return FPRegSet; ++ return LLDB_INVALID_REGNUM; ++} ++ ++const lldb_private::RegisterSet * ++RegisterInfoPOSIX_loongarch64::GetRegisterSet(size_t set_index) const { ++ if (set_index < GetRegisterSetCount()) ++ return &g_reg_sets_loongarch64[set_index]; ++ return nullptr; ++} +\ No newline at end of file +diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h +new file mode 100644 +index 0000000..c435ce7 +--- /dev/null ++++ b/lldb/source/Plugins/Process/Utility/RegisterInfoPOSIX_loongarch64.h +@@ -0,0 +1,68 @@ ++//===-- RegisterInfoPOSIX_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_UTILITY_REGISTERINFOPOSIX_LOONGARCH64_H ++#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_LOONGARCH64_H ++ ++#include "RegisterInfoAndSetInterface.h" ++#include "lldb/Target/RegisterContext.h" ++#include "lldb/lldb-private.h" ++#include ++ ++class RegisterInfoPOSIX_loongarch64 ++ : public lldb_private::RegisterInfoAndSetInterface { ++public: ++ static const lldb_private::RegisterInfo * ++ GetRegisterInfoPtr(const lldb_private::ArchSpec &target_arch); ++ static uint32_t ++ GetRegisterInfoCount(const lldb_private::ArchSpec &target_arch); ++ ++public: ++ enum RegSetKind { ++ GPRegSet, ++ FPRegSet, ++ }; ++ ++ struct GPR { ++ uint64_t gpr[32]; ++ ++ uint64_t orig_a0; ++ uint64_t csr_era; ++ uint64_t csr_badv; ++ uint64_t reserved[10]; ++ }; ++ ++ struct FPR { ++ uint64_t fpr[32]; ++ uint64_t fcc; ++ uint32_t fcsr; ++ }; ++ ++ RegisterInfoPOSIX_loongarch64(const lldb_private::ArchSpec &target_arch); ++ ++ size_t GetGPRSize() const override; ++ ++ size_t GetFPRSize() const override; ++ ++ const lldb_private::RegisterInfo *GetRegisterInfo() const override; ++ ++ uint32_t GetRegisterCount() const override; ++ ++ const lldb_private::RegisterSet * ++ GetRegisterSet(size_t reg_set) const override; ++ ++ size_t GetRegisterSetCount() const override; ++ ++ size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override; ++ ++private: ++ const lldb_private::RegisterInfo *m_register_info_p; ++ uint32_t m_register_info_count; ++}; ++ ++#endif +\ No newline at end of file +diff --git a/lldb/source/Plugins/Process/Utility/RegisterInfos_loongarch64.h b/lldb/source/Plugins/Process/Utility/RegisterInfos_loongarch64.h +new file mode 100644 +index 0000000..8072672 +--- /dev/null ++++ b/lldb/source/Plugins/Process/Utility/RegisterInfos_loongarch64.h +@@ -0,0 +1,171 @@ ++//===-- RegisterInfos_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 ++// ++//===----------------------------------------------------------------------===// ++ ++#ifdef DECLARE_REGISTER_INFOS_LOONGARCH64_STRUCT ++ ++#include ++ ++#include "lldb/lldb-defines.h" ++#include "lldb/lldb-enumerations.h" ++#include "lldb/lldb-private.h" ++ ++#include "Utility/LoongArch_DWARF_Registers.h" ++#include "lldb-loongarch-register-enums.h" ++ ++#ifndef GPR_OFFSET ++#error GPR_OFFSET must be defined before including this header file ++#endif ++ ++#ifndef FPR_OFFSET ++#error FPR_OFFSET must be defined before including this header file ++#endif ++ ++using namespace loongarch_dwarf; ++ ++// clang-format off ++ ++// I suppose EHFrame and DWARF are the same. ++#define KIND_HELPER(reg, generic_kind) \ ++ { \ ++ loongarch_dwarf::dwarf_##reg, loongarch_dwarf::dwarf_##reg, generic_kind, \ ++ LLDB_INVALID_REGNUM, reg##_loongarch \ ++ } ++ ++// Generates register kinds array for generic purpose registers ++#define GPR64_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind) ++ ++// Generates register kinds array for floating point registers ++#define FPR64_KIND(reg, generic_kind) KIND_HELPER(reg, generic_kind) ++ ++// Defines a 64-bit general purpose register ++#define DEFINE_GPR64(reg, generic_kind) DEFINE_GPR64_ALT(reg, reg, generic_kind) ++#define DEFINE_GPR64_ALT(reg, alt, generic_kind) \ ++ { \ ++ #reg, #alt, 8, GPR_OFFSET(gpr_##reg##_loongarch - gpr_first_loongarch), \ ++ lldb::eEncodingUint, lldb::eFormatHex, \ ++ GPR64_KIND(gpr_##reg, generic_kind), nullptr, nullptr \ ++ } ++ ++// Defines a 64-bit floating point register ++#define DEFINE_FPR64(reg, generic_kind) DEFINE_FPR64_ALT(reg, reg, generic_kind) ++#define DEFINE_FPR64_ALT(reg, alt, generic_kind) \ ++ { \ ++ #reg, #alt, 8, FPR_OFFSET(fpr_##reg##_loongarch - fpr_first_loongarch), \ ++ lldb::eEncodingUint, lldb::eFormatHex, \ ++ FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr \ ++ } ++ ++#define DEFINE_FCC(reg, generic_kind) \ ++ { \ ++ #reg, nullptr, 1, FCC_OFFSET(fpr_##reg##_loongarch - fpr_fcc0_loongarch), \ ++ lldb::eEncodingUint, lldb::eFormatHex, \ ++ FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr \ ++ } ++ ++#define DEFINE_FCSR(reg, generic_kind) \ ++ { \ ++ #reg, nullptr, 4, FCSR_OFFSET, \ ++ lldb::eEncodingUint, lldb::eFormatHex, \ ++ FPR64_KIND(fpr_##reg, generic_kind), nullptr, nullptr \ ++ } ++ ++// clang-format on ++ ++static lldb_private::RegisterInfo g_register_infos_loongarch64[] = { ++ DEFINE_GPR64_ALT(r0, zero, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r1, ra, LLDB_REGNUM_GENERIC_RA), ++ DEFINE_GPR64_ALT(r2, tp, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r3, sp, LLDB_REGNUM_GENERIC_SP), ++ DEFINE_GPR64_ALT(r4, a0, LLDB_REGNUM_GENERIC_ARG1), ++ DEFINE_GPR64_ALT(r5, a1, LLDB_REGNUM_GENERIC_ARG2), ++ DEFINE_GPR64_ALT(r6, a2, LLDB_REGNUM_GENERIC_ARG3), ++ DEFINE_GPR64_ALT(r7, a3, LLDB_REGNUM_GENERIC_ARG4), ++ DEFINE_GPR64_ALT(r8, a4, LLDB_REGNUM_GENERIC_ARG5), ++ DEFINE_GPR64_ALT(r9, a5, LLDB_REGNUM_GENERIC_ARG6), ++ DEFINE_GPR64_ALT(r10, a6, LLDB_REGNUM_GENERIC_ARG7), ++ DEFINE_GPR64_ALT(r11, a7, LLDB_REGNUM_GENERIC_ARG8), ++ DEFINE_GPR64_ALT(r12, t0, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r13, t1, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r14, t2, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r15, t3, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r16, t4, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r17, t5, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r18, t6, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r19, t7, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r20, t8, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(r21, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r22, fp, LLDB_REGNUM_GENERIC_FP), ++ DEFINE_GPR64_ALT(r23, s0, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r24, s1, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r25, s2, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r26, s3, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r27, s4, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r28, s5, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r29, s6, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r30, s7, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64_ALT(r31, s8, LLDB_INVALID_REGNUM), ++ ++ DEFINE_GPR64(orig_a0, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(pc, LLDB_REGNUM_GENERIC_PC), ++ DEFINE_GPR64(badv, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(reserved0, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(reserved1, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(reserved2, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(reserved3, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(reserved4, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(reserved5, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(reserved6, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(reserved7, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(reserved8, LLDB_INVALID_REGNUM), ++ DEFINE_GPR64(reserved9, LLDB_INVALID_REGNUM), ++ ++ DEFINE_FPR64_ALT(f0, fa0, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f1, fa1, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f2, fa2, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f3, fa3, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f4, fa4, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f5, fa5, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f6, fa6, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f7, fa7, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f8, ft0, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f9, ft1, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f10, ft2, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f11, ft3, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f12, ft4, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f13, ft5, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f14, ft6, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f15, ft7, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f16, ft8, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f17, ft9, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f18, ft10, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f19, ft11, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f20, ft12, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f21, ft13, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f22, ft14, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f23, ft15, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f24, fs0, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f25, fs1, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f26, fs2, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f27, fs3, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f28, fs4, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f29, fs5, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f30, fs6, LLDB_INVALID_REGNUM), ++ DEFINE_FPR64_ALT(f31, fs7, LLDB_INVALID_REGNUM), ++ ++ DEFINE_FCC(fcc0, LLDB_INVALID_REGNUM), ++ DEFINE_FCC(fcc1, LLDB_INVALID_REGNUM), ++ DEFINE_FCC(fcc2, LLDB_INVALID_REGNUM), ++ DEFINE_FCC(fcc3, LLDB_INVALID_REGNUM), ++ DEFINE_FCC(fcc4, LLDB_INVALID_REGNUM), ++ DEFINE_FCC(fcc5, LLDB_INVALID_REGNUM), ++ DEFINE_FCC(fcc6, LLDB_INVALID_REGNUM), ++ DEFINE_FCC(fcc7, LLDB_INVALID_REGNUM), ++ DEFINE_FCSR(fcsr, LLDB_INVALID_REGNUM), ++}; ++ ++#endif // DECLARE_REGISTER_INFOS_LOONGARCH64_STRUCT +\ No newline at end of file +diff --git a/lldb/source/Plugins/Process/Utility/lldb-loongarch-register-enums.h b/lldb/source/Plugins/Process/Utility/lldb-loongarch-register-enums.h +new file mode 100644 +index 0000000..1403870 +--- /dev/null ++++ b/lldb/source/Plugins/Process/Utility/lldb-loongarch-register-enums.h +@@ -0,0 +1,178 @@ ++//===-- lldb-loongarch-register-enums.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_UTILITY_LLDB_LOONGARCH_REGISTER_ENUMS_H ++#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_LOONGARCH_REGISTER_ENUMS_H ++ ++// LLDB register codes (e.g. RegisterKind == eRegisterKindLLDB) ++ ++// Internal codes for all loongarch registers. ++enum { ++ // The same order as user_regs_struct in ++ // note: these enum values are used as byte_offset ++ gpr_first_loongarch = 0, ++ gpr_r0_loongarch = gpr_first_loongarch, ++ gpr_r1_loongarch, ++ gpr_r2_loongarch, ++ gpr_r3_loongarch, ++ gpr_r4_loongarch, ++ gpr_r5_loongarch, ++ gpr_r6_loongarch, ++ gpr_r7_loongarch, ++ gpr_r8_loongarch, ++ gpr_r9_loongarch, ++ gpr_r10_loongarch, ++ gpr_r11_loongarch, ++ gpr_r12_loongarch, ++ gpr_r13_loongarch, ++ gpr_r14_loongarch, ++ gpr_r15_loongarch, ++ gpr_r16_loongarch, ++ gpr_r17_loongarch, ++ gpr_r18_loongarch, ++ gpr_r19_loongarch, ++ gpr_r20_loongarch, ++ gpr_r21_loongarch, ++ gpr_r22_loongarch, ++ gpr_r23_loongarch, ++ gpr_r24_loongarch, ++ gpr_r25_loongarch, ++ gpr_r26_loongarch, ++ gpr_r27_loongarch, ++ gpr_r28_loongarch, ++ gpr_r29_loongarch, ++ gpr_r30_loongarch, ++ gpr_r31_loongarch, ++ gpr_orig_a0_loongarch, ++ gpr_pc_loongarch, ++ gpr_badv_loongarch, ++ gpr_reserved0_loongarch, ++ gpr_reserved1_loongarch, ++ gpr_reserved2_loongarch, ++ gpr_reserved3_loongarch, ++ gpr_reserved4_loongarch, ++ gpr_reserved5_loongarch, ++ gpr_reserved6_loongarch, ++ gpr_reserved7_loongarch, ++ gpr_reserved8_loongarch, ++ gpr_reserved9_loongarch, ++ gpr_last_loongarch = 44, ++ ++ gpr_zero_loongarch = gpr_r0_loongarch, ++ gpr_ra_loongarch = gpr_r1_loongarch, ++ gpr_tp_loongarch = gpr_r2_loongarch, ++ gpr_sp_loongarch = gpr_r3_loongarch, ++ gpr_a0_loongarch = gpr_r4_loongarch, ++ gpr_a1_loongarch = gpr_r5_loongarch, ++ gpr_a2_loongarch = gpr_r6_loongarch, ++ gpr_a3_loongarch = gpr_r7_loongarch, ++ gpr_a4_loongarch = gpr_r8_loongarch, ++ gpr_a5_loongarch = gpr_r9_loongarch, ++ gpr_a6_loongarch = gpr_r10_loongarch, ++ gpr_a7_loongarch = gpr_r11_loongarch, ++ gpr_t0_loongarch = gpr_r12_loongarch, ++ gpr_t1_loongarch = gpr_r13_loongarch, ++ gpr_t2_loongarch = gpr_r14_loongarch, ++ gpr_t3_loongarch = gpr_r15_loongarch, ++ gpr_t4_loongarch = gpr_r16_loongarch, ++ gpr_t5_loongarch = gpr_r17_loongarch, ++ gpr_t6_loongarch = gpr_r18_loongarch, ++ gpr_t7_loongarch = gpr_r19_loongarch, ++ gpr_t8_loongarch = gpr_r20_loongarch, ++ gpr_fp_loongarch = gpr_r22_loongarch, ++ gpr_s0_loongarch = gpr_r23_loongarch, ++ gpr_s1_loongarch = gpr_r24_loongarch, ++ gpr_s2_loongarch = gpr_r25_loongarch, ++ gpr_s3_loongarch = gpr_r26_loongarch, ++ gpr_s4_loongarch = gpr_r27_loongarch, ++ gpr_s5_loongarch = gpr_r28_loongarch, ++ gpr_s6_loongarch = gpr_r29_loongarch, ++ gpr_s7_loongarch = gpr_r30_loongarch, ++ gpr_s8_loongarch = gpr_r31_loongarch, ++ ++ fpr_first_loongarch = 45, ++ fpr_f0_loongarch = fpr_first_loongarch, ++ fpr_f1_loongarch, ++ fpr_f2_loongarch, ++ fpr_f3_loongarch, ++ fpr_f4_loongarch, ++ fpr_f5_loongarch, ++ fpr_f6_loongarch, ++ fpr_f7_loongarch, ++ fpr_f8_loongarch, ++ fpr_f9_loongarch, ++ fpr_f10_loongarch, ++ fpr_f11_loongarch, ++ fpr_f12_loongarch, ++ fpr_f13_loongarch, ++ fpr_f14_loongarch, ++ fpr_f15_loongarch, ++ fpr_f16_loongarch, ++ fpr_f17_loongarch, ++ fpr_f18_loongarch, ++ fpr_f19_loongarch, ++ fpr_f20_loongarch, ++ fpr_f21_loongarch, ++ fpr_f22_loongarch, ++ fpr_f23_loongarch, ++ fpr_f24_loongarch, ++ fpr_f25_loongarch, ++ fpr_f26_loongarch, ++ fpr_f27_loongarch, ++ fpr_f28_loongarch, ++ fpr_f29_loongarch, ++ fpr_f30_loongarch, ++ fpr_f31_loongarch, ++ fpr_fcc0_loongarch, ++ fpr_fcc1_loongarch, ++ fpr_fcc2_loongarch, ++ fpr_fcc3_loongarch, ++ fpr_fcc4_loongarch, ++ fpr_fcc5_loongarch, ++ fpr_fcc6_loongarch, ++ fpr_fcc7_loongarch, ++ fpr_fcsr_loongarch, ++ fpr_last_loongarch = fpr_fcsr_loongarch, ++ ++ fpr_fa0_loongarch = fpr_f0_loongarch, ++ fpr_fa1_loongarch = fpr_f1_loongarch, ++ fpr_fa2_loongarch = fpr_f2_loongarch, ++ fpr_fa3_loongarch = fpr_f3_loongarch, ++ fpr_fa4_loongarch = fpr_f4_loongarch, ++ fpr_fa5_loongarch = fpr_f5_loongarch, ++ fpr_fa6_loongarch = fpr_f6_loongarch, ++ fpr_fa7_loongarch = fpr_f7_loongarch, ++ fpr_ft0_loongarch = fpr_f8_loongarch, ++ fpr_ft1_loongarch = fpr_f9_loongarch, ++ fpr_ft2_loongarch = fpr_f10_loongarch, ++ fpr_ft3_loongarch = fpr_f11_loongarch, ++ fpr_ft4_loongarch = fpr_f12_loongarch, ++ fpr_ft5_loongarch = fpr_f13_loongarch, ++ fpr_ft6_loongarch = fpr_f14_loongarch, ++ fpr_ft7_loongarch = fpr_f15_loongarch, ++ fpr_ft8_loongarch = fpr_f16_loongarch, ++ fpr_ft9_loongarch = fpr_f17_loongarch, ++ fpr_ft10_loongarch = fpr_f18_loongarch, ++ fpr_ft11_loongarch = fpr_f19_loongarch, ++ fpr_ft12_loongarch = fpr_f20_loongarch, ++ fpr_ft13_loongarch = fpr_f21_loongarch, ++ fpr_ft14_loongarch = fpr_f22_loongarch, ++ fpr_ft15_loongarch = fpr_f23_loongarch, ++ fpr_fs0_loongarch = fpr_f24_loongarch, ++ fpr_fs1_loongarch = fpr_f25_loongarch, ++ fpr_fs2_loongarch = fpr_f26_loongarch, ++ fpr_fs3_loongarch = fpr_f27_loongarch, ++ fpr_fs4_loongarch = fpr_f28_loongarch, ++ fpr_fs5_loongarch = fpr_f29_loongarch, ++ fpr_fs6_loongarch = fpr_f30_loongarch, ++ fpr_fs7_loongarch = fpr_f31_loongarch, ++ ++ k_num_registers_loongarch ++}; ++ ++#endif // LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_LLDB_LOONGARCH_REGISTER_ENUMS_H +\ No newline at end of file +diff --git a/lldb/source/Utility/LoongArch_DWARF_Registers.h b/lldb/source/Utility/LoongArch_DWARF_Registers.h +new file mode 100644 +index 0000000..b7d2678 +--- /dev/null ++++ b/lldb/source/Utility/LoongArch_DWARF_Registers.h +@@ -0,0 +1,177 @@ ++//===-- LoongArch_DWARF_Registers.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_UTILITY_LOONGARCH_DWARF_REGISTERS_H ++#define LLDB_SOURCE_UTILITY_LOONGARCH_DWARF_REGISTERS_H ++ ++#include "lldb/lldb-private.h" ++ ++namespace loongarch_dwarf { ++ ++enum { ++ dwarf_gpr_r0 = 0, ++ dwarf_gpr_r1, ++ dwarf_gpr_r2, ++ dwarf_gpr_r3, ++ dwarf_gpr_r4, ++ dwarf_gpr_r5, ++ dwarf_gpr_r6, ++ dwarf_gpr_r7, ++ dwarf_gpr_r8, ++ dwarf_gpr_r9, ++ dwarf_gpr_r10, ++ dwarf_gpr_r11, ++ dwarf_gpr_r12, ++ dwarf_gpr_r13, ++ dwarf_gpr_r14, ++ dwarf_gpr_r15, ++ dwarf_gpr_r16, ++ dwarf_gpr_r17, ++ dwarf_gpr_r18, ++ dwarf_gpr_r19, ++ dwarf_gpr_r20, ++ dwarf_gpr_r21, ++ dwarf_gpr_r22, ++ dwarf_gpr_r23, ++ dwarf_gpr_r24, ++ dwarf_gpr_r25, ++ dwarf_gpr_r26, ++ dwarf_gpr_r27, ++ dwarf_gpr_r28, ++ dwarf_gpr_r29, ++ dwarf_gpr_r30, ++ dwarf_gpr_r31 = 31, ++ ++ dwarf_gpr_orig_a0, ++ dwarf_gpr_pc, ++ dwarf_gpr_badv, ++ ++ dwarf_gpr_reserved0 = 35, ++ dwarf_gpr_reserved1, ++ dwarf_gpr_reserved2, ++ dwarf_gpr_reserved3, ++ dwarf_gpr_reserved4, ++ dwarf_gpr_reserved5, ++ dwarf_gpr_reserved6, ++ dwarf_gpr_reserved7, ++ dwarf_gpr_reserved8, ++ dwarf_gpr_reserved9, ++ ++ dwarf_fpr_f0 = 45, ++ dwarf_fpr_f1, ++ dwarf_fpr_f2, ++ dwarf_fpr_f3, ++ dwarf_fpr_f4, ++ dwarf_fpr_f5, ++ dwarf_fpr_f6, ++ dwarf_fpr_f7, ++ dwarf_fpr_f8, ++ dwarf_fpr_f9, ++ dwarf_fpr_f10, ++ dwarf_fpr_f11, ++ dwarf_fpr_f12, ++ dwarf_fpr_f13, ++ dwarf_fpr_f14, ++ dwarf_fpr_f15, ++ dwarf_fpr_f16, ++ dwarf_fpr_f17, ++ dwarf_fpr_f18, ++ dwarf_fpr_f19, ++ dwarf_fpr_f20, ++ dwarf_fpr_f21, ++ dwarf_fpr_f22, ++ dwarf_fpr_f23, ++ dwarf_fpr_f24, ++ dwarf_fpr_f25, ++ dwarf_fpr_f26, ++ dwarf_fpr_f27, ++ dwarf_fpr_f28, ++ dwarf_fpr_f29, ++ dwarf_fpr_f30, ++ dwarf_fpr_f31 = 76, ++ ++ dwarf_fpr_fcc0, ++ dwarf_fpr_fcc1, ++ dwarf_fpr_fcc2, ++ dwarf_fpr_fcc3, ++ dwarf_fpr_fcc4, ++ dwarf_fpr_fcc5, ++ dwarf_fpr_fcc6, ++ dwarf_fpr_fcc7, ++ dwarf_fpr_fcsr, ++ ++ // register name alias ++ dwarf_gpr_zero = dwarf_gpr_r0, ++ dwarf_gpr_ra = dwarf_gpr_r1, ++ dwarf_gpr_tp = dwarf_gpr_r2, ++ dwarf_gpr_sp = dwarf_gpr_r3, ++ dwarf_gpr_a0 = dwarf_gpr_r4, ++ dwarf_gpr_a1 = dwarf_gpr_r5, ++ dwarf_gpr_a2 = dwarf_gpr_r6, ++ dwarf_gpr_a3 = dwarf_gpr_r7, ++ dwarf_gpr_a4 = dwarf_gpr_r8, ++ dwarf_gpr_a5 = dwarf_gpr_r9, ++ dwarf_gpr_a6 = dwarf_gpr_r10, ++ dwarf_gpr_a7 = dwarf_gpr_r11, ++ dwarf_gpr_t0 = dwarf_gpr_r12, ++ dwarf_gpr_t1 = dwarf_gpr_r13, ++ dwarf_gpr_t2 = dwarf_gpr_r14, ++ dwarf_gpr_t3 = dwarf_gpr_r15, ++ dwarf_gpr_t4 = dwarf_gpr_r16, ++ dwarf_gpr_t5 = dwarf_gpr_r17, ++ dwarf_gpr_t6 = dwarf_gpr_r18, ++ dwarf_gpr_t7 = dwarf_gpr_r19, ++ dwarf_gpr_t8 = dwarf_gpr_r20, ++ dwarf_gpr_fp = dwarf_gpr_r22, ++ dwarf_gpr_s0 = dwarf_gpr_r23, ++ dwarf_gpr_s1 = dwarf_gpr_r24, ++ dwarf_gpr_s2 = dwarf_gpr_r25, ++ dwarf_gpr_s3 = dwarf_gpr_r26, ++ dwarf_gpr_s4 = dwarf_gpr_r27, ++ dwarf_gpr_s5 = dwarf_gpr_r28, ++ dwarf_gpr_s6 = dwarf_gpr_r29, ++ dwarf_gpr_s7 = dwarf_gpr_r30, ++ dwarf_gpr_s8 = dwarf_gpr_r31, ++ ++ dwarf_fpr_fa0 = dwarf_fpr_f0, ++ dwarf_fpr_fa1 = dwarf_fpr_f1, ++ dwarf_fpr_fa2 = dwarf_fpr_f2, ++ dwarf_fpr_fa3 = dwarf_fpr_f3, ++ dwarf_fpr_fa4 = dwarf_fpr_f4, ++ dwarf_fpr_fa5 = dwarf_fpr_f5, ++ dwarf_fpr_fa6 = dwarf_fpr_f6, ++ dwarf_fpr_fa7 = dwarf_fpr_f7, ++ dwarf_fpr_ft0 = dwarf_fpr_f8, ++ dwarf_fpr_ft1 = dwarf_fpr_f9, ++ dwarf_fpr_ft2 = dwarf_fpr_f10, ++ dwarf_fpr_ft3 = dwarf_fpr_f11, ++ dwarf_fpr_ft4 = dwarf_fpr_f12, ++ dwarf_fpr_ft5 = dwarf_fpr_f13, ++ dwarf_fpr_ft6 = dwarf_fpr_f14, ++ dwarf_fpr_ft7 = dwarf_fpr_f15, ++ dwarf_fpr_ft8 = dwarf_fpr_f16, ++ dwarf_fpr_ft9 = dwarf_fpr_f17, ++ dwarf_fpr_ft10 = dwarf_fpr_f18, ++ dwarf_fpr_ft11 = dwarf_fpr_f19, ++ dwarf_fpr_ft12 = dwarf_fpr_f20, ++ dwarf_fpr_ft13 = dwarf_fpr_f21, ++ dwarf_fpr_ft14 = dwarf_fpr_f22, ++ dwarf_fpr_ft15 = dwarf_fpr_f23, ++ dwarf_fpr_fs0 = dwarf_fpr_f24, ++ dwarf_fpr_fs1 = dwarf_fpr_f25, ++ dwarf_fpr_fs2 = dwarf_fpr_f26, ++ dwarf_fpr_fs3 = dwarf_fpr_f27, ++ dwarf_fpr_fs4 = dwarf_fpr_f28, ++ dwarf_fpr_fs5 = dwarf_fpr_f29, ++ dwarf_fpr_fs6 = dwarf_fpr_f30, ++ dwarf_fpr_fs7 = dwarf_fpr_f31, ++}; ++ ++} // namespace loongarch_dwarf ++ ++#endif // LLDB_SOURCE_UTILITY_LOONGARCH_DWARF_REGISTERS_H +\ No newline at end of file +diff --git a/lldb/test/Shell/ObjectFile/ELF/loongarch-arch.yaml b/lldb/test/Shell/ObjectFile/ELF/loongarch-arch.yaml +new file mode 100644 +index 0000000..0d72ce0 +--- /dev/null ++++ b/lldb/test/Shell/ObjectFile/ELF/loongarch-arch.yaml +@@ -0,0 +1,24 @@ ++# RUN: yaml2obj --docnum=1 %s > %t32 ++# RUN: yaml2obj --docnum=2 %s > %t64 ++# RUN: lldb-test object-file %t32 | FileCheck --check-prefix=CHECK-LA32 %s ++# RUN: lldb-test object-file %t64 | FileCheck --check-prefix=CHECK-LA64 %s ++ ++# CHECK-LA32: Architecture: loongarch32-- ++ ++--- !ELF ++FileHeader: ++ Class: ELFCLASS32 ++ Data: ELFDATA2LSB ++ Type: ET_EXEC ++ Machine: EM_LOONGARCH ++... ++ ++# CHECK-LA64: Architecture: loongarch64-- ++ ++--- !ELF ++FileHeader: ++ Class: ELFCLASS64 ++ Data: ELFDATA2LSB ++ Type: ET_EXEC ++ Machine: EM_LOONGARCH ++... +\ No newline at end of file +-- +2.41.0 + diff --git a/lldb.spec b/lldb.spec index 3b9ce77..12d827d 100644 --- a/lldb.spec +++ b/lldb.spec @@ -1,6 +1,6 @@ Name: lldb Version: 12.0.1 -Release: 1 +Release: 2 Summary: Next generation high-performance debugger License: NCSA @@ -31,6 +31,9 @@ BuildRequires: gnupg2 Patch0: 0001-PATCH-lldb-Portable-asm-ptrace.h-include.patch Patch1: 0002-PATCH-lldb-Support-DWARF-5-DW_FORM_line_strp-used-by.patch +Patch1000: 1000-add-loongarch-support-upstream-modified.patch +Patch1001: 1001-add-loongarch-support-upstream-new.patch + %description LLDB is a next generation, high-performance debugger. It is built as a set of reusable components which highly leverage existing libraries in the @@ -128,6 +131,9 @@ rm -f %{buildroot}%{python3_sitearch}/six.* %{python3_sitearch}/lldb %changelog +* Wed Aug 30 2023 herengui - 12.0.1-2 +- add support for loongarch + * Thu Jan 06 2022 Chen Chen - 12.0.1-1 - upgrade lldb to 12.0.1 -- Gitee