summaryrefslogtreecommitdiff
path: root/src/pal
diff options
context:
space:
mode:
authorJan Vorlicek <janvorli@microsoft.com>2017-02-24 21:29:15 +0100
committerGitHub <noreply@github.com>2017-02-24 21:29:15 +0100
commitd97861ce3fecc41b35d4c2e61f60ab7e54eedee8 (patch)
treeecc06a1471b7bde74d1f328d09a3dc35b4fb5a2c /src/pal
parent12f575c6043e0316429df7c331121ddaefe30097 (diff)
downloadcoreclr-d97861ce3fecc41b35d4c2e61f60ab7e54eedee8.tar.gz
coreclr-d97861ce3fecc41b35d4c2e61f60ab7e54eedee8.tar.bz2
coreclr-d97861ce3fecc41b35d4c2e61f60ab7e54eedee8.zip
Remove getcontext and setcontext usage (#9759)
It turns out that the getcontext and setcontext that I have used in my stack oveflow reporting change are not present e.g. on Alpine Linux or on Android. So I am replacing their usage with RtlCaptureContext and RtlRestoreContext instead. I have also found that the addition of the .cfi_adjust_cfa_offset to the PROLOG_SAVE_REG_PAIR has broken unwinding of all helpers that use PROLOG_WITH_TRANSITION_BLOCK, because the PROLOG_STACK_ALLOC macro updates the CFA offset. So I am fixing that by removing the CFA offset updating from the PROLOG_STACK_ALLOC and adding explicit one to the ARM64 CallSignalHandlerWrapper.
Diffstat (limited to 'src/pal')
-rw-r--r--src/pal/inc/unixasmmacrosarm64.inc1
-rw-r--r--src/pal/src/arch/amd64/signalhandlerhelper.cpp22
-rw-r--r--src/pal/src/arch/arm/signalhandlerhelper.cpp22
-rw-r--r--src/pal/src/arch/arm64/callsignalhandlerwrapper.S6
-rw-r--r--src/pal/src/arch/arm64/signalhandlerhelper.cpp24
-rw-r--r--src/pal/src/arch/i386/signalhandlerhelper.cpp13
-rw-r--r--src/pal/src/exception/signal.cpp33
-rw-r--r--src/pal/src/include/pal/context.h6
8 files changed, 47 insertions, 80 deletions
diff --git a/src/pal/inc/unixasmmacrosarm64.inc b/src/pal/inc/unixasmmacrosarm64.inc
index f391513ab2..34509f3e95 100644
--- a/src/pal/inc/unixasmmacrosarm64.inc
+++ b/src/pal/inc/unixasmmacrosarm64.inc
@@ -43,7 +43,6 @@ C_FUNC(\Name\()_End):
.macro PROLOG_STACK_ALLOC Size
sub sp, sp, \Size
- .cfi_adjust_cfa_offset \Size
.endm
.macro EPILOG_STACK_FREE Size
diff --git a/src/pal/src/arch/amd64/signalhandlerhelper.cpp b/src/pal/src/arch/amd64/signalhandlerhelper.cpp
index 5e37583a9f..8789f5a622 100644
--- a/src/pal/src/arch/amd64/signalhandlerhelper.cpp
+++ b/src/pal/src/arch/amd64/signalhandlerhelper.cpp
@@ -52,19 +52,19 @@ void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context,
*--sp = fakeFrameReturnAddress;
// Switch the current context to the signal_handler_worker and the original stack
- ucontext_t ucontext2;
- getcontext(&ucontext2);
+ CONTEXT context2;
+ RtlCaptureContext(&context2);
// We don't care about the other registers state since the stack unwinding restores
// them for the target frame directly from the signal context.
- MCREG_Rsp(ucontext2.uc_mcontext) = (size_t)sp;
- MCREG_Rbx(ucontext2.uc_mcontext) = (size_t)faultSp;
- MCREG_Rbp(ucontext2.uc_mcontext) = (size_t)fp;
- MCREG_Rip(ucontext2.uc_mcontext) = (size_t)signal_handler_worker;
- MCREG_Rdi(ucontext2.uc_mcontext) = code;
- MCREG_Rsi(ucontext2.uc_mcontext) = (size_t)siginfo;
- MCREG_Rdx(ucontext2.uc_mcontext) = (size_t)context;
- MCREG_Rcx(ucontext2.uc_mcontext) = (size_t)returnPoint;
+ context2.Rsp = (size_t)sp;
+ context2.Rbx = (size_t)faultSp;
+ context2.Rbp = (size_t)fp;
+ context2.Rip = (size_t)signal_handler_worker;
+ context2.Rdi = code;
+ context2.Rsi = (size_t)siginfo;
+ context2.Rdx = (size_t)context;
+ context2.Rcx = (size_t)returnPoint;
- setcontext(&ucontext2);
+ RtlRestoreContext(&context2, NULL);
}
diff --git a/src/pal/src/arch/arm/signalhandlerhelper.cpp b/src/pal/src/arch/arm/signalhandlerhelper.cpp
index beda0b441e..e1ad460905 100644
--- a/src/pal/src/arch/arm/signalhandlerhelper.cpp
+++ b/src/pal/src/arch/arm/signalhandlerhelper.cpp
@@ -52,19 +52,19 @@ void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context,
*--sp = (size_t)MCREG_R7(ucontext->uc_mcontext);
// Switch the current context to the signal_handler_worker and the original stack
- ucontext_t ucontext2;
- getcontext(&ucontext2);
+ CONTEXT context2;
+ RtlCaptureContext(&context2);
// We don't care about the other registers state since the stack unwinding restores
// them for the target frame directly from the signal context.
- MCREG_Sp(ucontext2.uc_mcontext) = (size_t)sp;
- MCREG_R7(ucontext2.uc_mcontext) = (size_t)sp; // Fp and Sp are the same
- MCREG_Lr(ucontext2.uc_mcontext) = fakeFrameReturnAddress;
- MCREG_Pc(ucontext2.uc_mcontext) = (size_t)signal_handler_worker;
- MCREG_R0(ucontext2.uc_mcontext) = code;
- MCREG_R1(ucontext2.uc_mcontext) = (size_t)siginfo;
- MCREG_R2(ucontext2.uc_mcontext) = (size_t)context;
- MCREG_R3(ucontext2.uc_mcontext) = (size_t)returnPoint;
+ context2.Sp = (size_t)sp;
+ context2.R7 = (size_t)sp; // Fp and Sp are the same
+ context2.Lr = fakeFrameReturnAddress;
+ context2.Pc = (size_t)signal_handler_worker;
+ context2.R0 = code;
+ context2.R1 = (size_t)siginfo;
+ context2.R2 = (size_t)context;
+ context2.R3 = (size_t)returnPoint;
- setcontext(&ucontext2);
+ RtlRestoreContext(&context2, NULL);
}
diff --git a/src/pal/src/arch/arm64/callsignalhandlerwrapper.S b/src/pal/src/arch/arm64/callsignalhandlerwrapper.S
index 6bff23b7be..90fb602479 100644
--- a/src/pal/src/arch/arm64/callsignalhandlerwrapper.S
+++ b/src/pal/src/arch/arm64/callsignalhandlerwrapper.S
@@ -15,12 +15,14 @@ C_FUNC(SignalHandlerWorkerReturnOffset\Alignment):
// address set to SignalHandlerWorkerReturn during SIGSEGV handling.
// It enables the unwinder to unwind stack from the handling code to the actual failure site.
NESTED_ENTRY CallSignalHandlerWrapper\Alignment, _TEXT, NoHandler
- PROLOG_STACK_ALLOC (128 + 8 + 8 + \Alignment) // red zone + fp + lr + alignment
+__StackAllocationSize = (128 + 8 + 8 + \Alignment) // red zone + fp + lr + alignment
+ PROLOG_STACK_ALLOC __StackAllocationSize
+ .cfi_adjust_cfa_offset __StackAllocationSize
PROLOG_SAVE_REG_PAIR fp, lr, 0
bl EXTERNAL_C_FUNC(signal_handler_worker)
LOCAL_LABEL(SignalHandlerWorkerReturn\Alignment):
EPILOG_RESTORE_REG_PAIR fp, lr, 0
- EPILOG_STACK_FREE (128 + 8 + 8 + \Alignment)
+ EPILOG_STACK_FREE __StackAllocationSize
ret
NESTED_END CallSignalHandlerWrapper\Alignment, _TEXT
diff --git a/src/pal/src/arch/arm64/signalhandlerhelper.cpp b/src/pal/src/arch/arm64/signalhandlerhelper.cpp
index 3891b9ea7f..c35c629ab3 100644
--- a/src/pal/src/arch/arm64/signalhandlerhelper.cpp
+++ b/src/pal/src/arch/arm64/signalhandlerhelper.cpp
@@ -51,19 +51,17 @@ void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context,
*--sp = (size_t)MCREG_Fp(ucontext->uc_mcontext);
// Switch the current context to the signal_handler_worker and the original stack
- ucontext_t ucontext2;
- getcontext(&ucontext2);
+ CONTEXT context2;
+ RtlCaptureContext(&context2);
- // We don't care about the other registers state since the stack unwinding restores
- // them for the target frame directly from the signal context.
- MCREG_Sp(ucontext2.uc_mcontext) = (size_t)sp;
- MCREG_Fp(ucontext2.uc_mcontext) = (size_t)sp; // Fp and Sp are the same
- MCREG_Lr(ucontext2.uc_mcontext) = fakeFrameReturnAddress;
- MCREG_Pc(ucontext2.uc_mcontext) = (size_t)signal_handler_worker;
- MCREG_X0(ucontext2.uc_mcontext) = code;
- MCREG_X1(ucontext2.uc_mcontext) = (size_t)siginfo;
- MCREG_X2(ucontext2.uc_mcontext) = (size_t)context;
- MCREG_X3(ucontext2.uc_mcontext) = (size_t)returnPoint;
+ context2.Sp = (size_t)sp;
+ context2.Fp = (size_t)sp;
+ context2.Lr = fakeFrameReturnAddress;
+ context2.Pc = (size_t)signal_handler_worker;
+ context2.X0 = code;
+ context2.X1 = (size_t)siginfo;
+ context2.X2 = (size_t)context;
+ context2.X3 = (size_t)returnPoint;
- setcontext(&ucontext2);
+ RtlRestoreContext(&context2, NULL);
}
diff --git a/src/pal/src/arch/i386/signalhandlerhelper.cpp b/src/pal/src/arch/i386/signalhandlerhelper.cpp
index 5e7333ad3d..3369abe093 100644
--- a/src/pal/src/arch/i386/signalhandlerhelper.cpp
+++ b/src/pal/src/arch/i386/signalhandlerhelper.cpp
@@ -64,14 +64,15 @@ void ExecuteHandlerOnOriginalStack(int code, siginfo_t *siginfo, void *context,
*--sp = fakeFrameReturnAddress;
// Switch the current context to the signal_handler_worker and the original stack
- ucontext_t ucontext2;
- getcontext(&ucontext2);
+ CONTEXT context2;
+ RtlCaptureContext(&context2);
// We don't care about the other registers state since the stack unwinding restores
// them for the target frame directly from the signal context.
- MCREG_Esp(ucontext2.uc_mcontext) = (size_t)sp;
- MCREG_Ebp(ucontext2.uc_mcontext) = (size_t)fp;
- MCREG_Eip(ucontext2.uc_mcontext) = (size_t)signal_handler_worker;
+ context2.Esp = (size_t)sp;
+ context2.ResumeEsp = (size_t)sp;
+ context2.Ebp = (size_t)fp;
+ context2.Eip = (size_t)signal_handler_worker;
- setcontext(&ucontext2);
+ RtlRestoreContext(&context2, NULL);
}
diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp
index ee7f7ce85f..18560eba8e 100644
--- a/src/pal/src/exception/signal.cpp
+++ b/src/pal/src/exception/signal.cpp
@@ -47,33 +47,6 @@ SET_DEFAULT_DEBUG_CHANNEL(EXCEPT); // some headers have code with asserts, so do
#include "pal/context.h"
-#ifdef __ANDROID__
-// getcontext and setcontext are not available natively on Android
-int getcontext(ucontext_t *ucp)
-{
- CONTEXT context;
- RtlCaptureContext(&context);
- CONTEXTToNativeContext(&context, ucp);
-
- return 0;
-}
-
-int setcontext(const ucontext_t *ucp)
-{
- CONTEXT context;
- ULONG contextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT;
-
-#if defined(_AMD64_)
- contextFlags |= CONTEXT_XSTATE;
-#endif
-
- CONTEXTFromNativeContext(ucp, &context, contextFlags);
- RtlRestoreContext(&context, NULL);
-
- return 0;
-}
-#endif
-
using namespace CorUnix;
#ifdef SIGRTMIN
@@ -98,7 +71,7 @@ typedef void (*SIGFUNC)(int, siginfo_t *, void *);
struct SignalHandlerWorkerReturnPoint
{
bool returnFromHandler;
- ucontext_t context;
+ CONTEXT context;
};
/* internal function declarations *********************************************/
@@ -419,7 +392,7 @@ extern "C" void signal_handler_worker(int code, siginfo_t *siginfo, void *contex
// fault. We must disassemble the instruction at record.ExceptionAddress
// to correctly fill in this value.
returnPoint->returnFromHandler = common_signal_handler(code, siginfo, context, 2, (size_t)0, (size_t)siginfo->si_addr);
- setcontext(&returnPoint->context);
+ RtlRestoreContext(&returnPoint->context, NULL);
}
/*++
@@ -457,7 +430,7 @@ static void sigsegv_handler(int code, siginfo_t *siginfo, void *context)
volatile bool contextInitialization = true;
SignalHandlerWorkerReturnPoint returnPoint;
- getcontext(&returnPoint.context);
+ RtlCaptureContext(&returnPoint.context);
// When the signal handler worker completes, it uses setcontext to return to this point
diff --git a/src/pal/src/include/pal/context.h b/src/pal/src/include/pal/context.h
index 782a51bcba..db6d69579a 100644
--- a/src/pal/src/include/pal/context.h
+++ b/src/pal/src/include/pal/context.h
@@ -29,12 +29,6 @@ extern "C"
#include <signal.h>
#include <pthread.h>
-#ifdef __ANDROID__
-// getcontext and setcontext are not available natively on Android
-int setcontext(const ucontext_t *ucp);
-int getcontext(ucontext_t* ucp);
-#endif
-
#if !HAVE_MACH_EXCEPTIONS
/* A type to wrap the native context type, which is ucontext_t on some
* platforms and another type elsewhere. */