Skip to content

Commit

Permalink
[RISC-V] coreclr-pal and coreclr-debug directories (#82380)
Browse files Browse the repository at this point in the history
* [RISC-V] coreclr-pal and coreclr-debug directories

- Successfully cross-build for RISC-V.
- Run A simple application "helloworld"
- Fail a test in clr.paltest

* Fix

* [PAL] Update

* [PAL] Update

* [PAL] Updated based on reviews

* [PAL] Update REGISTER_RISCV64_X0

* [PAL] Fix a mistake

* [PAL] Fix by reviews

* [PAL] Restore EPILOG_STACK_FREE
  • Loading branch information
clamp03 authored Apr 13, 2023
1 parent 42c6bcf commit e73d7fc
Show file tree
Hide file tree
Showing 38 changed files with 1,470 additions and 173 deletions.
4 changes: 3 additions & 1 deletion eng/native/tryrun.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ else()
message(FATAL_ERROR "Unsupported platform. OS: ${CMAKE_SYSTEM_NAME}, arch: ${TARGET_ARCH_NAME}")
endif()

if(TARGET_ARCH_NAME MATCHES "^(x86|x64|s390x|armv6|loongarch64|riscv64|ppc64le)$")
if(TARGET_ARCH_NAME MATCHES "^(x86|x64|s390x|armv6|loongarch64|ppc64le)$")
set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 0)
elseif (TARGET_ARCH_NAME STREQUAL "riscv64")
set_cache_value(HAVE_FUNCTIONAL_PTHREAD_ROBUST_MUTEXES_EXITCODE 1)
endif()
4 changes: 2 additions & 2 deletions src/coreclr/debug/createdump/createdumpunix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include "createdump.h"

#if defined(__arm__) || defined(__aarch64__) || defined(__loongarch64)
#if defined(__arm__) || defined(__aarch64__) || defined(__loongarch64) || defined(__riscv)
long g_pageSize = 0;
#endif

Expand All @@ -19,7 +19,7 @@ CreateDump(const CreateDumpOptions& options)
bool result = false;

// Initialize PAGE_SIZE
#if defined(__arm__) || defined(__aarch64__) || defined(__loongarch64)
#if defined(__arm__) || defined(__aarch64__) || defined(__loongarch64) || defined(__riscv)
g_pageSize = sysconf(_SC_PAGESIZE);
#endif
TRACE("PAGE_SIZE %d\n", PAGE_SIZE);
Expand Down
4 changes: 3 additions & 1 deletion src/coreclr/debug/createdump/datatarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ DumpDataTarget::GetMachineType(
*machine = IMAGE_FILE_MACHINE_I386;
#elif HOST_LOONGARCH64
*machine = IMAGE_FILE_MACHINE_LOONGARCH64;
#elif HOST_RISCV64
*machine = IMAGE_FILE_MACHINE_RISCV64;
#else
#error Unsupported architecture
#endif
Expand All @@ -87,7 +89,7 @@ HRESULT STDMETHODCALLTYPE
DumpDataTarget::GetPointerSize(
/* [out] */ ULONG32 *size)
{
#if defined(HOST_AMD64) || defined(HOST_ARM64) || defined(HOST_LOONGARCH64)
#if defined(HOST_AMD64) || defined(HOST_ARM64) || defined(HOST_LOONGARCH64) || defined(HOST_RISCV64)
*size = 8;
#elif defined(HOST_ARM) || defined(HOST_X86)
*size = 4;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/debug/createdump/dumpwriterelf.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#define ELF_ARCH EM_ARM
#elif defined(__loongarch64)
#define ELF_ARCH EM_LOONGARCH
#elif defined(__riscv)
#define ELF_ARCH EM_RISCV
#endif

#define PH_HDR_CANARY 0xFFFF
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/createdump/memoryregion.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#if !defined(PAGE_SIZE) && (defined(__arm__) || defined(__aarch64__) || defined(__loongarch64))
#if !defined(PAGE_SIZE) && (defined(__arm__) || defined(__aarch64__) || defined(__loongarch64)) || defined(__riscv)
extern long g_pageSize;
#define PAGE_SIZE g_pageSize
#endif
Expand Down
18 changes: 18 additions & 0 deletions src/coreclr/debug/createdump/threadinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ class CrashInfo;
#define MCREG_Pc(mc) ((mc).pc)
#endif

#if defined(__riscv)
// See src/coreclr/pal/src/include/pal/context.h
#define MCREG_Ra(mc) ((mc).ra)
#define MCREG_Fp(mc) ((mc).s0)
#define MCREG_Sp(mc) ((mc).sp)
#define MCREG_Pc(mc) ((mc).pc)
#endif

#define FPREG_ErrorOffset(fpregs) *(DWORD*)&((fpregs).rip)
#define FPREG_ErrorSelector(fpregs) *(((WORD*)&((fpregs).rip)) + 2)
#define FPREG_DataOffset(fpregs) *(DWORD*)&((fpregs).rdp)
Expand All @@ -30,6 +38,12 @@ class CrashInfo;
#elif defined(__loongarch64)
// struct user_regs_struct {} defined `/usr/include/loongarch64-linux-gnu/sys/user.h`

struct user_fpregs_struct
{
unsigned long long fpregs[32];
unsigned long fpscr;
} __attribute__((__packed__));
#elif defined(__riscv)
struct user_fpregs_struct
{
unsigned long long fpregs[32];
Expand Down Expand Up @@ -154,6 +168,10 @@ class ThreadInfo
inline const uint64_t GetInstructionPointer() const { return m_gpRegisters.ARM_pc; }
inline const uint64_t GetStackPointer() const { return m_gpRegisters.ARM_sp; }
inline const uint64_t GetFramePointer() const { return m_gpRegisters.ARM_fp; }
#elif defined(__riscv)
inline const uint64_t GetInstructionPointer() const { return MCREG_Pc(m_gpRegisters); }
inline const uint64_t GetStackPointer() const { return MCREG_Sp(m_gpRegisters); }
inline const uint64_t GetFramePointer() const { return MCREG_Fp(m_gpRegisters); }
#endif
#endif // __APPLE__
bool IsCrashThread() const;
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/debug/createdump/threadinfounix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ ThreadInfo::Initialize()
TRACE("Thread %04x RIP %016llx RSP %016llx\n", m_tid, (unsigned long long)m_gpRegisters.rip, (unsigned long long)m_gpRegisters.rsp);
#elif defined(__loongarch64)
TRACE("Thread %04x PC %016llx SP %016llx\n", m_tid, (unsigned long long)m_gpRegisters.pc, (unsigned long long)m_gpRegisters.gpr[3]);
#elif defined(__riscv)
TRACE("Thread %04x PC %016llx SP %016llx\n", m_tid, (unsigned long long)m_gpRegisters.pc, (unsigned long long)m_gpRegisters.sp);
#else
#error "Unsupported architecture"
#endif
Expand Down Expand Up @@ -243,6 +245,8 @@ ThreadInfo::GetThreadContext(uint32_t flags, CONTEXT* context) const
memcpy(context->F, m_fpRegisters.fpregs, sizeof(context->F));
context->Fcsr = m_fpRegisters.fpscr;
}
#elif defined(__riscv)
_ASSERTE(!"TODO RISCV64 NYI");
#else
#error Platform not supported
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/debug/daccess/daccess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5450,6 +5450,8 @@ ClrDataAccess::Initialize(void)
CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_ARM64;
#elif defined(TARGET_LOONGARCH64)
CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64;
#elif defined(TARGET_RISCV64)
CorDebugPlatform hostPlatform = CORDB_PLATFORM_POSIX_RISCV64;
#else
#error Unknown Processor.
#endif
Expand Down
12 changes: 12 additions & 0 deletions src/coreclr/debug/daccess/request.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,18 @@ ClrDataAccess::GetRegisterName(int regNum, unsigned int count, _Inout_updates_z_
W("S6"), W("S7"), W("K0"), W("K1"),
W("GP"), W("SP"), W("FP"), W("RA")
};
#elif defined(TARGET_RISCV64)
static const WCHAR *regs[] =
{
W("R0"), W("RA"), W("SP"), W("GP"),
W("TP"), W("T0"), W("T1"), W("T2"),
W("FP"), W("S1"), W("A0"), W("A1"),
W("A2"), W("A3"), W("A4"), W("A5"),
W("A6"), W("A7"), W("S2"), W("S3"),
W("S4"), W("S5"), W("S6"), W("S7"),
W("S8"), W("S9"), W("S10"), W("S11"),
W("T3"), W("T4"), W("T5"), W("T6")
};
#endif

// Caller frame registers are encoded as "-(reg+1)".
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/di/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ if(CLR_CMAKE_HOST_WIN32)
endif()
elseif(CLR_CMAKE_HOST_UNIX)

if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64)
if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM OR CLR_CMAKE_TARGET_ARCH_LOONGARCH64 OR CLR_CMAKE_TARGET_ARCH_RISCV64)
set(CORDBDI_SOURCES_ASM_FILE
${ARCH_SOURCES_DIR}/floatconversion.S
)
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/debug/di/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4872,6 +4872,8 @@ int CordbNativeCode::GetCallInstructionLength(BYTE *ip, ULONG32 count)

_ASSERTE(!"Invalid opcode!");
return -1;
#elif defined(TARGET_RISCV64)
return MAX_INSTRUCTION_LENGTH;
#else
#error Platform not implemented
#endif
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/debug/di/platformspecific.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@
#elif TARGET_LOONGARCH64
#include "loongarch64/cordbregisterset.cpp"
#include "loongarch64/primitives.cpp"
#elif TARGET_RISCV64
#include "riscv64/cordbregisterset.cpp"
#include "riscv64/primitives.cpp"
#else
#error Unsupported platform
#endif
116 changes: 116 additions & 0 deletions src/coreclr/debug/di/riscv64/cordbregisterset.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

//*****************************************************************************
// File: CordbRegisterSet.cpp
//

//
//*****************************************************************************
#include "primitives.h"


HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG64* pAvailable)
{
FAIL_IF_NEUTERED(this);
VALIDATE_POINTER_TO_OBJECT(pAvailable, ULONG64 *);

*pAvailable = SETBITULONG64(REGISTER_RISCV64_PC)
| SETBITULONG64(REGISTER_RISCV64_RA)
| SETBITULONG64(REGISTER_RISCV64_SP)
| SETBITULONG64(REGISTER_RISCV64_GP)
| SETBITULONG64(REGISTER_RISCV64_TP)
| SETBITULONG64(REGISTER_RISCV64_T0)
| SETBITULONG64(REGISTER_RISCV64_T1)
| SETBITULONG64(REGISTER_RISCV64_T2)
| SETBITULONG64(REGISTER_RISCV64_FP)
| SETBITULONG64(REGISTER_RISCV64_S1)
| SETBITULONG64(REGISTER_RISCV64_A0)
| SETBITULONG64(REGISTER_RISCV64_A1)
| SETBITULONG64(REGISTER_RISCV64_A2)
| SETBITULONG64(REGISTER_RISCV64_A3)
| SETBITULONG64(REGISTER_RISCV64_A4)
| SETBITULONG64(REGISTER_RISCV64_A5)
| SETBITULONG64(REGISTER_RISCV64_A6)
| SETBITULONG64(REGISTER_RISCV64_A7)
| SETBITULONG64(REGISTER_RISCV64_S2)
| SETBITULONG64(REGISTER_RISCV64_S3)
| SETBITULONG64(REGISTER_RISCV64_S4)
| SETBITULONG64(REGISTER_RISCV64_S5)
| SETBITULONG64(REGISTER_RISCV64_S6)
| SETBITULONG64(REGISTER_RISCV64_S7)
| SETBITULONG64(REGISTER_RISCV64_S8)
| SETBITULONG64(REGISTER_RISCV64_S9)
| SETBITULONG64(REGISTER_RISCV64_S10)
| SETBITULONG64(REGISTER_RISCV64_S11)
| SETBITULONG64(REGISTER_RISCV64_T3)
| SETBITULONG64(REGISTER_RISCV64_T4)
| SETBITULONG64(REGISTER_RISCV64_T5)
| SETBITULONG64(REGISTER_RISCV64_T6)
| SETBITULONG64(REGISTER_RISCV64_F0)
| SETBITULONG64(REGISTER_RISCV64_F1)
| SETBITULONG64(REGISTER_RISCV64_F2)
| SETBITULONG64(REGISTER_RISCV64_F3)
| SETBITULONG64(REGISTER_RISCV64_F4)
| SETBITULONG64(REGISTER_RISCV64_F5)
| SETBITULONG64(REGISTER_RISCV64_F6)
| SETBITULONG64(REGISTER_RISCV64_F7)
| SETBITULONG64(REGISTER_RISCV64_F8)
| SETBITULONG64(REGISTER_RISCV64_F9)
| SETBITULONG64(REGISTER_RISCV64_F10)
| SETBITULONG64(REGISTER_RISCV64_F11)
| SETBITULONG64(REGISTER_RISCV64_F12)
| SETBITULONG64(REGISTER_RISCV64_F13)
| SETBITULONG64(REGISTER_RISCV64_F14)
| SETBITULONG64(REGISTER_RISCV64_F15)
| SETBITULONG64(REGISTER_RISCV64_F16)
| SETBITULONG64(REGISTER_RISCV64_F17)
| SETBITULONG64(REGISTER_RISCV64_F18)
| SETBITULONG64(REGISTER_RISCV64_F19)
| SETBITULONG64(REGISTER_RISCV64_F20)
| SETBITULONG64(REGISTER_RISCV64_F21)
| SETBITULONG64(REGISTER_RISCV64_F22)
| SETBITULONG64(REGISTER_RISCV64_F23)
| SETBITULONG64(REGISTER_RISCV64_F24)
| SETBITULONG64(REGISTER_RISCV64_F25)
| SETBITULONG64(REGISTER_RISCV64_F26)
| SETBITULONG64(REGISTER_RISCV64_F27)
| SETBITULONG64(REGISTER_RISCV64_F28)
| SETBITULONG64(REGISTER_RISCV64_F29)
| SETBITULONG64(REGISTER_RISCV64_F30)
| SETBITULONG64(REGISTER_RISCV64_F31);

return S_OK;
}

HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount,
CORDB_REGISTER regBuffer[])
{
_ASSERTE(!"RISCV64:NYI");
return S_OK;
}


HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG32 regCount,
BYTE pAvailable[])
{
_ASSERTE(!"RISCV64:NYI");
return S_OK;
}


HRESULT CordbRegisterSet::GetRegisters(ULONG32 maskCount, BYTE mask[],
ULONG32 regCount, CORDB_REGISTER regBuffer[])
{
_ASSERTE(!"RISCV64:NYI");
return S_OK;
}


// This is just a convenience function to convert a regdisplay into a Context.
// Since a context has more info than a regdisplay, the conversion isn't perfect
// and the context can't be fully accurate.
void CordbRegisterSet::InternalCopyRDToContext(DT_CONTEXT *pInputContext)
{
_ASSERTE(!"RISCV64:NYI");
}
12 changes: 12 additions & 0 deletions src/coreclr/debug/di/riscv64/floatconversion.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include <unixasmmacros.inc>

// Arguments
// input: (in A0) the address of the ULONGLONG to be converted to a double
// output: the double corresponding to the ULONGLONG input value
LEAF_ENTRY FPFillR8, .TEXT
fld fa0, 0(a0)
ret
LEAF_END FPFillR8, .TEXT
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "unixasmmacros.inc"
#include "asmconstants.h"
//

#error "TODO-RISCV64: missing implementation"
#include "../../shared/riscv64/primitives.cpp"
7 changes: 7 additions & 0 deletions src/coreclr/debug/di/rsthread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8331,6 +8331,9 @@ HRESULT CordbJITILFrame::GetNativeVariable(CordbType *type,
#elif defined(TARGET_LOONGARCH64)
hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg + REGISTER_LOONGARCH64_F0,
type, ppValue);
#elif defined(TARGET_RISCV64)
hr = m_nativeFrame->GetLocalFloatingPointValue(pNativeVarInfo->loc.vlReg.vlrReg + REGISTER_RISCV64_F0,
type, ppValue);
#else
#error Platform not implemented
#endif // TARGET_ARM @ARMTODO
Expand Down Expand Up @@ -8769,6 +8772,8 @@ HRESULT CordbJITILFrame::GetReturnValueForType(CordbType *pType, ICorDebugValue
const CorDebugRegister floatRegister = REGISTER_ARM_D0;
#elif defined(TARGET_LOONGARCH64)
const CorDebugRegister floatRegister = REGISTER_LOONGARCH64_F0;
#elif defined(TARGET_RISCV64)
const CorDebugRegister floatRegister = REGISTER_RISCV64_F0;
#endif

#if defined(TARGET_X86)
Expand All @@ -8783,6 +8788,8 @@ HRESULT CordbJITILFrame::GetReturnValueForType(CordbType *pType, ICorDebugValue
const CorDebugRegister ptrHighWordRegister = REGISTER_ARM_R1;
#elif defined(TARGET_LOONGARCH64)
const CorDebugRegister ptrRegister = REGISTER_LOONGARCH64_A0;
#elif defined(TARGET_RISCV64)
const CorDebugRegister ptrRegister = REGISTER_RISCV64_A0;
#endif

CorElementType corReturnType = pType->GetElementType();
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/debug/di/shimremotedatatarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,8 @@ ShimRemoteDataTarget::GetPlatform(
*pPlatform = CORDB_PLATFORM_POSIX_ARM64;
#elif defined(TARGET_LOONGARCH64)
*pPlatform = CORDB_PLATFORM_POSIX_LOONGARCH64;
#elif defined(TARGET_RISCV64)
*pPlatform = CORDB_PLATFORM_POSIX_RISCV64;
#else
#error Unknown Processor.
#endif
Expand Down
38 changes: 37 additions & 1 deletion src/coreclr/debug/ee/riscv64/dbghelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,40 @@
#include "asmconstants.h"
#include "unixasmmacros.inc"

#error "TODO-RISCV64: missing implementation"
//
// hijacking stub used to perform a func-eval, see Debugger::FuncEvalSetup() for use.
//
// on entry:
// a0 : pointer to DebuggerEval object
//

// @dbgtodo- once we port Funceval, use the ExceptionHijack stub instead of this func-eval stub.
NESTED_ENTRY FuncEvalHijack, _TEXT, UnhandledExceptionHandlerUnix
// NOTE: FuncEvalHijackPersonalityRoutine is dependent on the stack layout so if
// you change the prolog you will also need to update the personality routine.

// push arg to the stack so our personality routine can find it
// push lr to get good stacktrace in debugger
PROLOG_SAVE_REG_PAIR_INDEXED fp, ra, -32
sd a0, 16(sp)

// FuncEvalHijackWorker returns the address we should jump to.
call C_FUNC(FuncEvalHijackWorker)

EPILOG_STACK_FREE 32
EPILOG_BRANCH_REG a0
NESTED_END FuncEvalHijack

// This is the general purpose hijacking stub. The DacDbi Hijack primitive will
// set up the stack and then set the IP here, and so this just makes the call.
NESTED_ENTRY ExceptionHijack, _TEXT, UnhandledExceptionHandlerUnix
// make the call
call C_FUNC(ExceptionHijackWorker)

// effective NOP to terminate unwind ???
nop

// *** should never get here ***
EMIT_BREAKPOINT
// exported label so the debugger knows where the end of this function is
NESTED_END ExceptionHijack, _TEXT
Loading

0 comments on commit e73d7fc

Please sign in to comment.