Skip to content
Merged
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
17 changes: 17 additions & 0 deletions src/coreclr/pal/inc/unixasmmacrosarm64.inc
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,20 @@ $__RedirectionStubEndFuncName
#endif

.endm

//-----------------------------------------------------------------------------
// Macro used to check (in debug builds only) whether the stack is 16-bytes aligned (a requirement before calling
// out into C++/OS code). Invoke this directly after your prolog (if the stack frame size is fixed) or directly
// before a call (if you have a frame pointer and a dynamic stack). A breakpoint will be invoked if the stack
// is misaligned.
//
.macro CHECK_STACK_ALIGNMENT

#ifdef _DEBUG
add x9, sp, xzr
tst x9, #15
beq 0f
EMIT_BREAKPOINT
0:
#endif
.endm
1 change: 1 addition & 0 deletions src/coreclr/vm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@ else(CLR_CMAKE_TARGET_WIN32)
${ARCH_SOURCES_DIR}/jithelpers_singleappdomain.S
${ARCH_SOURCES_DIR}/jithelpers_slow.S
${ARCH_SOURCES_DIR}/pinvokestubs.S
${ARCH_SOURCES_DIR}/redirectedhandledjitcase.S
${ARCH_SOURCES_DIR}/theprestubamd64.S
${ARCH_SOURCES_DIR}/thunktemplates.S
${ARCH_SOURCES_DIR}/unixasmhelpers.S
Expand Down
96 changes: 96 additions & 0 deletions src/coreclr/vm/amd64/redirectedhandledjitcase.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

.intel_syntax noprefix
#include "unixasmmacros.inc"
#include "asmconstants.h"

#define FaultingExceptionFrame_StackAlloc (SIZEOF__GSCookie + SIZEOF__FaultingExceptionFrame)
#define FaultingExceptionFrame_FrameOffset SIZEOF__GSCookie
#define OFFSET_OF_FRAME (8 + SIZEOF_GSCookie)

.macro GenerateRedirectedStubWithFrame stub, target

//
// This is the primary function to which execution will be redirected to.
//
NESTED_ENTRY \stub, _TEXT, NoHandler

//
// IN: rdi: original IP before redirect
// rsi: Rip from the Thread::GetAbortContext()
//

mov rdx, rsp

// This push of the return address must not be recorded in the unwind
// info. After this push, unwinding will work.
push rdi

test rsp, 0x0f
jnz C_FUNC(\stub\()_FixRsp)

LOCAL_LABEL(\stub\()_RspAligned):

// Any stack operations hereafter must be recorded in the unwind info, but
// only nonvolatile register locations are needed. Anything else is only
// a "sub rsp, 8" to the unwinder.

alloc_stack OFFSET_OF_FRAME + SIZEOF__FaultingExceptionFrame

END_PROLOGUE

lea rdi, [rsp + OFFSET_OF_FRAME]

mov dword ptr [rdi], 0 // Initialize vtbl (it is not strictly necessary)
mov dword ptr [rdi + OFFSETOF__FaultingExceptionFrame__m_fFilterExecuted], 0 // Initialize BOOL for personality routine

call C_FUNC(\target)

// Target should not return.
int 3

NESTED_END \stub, _TEXT

// This function is used by the stub above to adjust the stack alignment. The
// stub can't conditionally push something on the stack because the unwind
// encodings have no way to express that.
//
// CONSIDER: we could move the frame pointer above the FaultingExceptionFrame,
// and detect the misalignment adjustment in
// GetFrameFromRedirectedStubStackFrame. This is probably less code and more
// straightforward.
LEAF_ENTRY \stub\()_FixRsp, _TEXT

call LOCAL_LABEL(\stub\()_RspAligned)

// Target should not return.
int 3

LEAF_END \stub\()_FixRsp, _TEXT

.endm

REDIRECT_FOR_THROW_CONTROL_FRAME_SIZE = 8

NESTED_ENTRY RedirectForThrowControl2, _TEXT, NoHandler

// On entry
// rdi -> FaultingExceptionFrame
// rsi -> Rip from the Thread::GetAbortContext()
// rdx -> Original RSP

push_register rax // Align stack

END_PROLOGUE

mov [rdx - 8], rsi // Set return address slot to the Rip from the Thread::GetAbortContext()

call C_FUNC(ThrowControlForThread)

// ThrowControlForThread doesn't return.
int 3

NESTED_END RedirectForThrowControl2, _TEXT

GenerateRedirectedStubWithFrame RedirectForThrowControl, RedirectForThrowControl2
5 changes: 0 additions & 5 deletions src/coreclr/vm/amd64/unixstubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@

extern "C"
{
void RedirectForThrowControl()
{
PORTABILITY_ASSERT("Implement for PAL");
}

void STDMETHODCALLTYPE JIT_ProfilerEnterLeaveTailcallStub(UINT_PTR ProfilerHandle)
{
}
Expand Down
25 changes: 25 additions & 0 deletions src/coreclr/vm/arm/ehhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,31 @@ OFFSET_OF_FRAME=(4 + SIZEOF__GSCookie)

.endm

// ------------------------------------------------------------------
//
// Helpers for ThreadAbort exceptions
//

NESTED_ENTRY RedirectForThreadAbort2, _TEXT, NoHandler
PROLOG_PUSH "{r7, lr}"

// stack must be 8 byte aligned
CHECK_STACK_ALIGNMENT

// On entry:
//
// r0 = address of FaultingExceptionFrame
//
// Invoke the helper to setup the FaultingExceptionFrame and raise the exception
bl C_FUNC(ThrowControlForThread)

// ThrowControlForThread doesn't return.
EMIT_BREAKPOINT

NESTED_END RedirectForThreadAbort2, _TEXT

GenerateRedirectedStubWithFrame RedirectForThreadAbort, RedirectForThreadAbort2

// ------------------------------------------------------------------

// This helper enables us to call into a funclet after applying the non-volatiles
Expand Down
13 changes: 0 additions & 13 deletions src/coreclr/vm/arm/unixstubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,3 @@
// The .NET Foundation licenses this file to you under the MIT license.

#include "common.h"

extern "C"
{
void RedirectForThrowControl()
{
PORTABILITY_ASSERT("Implement for PAL");
}

void RedirectForThreadAbort()
{
PORTABILITY_ASSERT("Implement for PAL");
}
};
24 changes: 24 additions & 0 deletions src/coreclr/vm/arm64/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,30 @@ NESTED_END CallEHFilterFunclet, _TEXT

.endm

// ------------------------------------------------------------------
//
// Helpers for ThreadAbort exceptions
//

NESTED_ENTRY RedirectForThreadAbort2, _TEXT, NoHandler
PROLOG_SAVE_REG_PAIR_INDEXED fp,lr, -16

// stack must be 16 byte aligned
CHECK_STACK_ALIGNMENT

// On entry:
//
// x0 = address of FaultingExceptionFrame
//
// Invoke the helper to setup the FaultingExceptionFrame and raise the exception
bl C_FUNC(ThrowControlForThread)

// ThrowControlForThread doesn't return.
EMIT_BREAKPOINT

NESTED_END RedirectForThreadAbort2, _TEXT

GenerateRedirectedStubWithFrame RedirectForThreadAbort, RedirectForThreadAbort2

// ------------------------------------------------------------------
// ResolveWorkerChainLookupAsmStub
Expand Down
13 changes: 0 additions & 13 deletions src/coreclr/vm/arm64/unixstubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,3 @@
// The .NET Foundation licenses this file to you under the MIT license.

#include "common.h"

extern "C"
{
void RedirectForThrowControl()
{
PORTABILITY_ASSERT("Implement for PAL");
}

void RedirectForThreadAbort()
{
PORTABILITY_ASSERT("Implement for PAL");
}
};
7 changes: 6 additions & 1 deletion src/coreclr/vm/exceptionhandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ UINT_PTR ExceptionTracker::FinishSecondPass(
{
CopyOSContext(pThread->m_OSContext, pContextRecord);
SetIP(pThread->m_OSContext, (PCODE)uResumePC);
#ifdef TARGET_UNIX
#if defined(TARGET_UNIX) && !(defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_ARM))
uAbortAddr = NULL;
#else
uAbortAddr = (UINT_PTR)COMPlusCheckForAbort(uResumePC);
Expand Down Expand Up @@ -833,7 +833,12 @@ UINT_PTR ExceptionTracker::FinishSecondPass(
STRESS_LOG1(LF_EH, LL_INFO10, "resume under control: ip: %p\n", uResumePC);

#ifdef TARGET_AMD64
#ifdef TARGET_UNIX
pContextRecord->Rdi = uResumePC;
pContextRecord->Rsi = GetIP(pThread->GetAbortContext());
#else
pContextRecord->Rcx = uResumePC;
#endif
#elif defined(TARGET_ARM) || defined(TARGET_ARM64)
// On ARM & ARM64, we save off the original PC in Lr. This is the same as done
// in HandleManagedFault for H/W generated exceptions.
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/threadsuspend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3956,7 +3956,9 @@ ThrowControlForThread(
STRESS_LOG0(LF_SYNC, LL_INFO100, "ThrowControlForThread Aborting\n");

// Here we raise an exception.
INSTALL_MANAGED_EXCEPTION_DISPATCHER
RaiseComPlusException();
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER
}

#if defined(FEATURE_HIJACK) && !defined(TARGET_UNIX)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,6 @@ void Test()
_caughtException = true;
}

if (!PlatformDetection.IsWindows)
{
// Rethrowing a ThreadAbortException at the end of catch blocks is not implemented, so force it
// here by calling native code (https://github.com/dotnet/runtime/issues/72703).
Thread.Sleep(0);
}

_finishedExecution = true;
}
}
Expand Down