diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2017-02-24 21:29:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-24 21:29:15 +0100 |
commit | d97861ce3fecc41b35d4c2e61f60ab7e54eedee8 (patch) | |
tree | ecc06a1471b7bde74d1f328d09a3dc35b4fb5a2c /src/pal | |
parent | 12f575c6043e0316429df7c331121ddaefe30097 (diff) | |
download | coreclr-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.inc | 1 | ||||
-rw-r--r-- | src/pal/src/arch/amd64/signalhandlerhelper.cpp | 22 | ||||
-rw-r--r-- | src/pal/src/arch/arm/signalhandlerhelper.cpp | 22 | ||||
-rw-r--r-- | src/pal/src/arch/arm64/callsignalhandlerwrapper.S | 6 | ||||
-rw-r--r-- | src/pal/src/arch/arm64/signalhandlerhelper.cpp | 24 | ||||
-rw-r--r-- | src/pal/src/arch/i386/signalhandlerhelper.cpp | 13 | ||||
-rw-r--r-- | src/pal/src/exception/signal.cpp | 33 | ||||
-rw-r--r-- | src/pal/src/include/pal/context.h | 6 |
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. */ |