Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions src/coreclr/debug/ee/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
#include "../../vm/methoditer.h"
#include "../../vm/tailcallhelp.h"

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

const char *GetTType( TraceType tt);

#define IsSingleStep(exception) ((exception) == EXCEPTION_SINGLE_STEP)
Expand Down
77 changes: 70 additions & 7 deletions src/coreclr/unwinder/arm64/unwinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
#define FIELD_OFFSET(type, field) ((LONG)__builtin_offsetof(type, field))
#endif

#if !defined(DACCESS_COMPILE)
extern "C" void* PacAuthPtr(void* ptr, void* sp);
#endif // !defined(DACCESS_COMPILE)

#ifdef HOST_UNIX
#define RtlZeroMemory ZeroMemory

Expand Down Expand Up @@ -251,16 +255,75 @@ do {

#endif // !defined(DEBUGGER_UNWIND)

//
// Macros for stripping pointer authentication (PAC) bits.
//
#if !defined(DACCESS_COMPILE)

#if !defined(DEBUGGER_STRIP_PAC)
#define HANDLE_PAC(pointer, sp) RtlHandlePacOnline(pointer, sp)

// NOTE: Pointer authentication is not used by .NET, so the implementation does nothing
#define STRIP_PAC(Params, pointer)
FORCEINLINE
VOID RtlHandlePacOnline(_Inout_ PULONG64 Pointer, _In_ ULONG64 Sp)

#endif
/*++

Routine Description:

This routine authenticates an ARM64 pointer authenticated with PACIASP
using the supplied stack pointer as the modifier. Hence this should only
be called when authenticating a pointer at runtime (not debugger).

Arguments:

Pointer - Supplies a pointer to the pointer whose PAC will be authenticated.

Sp - Supplies the stack pointer value that was used as the PAC modifier.

Return Value:

None.

--*/

{
*Pointer = (ULONG64)PacAuthPtr((void *)(*Pointer), (void *)Sp);
}
#else

#define HANDLE_PAC(pointer, sp) RtlStripPacManual(pointer, sp)

FORCEINLINE
VOID
RtlStripPacManual(
_Inout_ PULONG64 Pointer,
_In_ ULONG64 Sp
)
/*++

Routine Description:

This routine manually strips the ARM64 Pointer Authentication Code (PAC)
from a pointer. This is functionally similar to the XPAC family of
instructions.

N.B. Even though PAC is only supported on ARM64, this routine is available
on all architectures to conveniently enable scenarios such as the
Debugger.

Arguments:

Pointer - Supplies a pointer to the pointer whose PAC will be stripped.

Return Value:

None.

--*/
{
UNREFERENCED_PARAMETER(Sp);
*Pointer &= 0x0000FFFFFFFFFFFF;
return;
}

#endif // !defined(DACCESS_COMPILE)

//
// Macros to clarify opcode parsing
Expand Down Expand Up @@ -2343,7 +2406,7 @@ Return Value:
return STATUS_UNWIND_INVALID_SEQUENCE;
}

STRIP_PAC(UnwindParams, &ContextRecord->Lr);
HANDLE_PAC(&ContextRecord->Lr, ContextRecord->Sp);

//
// TODO: Implement support for UnwindFlags RTL_VIRTUAL_UNWIND2_VALIDATE_PAC.
Expand Down
36 changes: 36 additions & 0 deletions src/coreclr/vm/arm64/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,47 @@ NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler
EPILOG_RESTORE_REG_PAIR x25, x26, 64
EPILOG_RESTORE_REG_PAIR x27, x28, 80
EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 192
xpaclri
EPILOG_RETURN
NESTED_END OnHijackTripThread, _TEXT

#endif // FEATURE_HIJACK

// 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.
// To avoid failing on non-PAC enabled machines, we use pacia1716 which signs lr explicitly.
// Thus we need to move input in lr, sign it and then copy it back to the result register.
.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.
// To avoid failing on non-PAC enabled machines, we use pacia1716 which authenticates lr explicitly.
// Thus we need to move input in lr, authenticate it and then copy it back to the result register.
.arch_extension pauth
LEAF_ENTRY PacAuthPtr, _TEXT
mov x17, x0
mov x16, x1
autia1716
mov x0, x17
ret
LEAF_END PacAuthPtr, _TEXT

// ------------------------------------------------------------------
// Redirection Stub for GC in fully interruptible method
//GenerateRedirectedHandledJITCaseStub GCThreadControl
Expand Down
34 changes: 34 additions & 0 deletions src/coreclr/vm/arm64/asmhelpers.asm
Original file line number Diff line number Diff line change
Expand Up @@ -311,11 +311,45 @@ NoFloatingPointRetVal
EPILOG_RESTORE_REG_PAIR x25, x26, #64
EPILOG_RESTORE_REG_PAIR x27, x28, #80
EPILOG_RESTORE_REG_PAIR fp, lr, #192!

DCD 0xD50320FF ; xpaclri instruction in binary to avoid error while compiling with non-PAC enabled compilers
EPILOG_RETURN
NESTED_END

#endif ; FEATURE_HIJACK

; 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.
LEAF_ENTRY PacStripPtr
DCD 0xDAC143E0 ; xpaci x0 instruction in binary to avoid requiring PAC-enabled assemblers
ret
LEAF_END PacStripPtr

; void* PacSignPtr(void *, void *);
; This function signs the input pointer using x1 as salt.
; To avoid failing on non-PAC enabled machines, we use pacib1716 which signs lr explicitly.
; Thus we need to move input in lr, sign it and then copy it back to the result register.
LEAF_ENTRY PacSignPtr
mov x17, x0
mov x16, x1
DCD 0xD503215F ; pacib1716 instruction in binary to avoid error while compiling with non-PAC enabled compilers
mov x0, x17
ret
LEAF_END PacSignPtr

; void* PacAuthPtr(void *, void *);
; This function authenticates the input signed-pointer using x1 as salt.
; To avoid failing on non-PAC enabled machines, we use autib1716 which authenticates lr explicitly.
; Thus we need to move input in lr, authenticate it and then copy it back to the result register.
LEAF_ENTRY PacAuthPtr
mov x17, x0
mov x16, x1
DCD 0xD50321DF ; autib1716 instruction in binary to avoid error while compiling with non-PAC enabled compilers
mov x0, x17
ret
LEAF_END PacAuthPtr

;; ------------------------------------------------------------------
;; Redirection Stub for GC in fully interruptible method
GenerateRedirectedHandledJITCaseStub GCThreadControl
Expand Down
6 changes: 5 additions & 1 deletion src/coreclr/vm/arm64/cgencpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ class ComCallMethodDesc;

extern PCODE GetPreStubEntryPoint();

#ifndef DACCESS_COMPILE
extern "C" void* PacAuthPtr(void* ptr, void* sp);
#endif

#define STACK_ALIGN_SIZE 16

#define JUMP_ALLOCATE_SIZE 16 // # bytes to allocate for a jump instruction
Expand Down Expand Up @@ -208,7 +212,7 @@ typedef struct _PROFILE_PLATFORM_SPECIFIC_DATA

inline PCODE GetIP(const T_CONTEXT * context) {
LIMITED_METHOD_DAC_CONTRACT;
return context->Pc;
return (PCODE) context->Pc;
}

inline void SetIP(T_CONTEXT *context, PCODE eip) {
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/arm64/stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ void HijackFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats
pRD->IsCallerContextValid = FALSE;
pRD->IsCallerSPValid = FALSE;

pRD->pCurrentContext->Pc = m_ReturnAddress;
pRD->pCurrentContext->Pc = GetReturnAddress();
size_t s = sizeof(struct HijackArgs);
_ASSERTE(s%8 == 0); // HijackArgs contains register values and hence will be a multiple of 8
// stack must be multiple of 16. So if s is not multiple of 16 then there must be padding of 8 bytes
Expand Down
Loading
Loading