Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
7dfa35d
Arm64: [PAC-RET] Add Pointer Authentication support for Arm64
SwapnilGaikwad Dec 18, 2025
8551ad0
Merge main
SwapnilGaikwad Mar 11, 2026
584a268
Fix build failures
SwapnilGaikwad Mar 11, 2026
8216472
Merge main
SwapnilGaikwad Mar 12, 2026
74a5293
Fix build errors
SwapnilGaikwad Mar 12, 2026
c9c43c9
Limit thread context changes to Arm64
SwapnilGaikwad Mar 12, 2026
5d6058c
Merge main
SwapnilGaikwad Mar 12, 2026
ce5d79b
Fix build issues on x86
SwapnilGaikwad Mar 12, 2026
8db6f6d
Merge main
SwapnilGaikwad Mar 12, 2026
872443e
Merge branch 'main' into github-add-pac
SwapnilGaikwad Mar 12, 2026
3591b2a
Merge main
SwapnilGaikwad Mar 18, 2026
867e149
Limit framelayout changes to JIT
SwapnilGaikwad Mar 18, 2026
f00f789
Fix formatting
SwapnilGaikwad Mar 18, 2026
9616e73
Merge main
SwapnilGaikwad Mar 31, 2026
4582f73
Add MethodAssociatedData containing hijackinfo for NativeAOT
SwapnilGaikwad Mar 31, 2026
d1e65cb
Merge main
SwapnilGaikwad Apr 9, 2026
e1cfd90
Use unwind info to determine value of SP at the time of signing using…
SwapnilGaikwad Apr 9, 2026
cfe6ab8
Fix windows build
SwapnilGaikwad Apr 10, 2026
bed17cd
Merge main
SwapnilGaikwad Apr 10, 2026
cefcd3f
Fix register addressing in asmhelpers
SwapnilGaikwad Apr 10, 2026
f93804f
Merge main
SwapnilGaikwad Apr 10, 2026
280870c
Refactor out IsPacPresent to avoid parsing unwind info multiple times
SwapnilGaikwad Apr 10, 2026
5cc10be
Merge main
SwapnilGaikwad Apr 10, 2026
f186f19
Bail out of RAH instead of hijacking calling frame
SwapnilGaikwad Apr 10, 2026
941d9e2
Remove left-over changes from MethodAssociated Data approach
SwapnilGaikwad Apr 13, 2026
8f9645b
Merge main
SwapnilGaikwad Apr 14, 2026
a755fba
Fallback to DWARF for PAC unwind codes on macos
SwapnilGaikwad Apr 14, 2026
5bde929
Merge main
SwapnilGaikwad Apr 21, 2026
352b3fd
Used stripped the return address while creating a frame OnHijackWorker
SwapnilGaikwad Apr 21, 2026
264f1fe
Remove redundant lef-over changes
SwapnilGaikwad Apr 21, 2026
f455dc1
Mark PacStrip Arm64 only
SwapnilGaikwad Apr 21, 2026
d5a4abb
Merge main
SwapnilGaikwad Apr 21, 2026
a02fac8
Temporarily Revert "JIT: Restore arm64, LA64 and RISCV64 OSR callee s…
SwapnilGaikwad Apr 22, 2026
0d2d0dd
Restore changes from "JIT: Restore arm64, LA64 and RISCV64 OSR callee…
SwapnilGaikwad Apr 23, 2026
f5b520a
Merge main
SwapnilGaikwad Apr 23, 2026
396c868
Strip return address for correct signing in prolog of Tier0 OSR
SwapnilGaikwad Apr 23, 2026
f7d4548
Avoid stripping while restoring Tier0 registers for OSR
SwapnilGaikwad Apr 27, 2026
3ca8d39
Merge main
SwapnilGaikwad Apr 27, 2026
e98099e
Merge main
SwapnilGaikwad Apr 28, 2026
a1768bd
Keep encrypted LR saved in a slot while creating hijack frame
SwapnilGaikwad Apr 28, 2026
1827095
Remove todo from libunwind to use strip instead of auth
SwapnilGaikwad Apr 28, 2026
b43e5e7
Use auth instead of strip in windows unwinder
SwapnilGaikwad Apr 29, 2026
52ca210
Merge main
SwapnilGaikwad Apr 29, 2026
e5d5ca3
Keep signed return address for the hijackframe and authenticate it on…
SwapnilGaikwad Apr 30, 2026
037a0a4
Merge main
SwapnilGaikwad Apr 30, 2026
1e4ae0a
Merge main
SwapnilGaikwad Apr 30, 2026
067c38f
Fix build issues on macos
SwapnilGaikwad Apr 30, 2026
fcbcdf5
Merge main
SwapnilGaikwad Apr 30, 2026
e1a3695
Handle phantom unwind codes correctly
SwapnilGaikwad Apr 30, 2026
d288cea
Merge main
SwapnilGaikwad May 5, 2026
146da5e
Address review comments
SwapnilGaikwad May 5, 2026
ebad545
Use xpaci instead xpaclri for stripping
SwapnilGaikwad May 5, 2026
89a9ded
Incorporate review comment
SwapnilGaikwad May 5, 2026
650ef08
Merge main
SwapnilGaikwad May 5, 2026
80ed0b4
Merge main
SwapnilGaikwad May 6, 2026
e17d8e9
Refactor GetPacSignInfo
SwapnilGaikwad May 6, 2026
22dccb7
Don't assume sp offset to be zero for PAC signing
SwapnilGaikwad May 7, 2026
21bc75a
Canonicalize return addresses in StackFrameIterator for NativeAOT
SwapnilGaikwad May 7, 2026
cd162df
Merge main
SwapnilGaikwad May 7, 2026
493eff7
Track SP offset for PAC instruction separately while calculating hija…
SwapnilGaikwad May 7, 2026
84741a8
Merge main
SwapnilGaikwad May 7, 2026
bcbc1c1
Use B key on Windows and A key otherwise for PAC
SwapnilGaikwad May 7, 2026
dfac51c
Merge main
SwapnilGaikwad May 7, 2026
24d44ea
Fix formatting
SwapnilGaikwad May 7, 2026
12ca90d
Merge main
SwapnilGaikwad May 8, 2026
7df0c1f
Address review comments
SwapnilGaikwad May 8, 2026
0b6b5a2
Merge main
SwapnilGaikwad May 8, 2026
e9be308
Track PAC CFA offset while unwinding for NativeAOT
SwapnilGaikwad May 8, 2026
ddccab0
Match finding SP for PAC signing on Windows NativeAOT with the JIT
SwapnilGaikwad May 8, 2026
ff1f08e
Fix build errors
SwapnilGaikwad May 11, 2026
3a6ad11
Merge main
SwapnilGaikwad May 11, 2026
e71d980
Merge main
SwapnilGaikwad May 13, 2026
a07d3bd
Merge main
SwapnilGaikwad May 13, 2026
af97173
Remove redundant changes
SwapnilGaikwad May 13, 2026
f153e2b
Merge main
SwapnilGaikwad May 14, 2026
c40c08c
Make JitPacEnabled config variable Arm64 only
SwapnilGaikwad May 14, 2026
27f8c9b
Merge main
SwapnilGaikwad May 15, 2026
a6b6641
Restore clearing THUMB_CODE on arm32
SwapnilGaikwad May 15, 2026
f5b5954
Merge main and JIT changes
SwapnilGaikwad May 19, 2026
b6fa62e
Merge main
SwapnilGaikwad May 19, 2026
401b496
Use PAL unwinder for UNIX to retrieve signing SP for PAC
SwapnilGaikwad May 19, 2026
d21c942
Merge main
SwapnilGaikwad May 20, 2026
9a2a161
Restore missing THUMB_CODE clearing on Arm32
SwapnilGaikwad May 20, 2026
82b962d
Merge main
SwapnilGaikwad May 21, 2026
f4c7ec1
Switch to use PAL unwinder for Windows to retrieve signing SP for PAC
SwapnilGaikwad May 21, 2026
82a8ec4
Try fixing build failures on Windows
SwapnilGaikwad May 21, 2026
64c7367
Merge main
SwapnilGaikwad May 27, 2026
a24b0b7
Merge main
SwapnilGaikwad May 28, 2026
b5bd6c2
Merge main
SwapnilGaikwad May 28, 2026
e44b17a
Update JIT GUID temporarilty to enable SPMI tests
SwapnilGaikwad May 28, 2026
0645777
Merge main
SwapnilGaikwad May 29, 2026
3ef9668
Address review comments
SwapnilGaikwad May 29, 2026
6bdc21f
Merge main
SwapnilGaikwad May 29, 2026
a66dd10
Pass signing sp for managed frame to hijack frame
SwapnilGaikwad May 29, 2026
4113f04
Merge main
SwapnilGaikwad Jun 1, 2026
d539d9d
Strip return address in cdac unwinder
SwapnilGaikwad Jun 1, 2026
88b9eb2
Handle RTL_VIRTUAL_UNWIND2_VALIDATE_PAC in unwinder
SwapnilGaikwad Jun 1, 2026
363156e
Revert "Handle RTL_VIRTUAL_UNWIND2_VALIDATE_PAC in unwinder"
SwapnilGaikwad Jun 1, 2026
13cf190
Merge main
SwapnilGaikwad Jun 2, 2026
d5a1b3c
Use ARM64_ARG macro for Arm64 specific args in HijackFrame
SwapnilGaikwad Jun 2, 2026
3da8014
Merge main
SwapnilGaikwad Jun 3, 2026
b3ffd12
Switch to PAL unwinder for NativeAOT on Windows
SwapnilGaikwad Jun 3, 2026
9dfec15
Use auth instead of strip while returning from hijack in NativeAOT
SwapnilGaikwad Jun 3, 2026
0f7379b
Fix build errors on Windows
SwapnilGaikwad Jun 3, 2026
9f20273
Merge main
SwapnilGaikwad Jun 3, 2026
b7f5452
Merge main
SwapnilGaikwad Jun 4, 2026
528710b
Fix build errors on Windows
SwapnilGaikwad Jun 4, 2026
782e0d8
Try fixing arm32 and x64 build failures
SwapnilGaikwad Jun 4, 2026
ba25589
Merge main
SwapnilGaikwad Jun 4, 2026
3efd414
Try fixing build errors
SwapnilGaikwad Jun 4, 2026
98cbb04
More build fixes
SwapnilGaikwad Jun 4, 2026
e41c3ca
Limit changes to NativeAOT declartions to Arm64 only
SwapnilGaikwad Jun 4, 2026
15fe969
Merge main
SwapnilGaikwad Jun 4, 2026
0910b0a
Avoid separate definitions for NativeAOT in daccess.h
SwapnilGaikwad Jun 5, 2026
0e41b35
Avoid adding crosscomp.h for NativeAOT builds to avoid redef warnings…
SwapnilGaikwad Jun 5, 2026
dbb330a
Merge main
SwapnilGaikwad Jun 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/coreclr/inc/cfi.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ enum CFI_OPCODE
CFI_ADJUST_CFA_OFFSET, // Offset is adjusted relative to the current one.
CFI_DEF_CFA_REGISTER, // New register is used to compute CFA
CFI_REL_OFFSET, // Register is saved at offset from the current CFA
CFI_DEF_CFA, // Take address from register and add offset to it
CFI_NEGATE_RA_STATE, // Sign the return address in lr with paciasp
};

Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/inc/clrnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ RtlpGetFunctionEndAddress (
else
{
// Get from the xdata record.
FunctionLength = *(PTR_ULONG64)(ImageBase + FunctionLength) & 0x3ffff;
FunctionLength = *(PTR_uint64_t)(ImageBase + FunctionLength) & 0x3ffff;
}

return FunctionEntry->BeginAddress + 4 * FunctionLength;
Expand Down Expand Up @@ -422,7 +422,7 @@ RtlpGetFunctionEndAddress (
if ((FunctionLength & 3) != 0) {
FunctionLength = (FunctionLength >> 2) & 0x7ff;
} else {
FunctionLength = *(PTR_ULONG64)(ImageBase + FunctionLength) & 0x3ffff;
FunctionLength = *(PTR_uint64_t)(ImageBase + FunctionLength) & 0x3ffff;
}

return FunctionEntry->BeginAddress + 4 * FunctionLength;
Expand Down Expand Up @@ -478,7 +478,7 @@ RtlpGetFunctionEndAddress (
if ((FunctionLength & 3) != 0) {
FunctionLength = (FunctionLength >> 2) & 0x7ff;
} else {
FunctionLength = *(PTR_ULONG64)(ImageBase + FunctionLength) & 0x3ffff;
FunctionLength = *(PTR_uint64_t)(ImageBase + FunctionLength) & 0x3ffff;
}

return FunctionEntry->BeginAddress + 2 * FunctionLength;
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/inc/daccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -2372,23 +2372,23 @@ typedef DPTR(TADDR) PTR_TADDR;

#ifndef NATIVEAOT
typedef ArrayDPTR(BYTE) PTR_BYTE;
typedef DPTR(WORD) PTR_WORD;
typedef DPTR(DWORD) PTR_DWORD;
typedef DPTR(ULONG64) PTR_ULONG64;
typedef DPTR(UINT64) PTR_UINT64;
typedef DPTR(PTR_BYTE) PTR_PTR_BYTE;
typedef DPTR(PTR_PTR_BYTE) PTR_PTR_PTR_BYTE;
typedef ArrayDPTR(signed char) PTR_SBYTE;
typedef ArrayDPTR(const BYTE) PTR_CBYTE;
typedef DPTR(INT8) PTR_INT8;
typedef DPTR(INT16) PTR_INT16;
typedef DPTR(UINT16) PTR_UINT16;
typedef DPTR(WORD) PTR_WORD;
typedef DPTR(USHORT) PTR_USHORT;
typedef DPTR(DWORD) PTR_DWORD;
typedef DPTR(LONG) PTR_LONG;
typedef DPTR(ULONG) PTR_ULONG;
typedef DPTR(INT32) PTR_INT32;
typedef DPTR(UINT32) PTR_UINT32;
typedef DPTR(ULONG64) PTR_ULONG64;
typedef DPTR(INT64) PTR_INT64;
typedef DPTR(UINT64) PTR_UINT64;
typedef DPTR(SIZE_T) PTR_SIZE_T;
typedef DPTR(int) PTR_int;
typedef DPTR(BOOL) PTR_BOOL;
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@

#include <minipal/guid.h>

constexpr GUID JITEEVersionIdentifier = { /* 31a04b06-915e-42a0-bbd2-c9c397677ae5 */
0x31a04b06,
0x915e,
0x42a0,
{0xbb, 0xd2, 0xc9, 0xc3, 0x97, 0x67, 0x7a, 0xe5}
constexpr GUID JITEEVersionIdentifier = { /* 91460d2c-d6a8-460b-a95f-8342301bebe8 */
0x91460d2c,
0xd6a8,
0x460b,
{0xa9, 0x5f, 0x83, 0x42, 0x30, 0x1b, 0xeb, 0xe8}
};

#endif // JIT_EE_VERSIONING_GUID_H
2 changes: 1 addition & 1 deletion src/coreclr/jit/jitconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ CONFIG_STRING(JitInlineMethodsWithEHRange, "JitInlineMethodsWithEHRange")
CONFIG_INTEGER(JitLongAddress, "JitLongAddress", 0) // Force using the large pseudo instruction form for long address
CONFIG_INTEGER(JitMaxUncheckedOffset, "JitMaxUncheckedOffset", 8)
#if defined(TARGET_ARM64)
RELEASE_CONFIG_INTEGER(JitPacEnabled, "JitPacEnabled", 0)
RELEASE_CONFIG_INTEGER(JitPacEnabled, "JitPacEnabled", 1)
#endif

Comment thread
SwapnilGaikwad marked this conversation as resolved.
// Enable devirtualization for generic virtual methods
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/nativeaot/Runtime/AsmOffsets.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,12 @@ ASM_OFFSET( 30, 48, Thread, m_pTransitionFrame)
ASM_OFFSET( 34, 50, Thread, m_pDeferredTransitionFrame)
ASM_OFFSET( 40, 68, Thread, m_ppvHijackedReturnAddressLocation)
ASM_OFFSET( 44, 70, Thread, m_pvHijackedReturnAddress)
#if defined(TARGET_ARM64)
ASM_OFFSET( 48, 78, Thread, m_pSpForPacSign)
ASM_OFFSET( 4c, 80, Thread, m_pExInfoStackHead)
#else
ASM_OFFSET( 48, 78, Thread, m_pExInfoStackHead)
#endif
#ifdef TARGET_X86
ASM_OFFSET( 4c, FF, Thread, m_uHijackedReturnValueFlags)
#endif
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/nativeaot/Runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ if (WIN32)

list(APPEND FULL_RUNTIME_SOURCES windows/CoffNativeCodeManager.cpp)

if(CLR_CMAKE_TARGET_ARCH_ARM64)
list(APPEND FULL_RUNTIME_SOURCES
../../unwinder/arm64/unwinder.cpp
)
include_directories(../../inc)
include_directories(../../unwinder)
include_directories(../../unwinder/arm64)
endif()

set(ASM_SUFFIX asm)
else()

Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/nativeaot/Runtime/ICodeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ class ICodeManager

virtual bool GetReturnAddressHijackInfo(MethodInfo * pMethodInfo,
REGDISPLAY * pRegisterSet, // in
PTR_PTR_VOID * ppvRetAddrLocation // out
PTR_PTR_VOID * ppvRetAddrLocation, // out
uintptr_t * pSpForArm64PacSign // out
) PURE_VIRTUAL

#ifdef TARGET_X86
Expand Down
35 changes: 25 additions & 10 deletions src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,18 @@ EXTERN_C CODE_LOCATION RhpRethrow2;
#define FAILFAST_OR_DAC_FAIL_UNCONDITIONALLY(msg) { ASSERT_UNCONDITIONALLY(msg); RhFailFast(); }
#endif

#if defined(TARGET_ARM64)
extern "C" void* PacStripPtr(void* ptr);
#endif // TARGET_ARM64

static TADDR ReturnAddressToCanonicalPC(TADDR returnAddress)
{
#if defined(TARGET_ARM64)
returnAddress = (TADDR)PacStripPtr((void*)returnAddress);
#endif // TARGET_ARM64
return PCODEToPINSTR(dac_cast<PCODE>(returnAddress));
}

StackFrameIterator::StackFrameIterator(Thread * pThreadToWalk, PInvokeTransitionFrame* pInitialTransitionFrame)
{
STRESS_LOG0(LF_STACKWALK, LL_INFO10000, "----Init---- [ GC ]\n");
Expand Down Expand Up @@ -164,7 +176,7 @@ void StackFrameIterator::InternalInit(Thread * pThreadToWalk, PInvokeTransitionF

#if !defined(FEATURE_PORTABLE_HELPERS) // @TODO: no portable version of regdisplay
memset(&m_RegDisplay, 0, sizeof(m_RegDisplay));
m_RegDisplay.SetIP((PCODE)PCODEToPINSTR((PCODE)pFrame->m_RIP));
m_RegDisplay.SetIP(ReturnAddressToCanonicalPC(dac_cast<TADDR>(pFrame->m_RIP)));
SetControlPC(dac_cast<PTR_VOID>(m_RegDisplay.GetIP()));

PTR_uintptr_t pPreservedRegsCursor = (PTR_uintptr_t)PTR_HOST_MEMBER_TADDR(PInvokeTransitionFrame, pFrame, m_PreservedRegs);
Expand Down Expand Up @@ -413,14 +425,15 @@ void StackFrameIterator::InternalInit(Thread * pThreadToWalk, PTR_PAL_LIMITED_CO

// This codepath is used by the hijack stackwalk and we can get arbitrary ControlPCs from there. If this
// context has a non-managed control PC, then we're done.
if (!m_pInstance->IsManaged(dac_cast<PTR_VOID>(pCtx->GetIp())))
TADDR controlPC = ReturnAddressToCanonicalPC(pCtx->GetIp());
if (!m_pInstance->IsManaged(dac_cast<PTR_VOID>(controlPC)))
return;

//
// control state
//
m_RegDisplay.SP = pCtx->GetSp();
m_RegDisplay.IP = PCODEToPINSTR(pCtx->GetIp());
m_RegDisplay.IP = controlPC;
SetControlPC(dac_cast<PTR_VOID>(m_RegDisplay.GetIP()));

#ifdef TARGET_ARM
Expand Down Expand Up @@ -633,14 +646,15 @@ void StackFrameIterator::InternalInit(Thread * pThreadToWalk, NATIVE_CONTEXT* pC

// This codepath is used by the hijack stackwalk. The IP must be in managed code
// or in a conservatively reported assembly thunk.
ASSERT(IsValidReturnAddress((void*)pCtx->GetIp()));
TADDR controlPC = ReturnAddressToCanonicalPC(pCtx->GetIp());
ASSERT(IsValidReturnAddress(dac_cast<PTR_VOID>(controlPC)));

//
// control state
//
SetControlPC(dac_cast<PTR_VOID>(pCtx->GetIp()));
SetControlPC(dac_cast<PTR_VOID>(controlPC));
m_RegDisplay.SP = pCtx->GetSp();
m_RegDisplay.IP = pCtx->GetIp();
m_RegDisplay.IP = controlPC;

#ifdef TARGET_UNIX
#define PTR_TO_REG(ptr, reg) (&((ptr)->reg()))
Expand Down Expand Up @@ -1223,7 +1237,7 @@ void StackFrameIterator::UnwindFuncletInvokeThunk()

m_RegDisplay.pFP = SP++;

m_RegDisplay.SetIP(*SP++);
m_RegDisplay.SetIP(ReturnAddressToCanonicalPC(*SP++));

m_RegDisplay.pX19 = SP++;
m_RegDisplay.pX20 = SP++;
Expand Down Expand Up @@ -1636,7 +1650,7 @@ void StackFrameIterator::UnwindUniversalTransitionThunk()
stackFrame->UnwindVolatileArgRegisters(&m_RegDisplay);

PTR_uintptr_t addressOfPushedCallerIP = stackFrame->get_AddressOfPushedCallerIP();
m_RegDisplay.SetIP(PCODEToPINSTR(*addressOfPushedCallerIP));
m_RegDisplay.SetIP(ReturnAddressToCanonicalPC(*addressOfPushedCallerIP));
m_RegDisplay.SetSP((uintptr_t)dac_cast<TADDR>(stackFrame->get_CallerSP()));
SetControlPC(dac_cast<PTR_VOID>(m_RegDisplay.GetIP()));
#if defined(TARGET_AMD64) && defined(TARGET_WINDOWS)
Expand Down Expand Up @@ -1767,7 +1781,7 @@ void StackFrameIterator::UnwindThrowSiteThunk()
ASSERT_UNCONDITIONALLY("NYI for this arch");
#endif

m_RegDisplay.SetIP(PCODEToPINSTR(pContext->IP));
m_RegDisplay.SetIP(ReturnAddressToCanonicalPC(pContext->IP));
m_RegDisplay.SetSP(pContext->GetSp());
SetControlPC(dac_cast<PTR_VOID>(m_RegDisplay.GetIP()));

Expand Down Expand Up @@ -1862,7 +1876,8 @@ void StackFrameIterator::NextInternal()
// if the thread is safe to walk, it better not have a hijack in place.
ASSERT(!m_pThread->IsHijacked());

SetControlPC(dac_cast<PTR_VOID>(PCODEToPINSTR(m_RegDisplay.GetIP())));
m_RegDisplay.SetIP(ReturnAddressToCanonicalPC(m_RegDisplay.GetIP()));
SetControlPC(dac_cast<PTR_VOID>(m_RegDisplay.GetIP()));

PTR_VOID collapsingTargetFrame = NULL;

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/nativeaot/Runtime/arm64/AsmMacros.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ TrashRegister32Bit SETS "w":CC:("$TrashRegister32Bit":RIGHT:((:LEN:TrashRegister
str $trashReg1, [$trashReg2]
str xzr, [$threadReg, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation]
str xzr, [$threadReg, #OFFSETOF__Thread__m_pvHijackedReturnAddress]
str xzr, [$threadReg, #OFFSETOF__Thread__m_pSpForPacSign]
0
MEND

Expand Down
1 change: 1 addition & 0 deletions src/coreclr/nativeaot/Runtime/arm64/ExceptionHandling.S
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ LOCAL_LABEL(ClearThreadState):
// clear the Thread's hijack state
str xzr, [x2, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation]
str xzr, [x2, #OFFSETOF__Thread__m_pvHijackedReturnAddress]
str xzr, [x2, #OFFSETOF__Thread__m_pSpForPacSign]

LOCAL_LABEL(NotHijacked):

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ ClearThreadState
;; clear the Thread's hijack state
str xzr, [x2, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation]
str xzr, [x2, #OFFSETOF__Thread__m_pvHijackedReturnAddress]
str xzr, [x2, #OFFSETOF__Thread__m_pSpForPacSign]

NotHijacked

Expand Down
15 changes: 11 additions & 4 deletions src/coreclr/nativeaot/Runtime/arm64/GcProbe.S
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <unixasmmacros.inc>
#include "AsmOffsets.inc"

.arch_extension pauth

#define PROBE_FRAME_SIZE 0x140 // 4 * 8 for fixed part of PInvokeTransitionFrame (fp, lr, m_pThread, m_Flags) +
// 10 * 8 for callee saved registers +
// 1 * 8 for caller SP +
Expand Down Expand Up @@ -103,7 +105,7 @@
// x9: thread pointer
// x0-x7, q0-q7 preserved, x10 trashed
//
.macro FixupHijackedCallstack
.macro FixupHijackedCallstack clearHijackState

// x9 <- GetThread()

Expand Down Expand Up @@ -150,22 +152,27 @@
#endif

//
// Fix the stack by restoring the original return address
// Fix the stack by restoring and authenticating the original return address.
//
ldr lr, [x9, #OFFSETOF__Thread__m_pvHijackedReturnAddress]
ldr x16, [x9, #OFFSETOF__Thread__m_pSpForPacSign]
cbz x16, \clearHijackState
autia lr, x16

\clearHijackState:
//
// Clear hijack state
//
// Clear m_ppvHijackedReturnAddressLocation and m_pvHijackedReturnAddress
// Clear m_ppvHijackedReturnAddressLocation, m_pvHijackedReturnAddress, and m_pSpForPacSign
stp xzr, xzr, [x9, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation]
str xzr, [x9, #OFFSETOF__Thread__m_pSpForPacSign]
.endm

//
// GC Probe Hijack target
//
NESTED_ENTRY RhpGcProbeHijack, _TEXT, NoHandler
FixupHijackedCallstack
FixupHijackedCallstack LOCAL_LABEL(RhpGcProbeClearHijackState)

PREPARE_EXTERNAL_VAR_INDIRECT_W RhpTrapThreads, 10
tbnz x10, #TrapThreadsFlags_TrapThreads_Bit, LOCAL_LABEL(WaitForGC)
Expand Down
17 changes: 11 additions & 6 deletions src/coreclr/nativeaot/Runtime/arm64/GcProbe.asm
Original file line number Diff line number Diff line change
Expand Up @@ -112,25 +112,30 @@ PROBE_FRAME_SIZE field 0
;;
;; Register state on exit:
;; x9: thread pointer
;; x0-x7 preserved, x10 trashed
;; x0-x7 preserved, x10 and x16 trashed
;;
MACRO
FixupHijackedCallstack
FixupHijackedCallstack $ClearHijackStateLabel

;; x9 <- GetThread(), TRASHES x10
INLINE_GETTHREAD x9, x10

;;
;; Fix the stack by restoring the original return address
;; Fix the stack by restoring and authenticating the original return address.
;;
ldr lr, [x9, #OFFSETOF__Thread__m_pvHijackedReturnAddress]
ldr x16, [x9, #OFFSETOF__Thread__m_pSpForPacSign]
cbz x16, $ClearHijackStateLabel
DCD 0xDAC1161E ;; autib lr, x16 instruction in binary to avoid requiring PAC-enabled assemblers

$ClearHijackStateLabel
;;
;; Clear hijack state
;;
ASSERT OFFSETOF__Thread__m_pvHijackedReturnAddress == (OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation + 8)
;; Clear m_ppvHijackedReturnAddressLocation and m_pvHijackedReturnAddress
;; Clear m_ppvHijackedReturnAddressLocation, m_pvHijackedReturnAddress, and m_pSpForPacSign
stp xzr, xzr, [x9, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation]
str xzr, [x9, #OFFSETOF__Thread__m_pSpForPacSign]
MEND

MACRO
Expand All @@ -154,7 +159,7 @@ PROBE_FRAME_SIZE field 0
HijackTargetFakeProlog

LABELED_RETURN_ADDRESS RhpGcProbeHijack
FixupHijackedCallstack
FixupHijackedCallstack RhpGcProbeClearHijackState

ldr x10, =RhpTrapThreads
ldr w10, [x10]
Expand Down Expand Up @@ -201,7 +206,7 @@ WaitForGC
;;
;;
LEAF_ENTRY RhpGcStressHijack
FixupHijackedCallstack
FixupHijackedCallstack RhpGcStressClearHijackState
mov x12, #(DEFAULT_FRAME_SAVE_FLAGS + PTFF_SAVE_X0 + PTFF_SAVE_X1 + PTFF_SAVE_X2 + PTFF_SAVE_X3 + PTFF_SAVE_X4 + PTFF_SAVE_X5 + PTFF_SAVE_X6 + PTFF_SAVE_X7)
b RhpGcStressProbe
LEAF_END RhpGcStressHijack
Expand Down
31 changes: 31 additions & 0 deletions src/coreclr/nativeaot/Runtime/arm64/MiscStubs.S
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,34 @@

#include <unixasmmacros.inc>
#include "AsmOffsets.inc"

// void* PacStripPtr(void *);
// This function strips the pointer of PAC info that is passed as an argument.
// We prefer to strip a pointer where it's not going to be used to branch execution to.
.arch_extension pauth
LEAF_ENTRY PacStripPtr, _TEXT
xpaci x0
ret
LEAF_END PacStripPtr, _TEXT

// void* PacSignPtr(void *, void *);
// This function signs the input pointer using x1 as salt. It is a no-op on non-PAC enabled machines.
.arch_extension pauth
LEAF_ENTRY PacSignPtr, _TEXT
mov x17, x0
mov x16, x1
pacia1716
mov x0, x17
ret
LEAF_END PacSignPtr, _TEXT

// void* PacAuthPtr(void *, void *);
// This function authenticates the input signed-pointer using x1 as salt. It is a no-op on non-PAC enabled machines.
.arch_extension pauth
LEAF_ENTRY PacAuthPtr, _TEXT
mov x17, x0
mov x16, x1
autia1716
mov x0, x17
ret
LEAF_END PacAuthPtr, _TEXT
Loading
Loading