From 37f44c128570a592f87b76f6df435cdf8680630c Mon Sep 17 00:00:00 2001 From: Xu Liangyu Date: Thu, 15 Aug 2024 05:14:46 +0800 Subject: [PATCH] [LoongArch64] Part-2: Add support for LoongArch64 under 'src/SOS' and some other files. (#4852) This PR mainly implement the src/SOS directory and some other files for LA64. With [Part-1](https://github.com/dotnet/diagnostics/pull/4835) and Part-2, some dotnet-sos cli can be executed, such as gcinfo/clrstack... --- CMakeLists.txt | 13 ++ .../ThreadService.cs | 6 + .../TargetFromFromDebuggerServices.cs | 1 + .../SOS.Hosting/CorDebugDataTargetWrapper.cs | 3 + src/SOS/SOS.Hosting/DataTargetWrapper.cs | 1 + src/SOS/SOS.Hosting/SOSHost.cs | 3 + src/SOS/Strike/CMakeLists.txt | 9 + src/SOS/Strike/clrma/thread.cpp | 10 ++ src/SOS/Strike/crosscontext.h | 51 ++++++ src/SOS/Strike/disasm.cpp | 12 ++ src/SOS/Strike/disasm.h | 86 +++++++++- src/SOS/Strike/disasmLOONGARCH64.cpp | 154 ++++++++++++++++++ src/SOS/Strike/exts.cpp | 8 + src/SOS/Strike/exts.h | 5 + src/SOS/Strike/platform/cordebugdatatarget.h | 2 + src/SOS/Strike/platform/datatarget.cpp | 2 +- src/SOS/Strike/strike.cpp | 20 ++- src/SOS/Strike/util.h | 2 +- src/SOS/extensions/hostcoreclr.cpp | 4 + src/SOS/lldbplugin/CMakeLists.txt | 7 + src/SOS/lldbplugin/services.cpp | 39 +++++ src/dbgshim/debugshim.cpp | 2 + 22 files changed, 436 insertions(+), 4 deletions(-) create mode 100644 src/SOS/Strike/disasmLOONGARCH64.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c93eba23c..a887a9525 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,6 +100,11 @@ elseif (CLR_CMAKE_HOST_ARCH_RISCV64) add_definitions(-DRISCV64) add_definitions(-D_WIN64) add_definitions(-DBIT64=1) +elseif (CLR_CMAKE_HOST_ARCH_LOONGARCH64) + add_definitions(-D_LOONGARCH64_) + add_definitions(-DLOONGARCH64) + add_definitions(-D_WIN64) + add_definitions(-DBIT64=1) else () clr_unknown_arch() endif () @@ -156,6 +161,14 @@ elseif (CLR_CMAKE_TARGET_ARCH_RISCV64) add_definitions(-DDBG_TARGET_64BIT=1) add_definitions(-DDBG_TARGET_WIN64=1) add_definitions(-DFEATURE_MULTIREG_RETURN) +elseif (CLR_CMAKE_TARGET_ARCH_LOONGARCH64) + add_definitions(-DDBG_TARGET_LOONGARCH64_UNIX) + add_definitions(-D_TARGET_LOONGARCH64_=1) + add_definitions(-D_TARGET_64BIT_=1) + add_definitions(-DDBG_TARGET_LOONGARCH64=1) + add_definitions(-DDBG_TARGET_64BIT=1) + add_definitions(-DDBG_TARGET_WIN64=1) + add_definitions(-DFEATURE_MULTIREG_RETURN) else () clr_unknown_arch() endif (CLR_CMAKE_TARGET_ARCH_AMD64) diff --git a/src/Microsoft.Diagnostics.DebugServices.Implementation/ThreadService.cs b/src/Microsoft.Diagnostics.DebugServices.Implementation/ThreadService.cs index de9149330..2d0a95cbe 100644 --- a/src/Microsoft.Diagnostics.DebugServices.Implementation/ThreadService.cs +++ b/src/Microsoft.Diagnostics.DebugServices.Implementation/ThreadService.cs @@ -59,6 +59,12 @@ namespace Microsoft.Diagnostics.DebugServices.Implementation contextType = typeof(ArmContext); break; + case (Architecture)6 /* Architecture.LoongArch64 */: + _contextSize = LoongArch64Context.Size; + _contextFlags = LoongArch64Context.ContextControl | LoongArch64Context.ContextInteger | LoongArch64Context.ContextFloatingPoint; + contextType = typeof(LoongArch64Context); + break; + case (Architecture)9 /* Architecture.RiscV64 */: _contextSize = RiscV64Context.Size; _contextFlags = RiscV64Context.ContextControl | RiscV64Context.ContextInteger | RiscV64Context.ContextFloatingPoint; diff --git a/src/SOS/SOS.Extensions/TargetFromFromDebuggerServices.cs b/src/SOS/SOS.Extensions/TargetFromFromDebuggerServices.cs index da99d05a5..aa8b37825 100644 --- a/src/SOS/SOS.Extensions/TargetFromFromDebuggerServices.cs +++ b/src/SOS/SOS.Extensions/TargetFromFromDebuggerServices.cs @@ -55,6 +55,7 @@ namespace SOS.Extensions IMAGE_FILE_MACHINE.ARMNT => Architecture.Arm, IMAGE_FILE_MACHINE.AMD64 => Architecture.X64, IMAGE_FILE_MACHINE.ARM64 => Architecture.Arm64, + IMAGE_FILE_MACHINE.LOONGARCH64 => (Architecture)6 /* Architecture.LoongArch64 */, IMAGE_FILE_MACHINE.RISCV64 => (Architecture)9 /* Architecture.RiscV64 */, _ => throw new PlatformNotSupportedException($"Machine type not supported: {type}"), }; diff --git a/src/SOS/SOS.Hosting/CorDebugDataTargetWrapper.cs b/src/SOS/SOS.Hosting/CorDebugDataTargetWrapper.cs index c46e8f159..a58f59211 100644 --- a/src/SOS/SOS.Hosting/CorDebugDataTargetWrapper.cs +++ b/src/SOS/SOS.Hosting/CorDebugDataTargetWrapper.cs @@ -107,6 +107,9 @@ namespace SOS.Hosting case Architecture.Arm64: platform = CorDebugPlatform.CORDB_PLATFORM_POSIX_ARM64; break; + case (Architecture)6 /* Architecture.LoongArch64 */: + platform = CorDebugPlatform.CORDB_PLATFORM_POSIX_LOONGARCH64; + break; case (Architecture)9 /* Architecture.RiscV64 */: platform = CorDebugPlatform.CORDB_PLATFORM_POSIX_RISCV64; break; diff --git a/src/SOS/SOS.Hosting/DataTargetWrapper.cs b/src/SOS/SOS.Hosting/DataTargetWrapper.cs index d3b86016b..659835540 100644 --- a/src/SOS/SOS.Hosting/DataTargetWrapper.cs +++ b/src/SOS/SOS.Hosting/DataTargetWrapper.cs @@ -112,6 +112,7 @@ namespace SOS.Hosting Architecture.X86 => IMAGE_FILE_MACHINE.I386, Architecture.Arm => IMAGE_FILE_MACHINE.ARMNT, Architecture.Arm64 => IMAGE_FILE_MACHINE.ARM64, + (Architecture)6 /* Architecture.LoongArch64 */ => IMAGE_FILE_MACHINE.LOONGARCH64, (Architecture)9 /* Architecture.RiscV64 */ => IMAGE_FILE_MACHINE.RISCV64, _ => IMAGE_FILE_MACHINE.UNKNOWN, }; diff --git a/src/SOS/SOS.Hosting/SOSHost.cs b/src/SOS/SOS.Hosting/SOSHost.cs index 345aa86a1..e78234871 100644 --- a/src/SOS/SOS.Hosting/SOSHost.cs +++ b/src/SOS/SOS.Hosting/SOSHost.cs @@ -179,6 +179,9 @@ namespace SOS.Hosting case Architecture.Arm64: *type = IMAGE_FILE_MACHINE.ARM64; break; + case (Architecture)6 /* Architecture.LoongArch64 */: + *type = IMAGE_FILE_MACHINE.LOONGARCH64; + break; case (Architecture)9 /* Architecture.RiscV64 */: *type = IMAGE_FILE_MACHINE.RISCV64; break; diff --git a/src/SOS/Strike/CMakeLists.txt b/src/SOS/Strike/CMakeLists.txt index bb68c99ba..ec2734747 100644 --- a/src/SOS/Strike/CMakeLists.txt +++ b/src/SOS/Strike/CMakeLists.txt @@ -69,6 +69,11 @@ elseif(CLR_CMAKE_HOST_ARCH_RISCV64) add_definitions(-D_TARGET_WIN64_=1) add_definitions(-DDBG_TARGET_64BIT) add_definitions(-DDBG_TARGET_WIN64=1) +elseif(CLR_CMAKE_HOST_ARCH_LOONGARCH64) + add_definitions(-DSOS_TARGET_LOONGARCH64=1) + add_definitions(-D_TARGET_WIN64_=1) + add_definitions(-DDBG_TARGET_64BIT) + add_definitions(-DDBG_TARGET_WIN64=1) endif() add_definitions(-DSTRIKE) @@ -229,6 +234,10 @@ elseif(CLR_CMAKE_HOST_ARCH_RISCV64) set(SOS_SOURCES_ARCH disasmRISCV64.cpp ) +elseif(CLR_CMAKE_HOST_ARCH_LOONGARCH64) + set(SOS_SOURCES_ARCH + disasmLOONGARCH64.cpp + ) endif() list(APPEND SOS_SOURCES ${SOS_SOURCES_ARCH}) diff --git a/src/SOS/Strike/clrma/thread.cpp b/src/SOS/Strike/clrma/thread.cpp index c2d1d373e..5ae175f3d 100644 --- a/src/SOS/Strike/clrma/thread.cpp +++ b/src/SOS/Strike/clrma/thread.cpp @@ -464,6 +464,11 @@ ClrmaThread::GetFrameLocation( contextFlags = 0x01000001; break; + case IMAGE_FILE_MACHINE_LOONGARCH64: + contextSize = sizeof(LOONGARCH64_CONTEXT); + contextFlags = 0x00800001; + break; + default: TraceError("GetFrameLocation: Invalid processor type %04x\n", processorType); return E_FAIL; @@ -509,6 +514,11 @@ ClrmaThread::GetFrameLocation( *ip = context.RiscV64Context.Pc; *sp = context.RiscV64Context.Sp; break; + + case IMAGE_FILE_MACHINE_LOONGARCH64: + *ip = context.LoongArch64Context.Pc; + *sp = context.LoongArch64Context.Sp; + break; } return S_OK; } diff --git a/src/SOS/Strike/crosscontext.h b/src/SOS/Strike/crosscontext.h index 8f2ba92f7..47937e376 100644 --- a/src/SOS/Strike/crosscontext.h +++ b/src/SOS/Strike/crosscontext.h @@ -332,6 +332,56 @@ typedef struct { } RISCV64_CONTEXT; +///LOONGARCH64 Context +#define LOONGARCH64_MAX_BREAKPOINTS 8 +#define LOONGARCH64_MAX_WATCHPOINTS 2 +typedef struct { + + DWORD ContextFlags; + + DWORD64 R0; + DWORD64 Ra; + DWORD64 Tp; + DWORD64 Sp; + DWORD64 A0; + DWORD64 A1; + DWORD64 A2; + DWORD64 A3; + DWORD64 A4; + DWORD64 A5; + DWORD64 A6; + DWORD64 A7; + DWORD64 T0; + DWORD64 T1; + DWORD64 T2; + DWORD64 T3; + DWORD64 T4; + DWORD64 T5; + DWORD64 T6; + DWORD64 T7; + DWORD64 T8; + DWORD64 X0; + DWORD64 Fp; + DWORD64 S0; + DWORD64 S1; + DWORD64 S2; + DWORD64 S3; + DWORD64 S4; + DWORD64 S5; + DWORD64 S6; + DWORD64 S7; + DWORD64 S8; + DWORD64 Pc; + + // + // Floating Point Registers: FPR64/LSX/LASX. + // + ULONGLONG F[4*32]; + DWORD64 Fcc; + DWORD Fcsr; + +} LOONGARCH64_CONTEXT; + typedef struct _CROSS_PLATFORM_CONTEXT { _CROSS_PLATFORM_CONTEXT() {} @@ -342,6 +392,7 @@ typedef struct _CROSS_PLATFORM_CONTEXT { ARM_CONTEXT ArmContext; ARM64_CONTEXT Arm64Context; RISCV64_CONTEXT RiscV64Context; + LOONGARCH64_CONTEXT LoongArch64Context; }; } CROSS_PLATFORM_CONTEXT, *PCROSS_PLATFORM_CONTEXT; diff --git a/src/SOS/Strike/disasm.cpp b/src/SOS/Strike/disasm.cpp index b116c72b9..3abe7a2d5 100644 --- a/src/SOS/Strike/disasm.cpp +++ b/src/SOS/Strike/disasm.cpp @@ -1140,6 +1140,18 @@ LPCSTR RISCV64Machine::s_SPName = "sp"; #endif // SOS_TARGET_RISCV64 +#ifdef SOS_TARGET_LOONGARCH64 +/// +/// LOONGARCH64Machine implementation +/// +LPCSTR LOONGARCH64Machine::s_DumpStackHeading = "ChildFP RetAddr Caller, Callee\n"; +LPCSTR LOONGARCH64Machine::s_GCRegs[30] = {"r0", "ra", "tp", "a0", "a1", "a2", "a3", "a4", "a5", + "a6", "a7", "t0", "t1", "t2", "t3", "t4", "t5", "t6", + "t7", "t8", "x0", "s0", "s1", "s2", "s3", "s4", "s5", + "s6", "s7", "s8"}; +LPCSTR LOONGARCH64Machine::s_SPName = "sp"; +#endif // SOS_TARGET_LOONGARCH64 + // // GCEncodingInfo class member implementations // diff --git a/src/SOS/Strike/disasm.h b/src/SOS/Strike/disasm.h index 714e0fdda..82ad58378 100644 --- a/src/SOS/Strike/disasm.h +++ b/src/SOS/Strike/disasm.h @@ -402,7 +402,6 @@ private: #endif // SOS_TARGET_ARM64 - #ifdef SOS_TARGET_RISCV64 /// RISCV64 Machine specific code @@ -471,6 +470,74 @@ private: #endif // SOS_TARGET_RISCV64 +#ifdef SOS_TARGET_LOONGARCH64 + +/// LOONGARCH64 Machine specific code +class LOONGARCH64Machine : public IMachine +{ +public: + typedef LOONGARCH64_CONTEXT TGT_CTXT; + + static IMachine* GetInstance() + { static LOONGARCH64Machine s_LOONGARCH64MachineInstance; return &s_LOONGARCH64MachineInstance; } + + ULONG GetPlatform() const { return IMAGE_FILE_MACHINE_LOONGARCH64; } + ULONG GetContextSize() const { return sizeof(LOONGARCH64_CONTEXT); } + ULONG GetFullContextFlags() const { return 0x00800007L; } + void SetContextFlags(BYTE* context, ULONG32 contextFlags) { ((LOONGARCH64_CONTEXT*)context)->ContextFlags = contextFlags; }; + + virtual void Unassembly( + TADDR IPBegin, + TADDR IPEnd, + TADDR IPAskedFor, + TADDR GCStressCodeCopy, + GCEncodingInfo *pGCEncodingInfo, + SOSEHInfo *pEHInfo, + BOOL bSuppressLines, + BOOL bDisplayOffsets, + std::function displayIL) const; + virtual void IsReturnAddress( + TADDR retAddr, + TADDR* whereCalled) const; + virtual BOOL GetExceptionContext ( + TADDR stack, + TADDR PC, + TADDR *cxrAddr, + CROSS_PLATFORM_CONTEXT * cxr, + TADDR *exrAddr, + PEXCEPTION_RECORD exr) const; + + // retrieve stack pointer, frame pointer, and instruction pointer from the target context + virtual TADDR GetSP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.LoongArch64Context.Sp; } + virtual TADDR GetBP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.LoongArch64Context.Fp; } + virtual TADDR GetIP(const CROSS_PLATFORM_CONTEXT & ctx) const { return ctx.LoongArch64Context.Pc; } + + virtual void FillSimpleContext(StackTrace_SimpleContext * dest, LPVOID srcCtx) const; + virtual void FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int idx = 0) const; + + virtual LPCSTR GetDumpStackHeading() const { return s_DumpStackHeading; } + virtual LPCSTR GetSPName() const { return s_SPName; } + virtual void GetGCRegisters(LPCSTR** regNames, unsigned int* cntRegs) const + { _ASSERTE(cntRegs != NULL); *regNames = s_GCRegs; *cntRegs = ARRAY_SIZE(s_GCRegs);} + + virtual void DumpGCInfo(GCInfoToken gcInfoToken, unsigned methodSize, printfFtn gcPrintf, bool encBytes, bool bPrintHeader) const; + + int StackWalkIPAdjustOffset() const { return 4; } + +private: + LOONGARCH64Machine() {} + ~LOONGARCH64Machine() {} + LOONGARCH64Machine(const LOONGARCH64Machine& machine); // undefined + LOONGARCH64Machine & operator=(const LOONGARCH64Machine&); // undefined + + static LPCSTR s_DumpStackHeading; + static LPCSTR s_GCRegs[30]; + static LPCSTR s_SPName; + +}; // class LOONGARCH64Machine + +#endif // SOS_TARGET_LOONGARCH64 + #ifdef _MSC_VER #pragma warning(pop) #endif // _MSC_VER @@ -563,4 +630,21 @@ inline void RISCV64Machine::FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int *dest = *(TGT_CTXT*)srcCtx; } #endif // SOS_TARGET_RISCV64 + +#ifdef SOS_TARGET_LOONGARCH64 +inline void LOONGARCH64Machine::FillSimpleContext(StackTrace_SimpleContext * dest, LPVOID srcCtx) const +{ + TGT_CTXT& src = *(TGT_CTXT*) srcCtx; + dest->StackOffset = src.Sp; + dest->FrameOffset = src.Fp; + dest->InstructionOffset = src.Pc; +} + +inline void LOONGARCH64Machine::FillTargetContext(LPVOID destCtx, LPVOID srcCtx, int idx /*= 0*/) const +{ + TGT_CTXT* dest = (TGT_CTXT*)destCtx + idx; + *dest = *(TGT_CTXT*)srcCtx; +} +#endif // SOS_TARGET_LOONGARCH64 + #endif // __disasm_h__ diff --git a/src/SOS/Strike/disasmLOONGARCH64.cpp b/src/SOS/Strike/disasmLOONGARCH64.cpp new file mode 100644 index 000000000..d9f509500 --- /dev/null +++ b/src/SOS/Strike/disasmLOONGARCH64.cpp @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#undef _TARGET_AMD64_ +#ifndef _TARGET_LOONGARCH64_ +#define _TARGET_LOONGARCH64_ +#endif + +#undef TARGET_AMD64 +#ifndef TARGET_LOONGARCH64 +#define TARGET_LOONGARCH64 +#endif + +#include "strike.h" +#include "util.h" +#include + +#include "disasm.h" + +#include "corhdr.h" +#include "cor.h" +#include "dacprivate.h" + +namespace LOONGARCH64GCDump +{ +#undef TARGET_X86 +#undef LIMITED_METHOD_CONTRACT +#define LIMITED_METHOD_DAC_CONTRACT ((void)0) +#define SUPPORTS_DAC ((void)0) +#define LF_GCROOTS +#define LL_INFO1000 +#define LOG(x) +#define LOG_PIPTR(pObjRef, gcFlags, hCallBack) +#define DAC_ARG(x) +#include "gcdumpnonx86.cpp" +} + +#if !defined(_TARGET_WIN64_) +#error This file only supports SOS targeting LOONGARCH64 from a 64-bit debugger +#endif + +#if !defined(SOS_TARGET_LOONGARCH64) +#error This file should be used to support SOS targeting LOONGARCH64 debuggees +#endif + + +void LOONGARCH64Machine::IsReturnAddress(TADDR retAddr, TADDR* whereCalled) const +{ + *whereCalled = 0; + _ASSERTE("LOONGARCH64:NYI"); +} + +// Determine if a value is MT/MD/Obj +static void HandleValue(TADDR value) +{ + // A MethodTable? + if (IsMethodTable(value)) + { + NameForMT_s (value, g_mdName,mdNameLen); + ExtOut (" (MT: %S)", g_mdName); + return; + } + + // A Managed Object? + TADDR dwMTAddr; + move_xp (dwMTAddr, value); + if (IsStringObject(value)) + { + ExtOut (" (\""); + StringObjectContent (value, TRUE); + ExtOut ("\")"); + return; + } + else if (IsMethodTable(dwMTAddr)) + { + NameForMT_s (dwMTAddr, g_mdName,mdNameLen); + ExtOut (" (Object: %S)", g_mdName); + return; + } + + // A MethodDesc? + if (IsMethodDesc(value)) + { + NameForMD_s (value, g_mdName,mdNameLen); + ExtOut (" (MD: %S)", g_mdName); + return; + } + + // A JitHelper? + const char* name = HelperFuncName(value); + if (name) { + ExtOut (" (JitHelp: %s)", name); + return; + } + + // A call to managed code? + // LOONGARCH64TODO: not (yet) implemented. perhaps we don't need it at all. + + // Random symbol. + char Symbol[1024]; + if (SUCCEEDED(g_ExtSymbols->GetNameByOffset(TO_CDADDR(value), Symbol, 1024, + NULL, NULL))) + { + if (Symbol[0] != '\0') + { + ExtOut (" (%s)", Symbol); + return; + } + } +} + +/**********************************************************************\ +* Routine Description: * +* * +* Unassembly a managed code. Translating managed object, * +* call. * +* * +\**********************************************************************/ +void LOONGARCH64Machine::Unassembly ( + TADDR PCBegin, + TADDR PCEnd, + TADDR PCAskedFor, + TADDR GCStressCodeCopy, + GCEncodingInfo *pGCEncodingInfo, + SOSEHInfo *pEHInfo, + BOOL bSuppressLines, + BOOL bDisplayOffsets, + std::function displayIL) const +{ + _ASSERTE("LOONGARCH64:NYI"); +} + +BOOL LOONGARCH64Machine::GetExceptionContext (TADDR stack, TADDR PC, TADDR *cxrAddr, CROSS_PLATFORM_CONTEXT * cxr, + TADDR * exrAddr, PEXCEPTION_RECORD exr) const +{ + _ASSERTE("LOONGARCH64:NYI"); + return FALSE; +} + +/// +/// Dump LOONGARCH GCInfo table +/// +void LOONGARCH64Machine::DumpGCInfo(GCInfoToken gcInfoToken, unsigned methodSize, printfFtn gcPrintf, bool encBytes, bool bPrintHeader) const +{ + if (bPrintHeader) + { + ExtOut("Pointer table:\n"); + } + + LOONGARCH64GCDump::GCDump gcDump(gcInfoToken.Version, encBytes, 5, true); + gcDump.gcPrintf = gcPrintf; + + gcDump.DumpGCTable(dac_cast(gcInfoToken.Info), methodSize, 0); +} diff --git a/src/SOS/Strike/exts.cpp b/src/SOS/Strike/exts.cpp index 31629e664..0337e51a0 100644 --- a/src/SOS/Strike/exts.cpp +++ b/src/SOS/Strike/exts.cpp @@ -158,6 +158,12 @@ GetTargetMachine(ULONG processorType) targetMachine = RISCV64Machine::GetInstance(); } #endif // SOS_TARGET_RISCV64 +#ifdef SOS_TARGET_LOONGARCH64 + if (processorType == IMAGE_FILE_MACHINE_LOONGARCH64) + { + targetMachine = LOONGARCH64Machine::GetInstance(); + } +#endif // SOS_TARGET_LOONGARCH64 return targetMachine; } @@ -189,6 +195,8 @@ ArchQuery(void) break; case IMAGE_FILE_MACHINE_RISCV64: architecture = "riscv64"; + case IMAGE_FILE_MACHINE_LOONGARCH64: + architecture = "loongarch64"; break; } ExtErr("SOS does not support the current target architecture '%s' (0x%04x). A 32 bit target may require a 32 bit debugger or vice versa. In general, try to use the same bitness for the debugger and target process.\n", diff --git a/src/SOS/Strike/exts.h b/src/SOS/Strike/exts.h index 633b925e7..8f0f8fe86 100644 --- a/src/SOS/Strike/exts.h +++ b/src/SOS/Strike/exts.h @@ -60,6 +60,10 @@ #define IMAGE_FILE_MACHINE_RISCV64 0x5064 // RISCV64 #endif // !IMAGE_FILE_MACHINE_RISCV64 +#ifndef IMAGE_FILE_MACHINE_LOONGARCH64 +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 // LOONGARCH64 +#endif // !IMAGE_FILE_MACHINE_LOONGARCH64 + typedef struct _TADDR_RANGE { TADDR start; @@ -416,6 +420,7 @@ inline BOOL IsDbgTargetAmd64() { return g_targetMachine->GetPlatform() == IMAGE inline BOOL IsDbgTargetArm() { return g_targetMachine->GetPlatform() == IMAGE_FILE_MACHINE_ARMNT; } inline BOOL IsDbgTargetArm64() { return g_targetMachine->GetPlatform() == IMAGE_FILE_MACHINE_ARM64; } inline BOOL IsDbgTargetRiscV64(){ return g_targetMachine->GetPlatform() == IMAGE_FILE_MACHINE_RISCV64; } +inline BOOL IsDbgTargetLoongArch64(){ return g_targetMachine->GetPlatform() == IMAGE_FILE_MACHINE_LOONGARCH64; } inline BOOL IsDbgTargetWin64() { return IsDbgTargetAmd64(); } /* Returns the instruction pointer for the given CONTEXT. We need this and its family of diff --git a/src/SOS/Strike/platform/cordebugdatatarget.h b/src/SOS/Strike/platform/cordebugdatatarget.h index a91176919..78dc96681 100644 --- a/src/SOS/Strike/platform/cordebugdatatarget.h +++ b/src/SOS/Strike/platform/cordebugdatatarget.h @@ -98,6 +98,8 @@ public: *pPlatform = CORDB_PLATFORM_POSIX_ARM64; else if (platformKind == IMAGE_FILE_MACHINE_RISCV64) *pPlatform = CORDB_PLATFORM_POSIX_RISCV64; + else if (platformKind == IMAGE_FILE_MACHINE_LOONGARCH64) + *pPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64; else return E_FAIL; } diff --git a/src/SOS/Strike/platform/datatarget.cpp b/src/SOS/Strike/platform/datatarget.cpp index eb22b9397..63a059b53 100644 --- a/src/SOS/Strike/platform/datatarget.cpp +++ b/src/SOS/Strike/platform/datatarget.cpp @@ -99,7 +99,7 @@ HRESULT STDMETHODCALLTYPE DataTarget::GetPointerSize( /* [out] */ ULONG32 *size) { -#if defined(SOS_TARGET_AMD64) || defined(SOS_TARGET_ARM64) || defined(SOS_TARGET_MIPS64) || defined(SOS_TARGET_RISCV64) +#if defined(SOS_TARGET_AMD64) || defined(SOS_TARGET_ARM64) || defined(SOS_TARGET_MIPS64) || defined(SOS_TARGET_RISCV64) || defined(SOS_TARGET_LOONGARCH64) *size = 8; #elif defined(SOS_TARGET_ARM) || defined(SOS_TARGET_X86) *size = 4; diff --git a/src/SOS/Strike/strike.cpp b/src/SOS/Strike/strike.cpp index 70e2a1dbd..afaffbce9 100644 --- a/src/SOS/Strike/strike.cpp +++ b/src/SOS/Strike/strike.cpp @@ -10593,7 +10593,7 @@ public: InternalFrameManager internalFrameManager; IfFailRet(internalFrameManager.Init(pThread3)); - #if defined(_AMD64_) || defined(_ARM64_) || defined(_RISCV64_) + #if defined(_AMD64_) || defined(_ARM64_) || defined(_RISCV64_) || defined(_LOONGARCH64_) ExtOut("%-16s %-16s %s\n", "Child SP", "IP", "Call Site"); #elif defined(_X86_) || defined(_ARM_) ExtOut("%-8s %-8s %s\n", "Child SP", "IP", "Call Site"); @@ -11081,6 +11081,24 @@ public: ExtOut(outputFormat3, "t5", context.RiscV64Context.T5, "t6", context.RiscV64Context.T6, "pc", context.RiscV64Context.Pc); } #endif +#if defined(SOS_TARGET_LOONGARCH64) + if (IsDbgTargetLoongArch64()) + { + foundPlatform = true; + String outputFormat3 = " %3s=%016llx %3s=%016llx %3s=%016llx\n"; + ExtOut(outputFormat3, "r0", context.LoongArch64Context.R0, "ra", context.LoongArch64Context.Ra, "tp", context.LoongArch64Context.Tp); + ExtOut(outputFormat3, "sp", context.LoongArch64Context.Sp, "a0", context.LoongArch64Context.A0, "a1", context.LoongArch64Context.A1); + ExtOut(outputFormat3, "a2", context.LoongArch64Context.A2, "a3", context.LoongArch64Context.A3, "a4", context.LoongArch64Context.A4); + ExtOut(outputFormat3, "a5", context.LoongArch64Context.A5, "a6", context.LoongArch64Context.A6, "a7", context.LoongArch64Context.A7); + ExtOut(outputFormat3, "t0", context.LoongArch64Context.T0, "t1", context.LoongArch64Context.T1, "t2", context.LoongArch64Context.T2); + ExtOut(outputFormat3, "t3", context.LoongArch64Context.T3, "t4", context.LoongArch64Context.T4, "t5", context.LoongArch64Context.T5); + ExtOut(outputFormat3, "t6", context.LoongArch64Context.T6, "t7", context.LoongArch64Context.T7, "t8", context.LoongArch64Context.T8); + ExtOut(outputFormat3, "x0", context.LoongArch64Context.X0, "fp", context.LoongArch64Context.Fp, "s0", context.LoongArch64Context.S0); + ExtOut(outputFormat3, "s1", context.LoongArch64Context.S1, "s2", context.LoongArch64Context.S2, "s3", context.LoongArch64Context.S3); + ExtOut(outputFormat3, "s4", context.LoongArch64Context.S4, "s5", context.LoongArch64Context.S5, "s6", context.LoongArch64Context.S6); + ExtOut(outputFormat3, "s7", context.LoongArch64Context.S7, "s8", context.LoongArch64Context.S8, "pc", context.LoongArch64Context.Pc); + } +#endif if (!foundPlatform) { diff --git a/src/SOS/Strike/util.h b/src/SOS/Strike/util.h index f63cf790d..51ddf8559 100644 --- a/src/SOS/Strike/util.h +++ b/src/SOS/Strike/util.h @@ -1547,7 +1547,7 @@ BOOL IsMiniDumpFile(); void ReportOOM(); BOOL SafeReadMemory (TADDR offset, PVOID lpBuffer, ULONG cb, PULONG lpcbBytesRead); -#if !defined(_TARGET_WIN64_) && !defined(_ARM64_) && !defined(_MIPS64_) && !defined(_RISCV64_) +#if !defined(_TARGET_WIN64_) && !defined(_ARM64_) && !defined(_MIPS64_) && !defined(_RISCV64_) && !defined(_LOONGARCH64_) // on 64-bit platforms TADDR and CLRDATA_ADDRESS are identical inline BOOL SafeReadMemory (CLRDATA_ADDRESS offset, PVOID lpBuffer, ULONG cb, PULONG lpcbBytesRead) { return SafeReadMemory(TO_TADDR(offset), lpBuffer, cb, lpcbBytesRead); } diff --git a/src/SOS/extensions/hostcoreclr.cpp b/src/SOS/extensions/hostcoreclr.cpp index 7a9e63552..3bd499dc2 100644 --- a/src/SOS/extensions/hostcoreclr.cpp +++ b/src/SOS/extensions/hostcoreclr.cpp @@ -89,6 +89,8 @@ namespace RuntimeHostingConstants "DOTNET_ROOT_ARM64"; #elif defined(HOST_RISCV64) "DOTNET_ROOT_RISCV64"; +#elif defined(HOST_LOONGARCH64) + "DOTNET_ROOT_LOONGARCH64"; #else "Error"; #error Hosting layer doesn't support target arch @@ -111,6 +113,8 @@ namespace RuntimeHostingConstants "/etc/dotnet/install_location_arm64"; #elif defined(HOST_RISCV64) "/etc/dotnet/install_location_riscv64"; +#elif defined(HOST_LOONGARCH64) + "/etc/dotnet/install_location_loongarch64"; #else "ERROR"; #error Hosting layer doesn't support target arch diff --git a/src/SOS/lldbplugin/CMakeLists.txt b/src/SOS/lldbplugin/CMakeLists.txt index 49936d30b..ca15672ff 100644 --- a/src/SOS/lldbplugin/CMakeLists.txt +++ b/src/SOS/lldbplugin/CMakeLists.txt @@ -57,6 +57,13 @@ elseif(CLR_CMAKE_HOST_ARCH_RISCV64) add_definitions(-DDBG_TARGET_WIN64=1) add_definitions(-DBIT64) SET(REQUIRE_LLDBPLUGIN false) +elseif(CLR_CMAKE_HOST_ARCH_LOONGARCH64) + add_definitions(-D_TARGET_LOONGARCH64_=1) + add_definitions(-DDBG_TARGET_64BIT=1) + add_definitions(-DDBG_TARGET_LOONGARCH64=1) + add_definitions(-DDBG_TARGET_WIN64=1) + add_definitions(-DBIT64) + SET(REQUIRE_LLDBPLUGIN false) endif() if(NOT $ENV{LLVM_HOME} STREQUAL "") diff --git a/src/SOS/lldbplugin/services.cpp b/src/SOS/lldbplugin/services.cpp index 291f0f677..182a74be4 100644 --- a/src/SOS/lldbplugin/services.cpp +++ b/src/SOS/lldbplugin/services.cpp @@ -233,6 +233,8 @@ LLDBServices::VirtualUnwind( DWORD64 spToFind = dtcontext->Sp; #elif DBG_TARGET_RISCV64 DWORD64 spToFind = dtcontext->Sp; +#elif DBG_TARGET_LOONGARCH64 + DWORD64 spToFind = dtcontext->Sp; #else #error "spToFind undefined for this platform" #endif @@ -458,6 +460,8 @@ LLDBServices::GetExecutingProcessorType( *type = IMAGE_FILE_MACHINE_I386; #elif DBG_TARGET_RISCV64 *type = IMAGE_FILE_MACHINE_RISCV64; +#elif DBG_TARGET_LOONGARCH64 + *type = IMAGE_FILE_MACHINE_LOONGARCH64; #else #error "Unsupported target" #endif @@ -1726,6 +1730,41 @@ LLDBServices::GetContextFromFrame( dtcontext->SegEs = GetRegister(frame, "es"); dtcontext->SegFs = GetRegister(frame, "fs"); dtcontext->SegGs = GetRegister(frame, "gs"); +#elif DBG_TARGET_LOONGARCH64 + dtcontext->Pc = frame.GetPC(); + dtcontext->Sp = frame.GetSP(); + dtcontext->Ra = GetRegister(frame, "ra"); + dtcontext->Fp = GetRegister(frame, "fp"); + + dtcontext->R0 = GetRegister(frame, "r0"); + dtcontext->Tp = GetRegister(frame, "tp"); + dtcontext->A0 = GetRegister(frame, "a0"); + dtcontext->A1 = GetRegister(frame, "a1"); + dtcontext->A2 = GetRegister(frame, "a2"); + dtcontext->A3 = GetRegister(frame, "a3"); + dtcontext->A4 = GetRegister(frame, "a4"); + dtcontext->A5 = GetRegister(frame, "a5"); + dtcontext->A6 = GetRegister(frame, "a6"); + dtcontext->A7 = GetRegister(frame, "a7"); + dtcontext->T0 = GetRegister(frame, "t0"); + dtcontext->T1 = GetRegister(frame, "t1"); + dtcontext->T2 = GetRegister(frame, "t2"); + dtcontext->T3 = GetRegister(frame, "t3"); + dtcontext->T4 = GetRegister(frame, "t4"); + dtcontext->T5 = GetRegister(frame, "t5"); + dtcontext->T6 = GetRegister(frame, "t6"); + dtcontext->T7 = GetRegister(frame, "t7"); + dtcontext->T8 = GetRegister(frame, "t8"); + dtcontext->X0 = GetRegister(frame, "x0"); + dtcontext->S0 = GetRegister(frame, "s0"); + dtcontext->S1 = GetRegister(frame, "s1"); + dtcontext->S2 = GetRegister(frame, "s2"); + dtcontext->S3 = GetRegister(frame, "s3"); + dtcontext->S4 = GetRegister(frame, "s4"); + dtcontext->S5 = GetRegister(frame, "s5"); + dtcontext->S6 = GetRegister(frame, "s6"); + dtcontext->S7 = GetRegister(frame, "s7"); + dtcontext->S8 = GetRegister(frame, "s8"); #endif } diff --git a/src/dbgshim/debugshim.cpp b/src/dbgshim/debugshim.cpp index bc480ee80..62cede725 100644 --- a/src/dbgshim/debugshim.cpp +++ b/src/dbgshim/debugshim.cpp @@ -758,6 +758,8 @@ HRESULT CLRDebuggingImpl::FormatLongDacModuleName(_Inout_updates_z_(cchBuffer) W const WCHAR* pHostArch = W("arm64"); #elif defined(HOST_RISCV64) const WCHAR* pHostArch = W("riscv64"); +#elif defined(HOST_LOONGARCH64) + const WCHAR* pHostArch = W("loongarch64"); #else _ASSERTE(!"Unknown host arch"); return E_NOTIMPL; -- 2.34.1