diff options
Diffstat (limited to 'Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp')
-rw-r--r-- | Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp b/Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp new file mode 100644 index 000000000..66947fd59 --- /dev/null +++ b/Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2013 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" + +#include "StructuredExceptionHandlerSuppressor.h" + +#if defined(_M_IX86) +extern "C" int __stdcall exceptionHandlerThunk(); // Defined in makesafeseh.asm +#endif + +static bool exceptionShouldTerminateProgram(int code) +{ + switch (code) { +#ifndef NDEBUG + case EXCEPTION_DATATYPE_MISALIGNMENT: + case EXCEPTION_FLT_DENORMAL_OPERAND: + case EXCEPTION_FLT_DIVIDE_BY_ZERO: + case EXCEPTION_FLT_INEXACT_RESULT: + case EXCEPTION_FLT_INVALID_OPERATION: + case EXCEPTION_FLT_OVERFLOW: + case EXCEPTION_FLT_STACK_CHECK: + case EXCEPTION_FLT_UNDERFLOW: +#endif + case EXCEPTION_ACCESS_VIOLATION: + case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: + case EXCEPTION_INT_DIVIDE_BY_ZERO: + case EXCEPTION_INT_OVERFLOW: + case EXCEPTION_PRIV_INSTRUCTION: + case EXCEPTION_IN_PAGE_ERROR: + case EXCEPTION_ILLEGAL_INSTRUCTION: + case EXCEPTION_NONCONTINUABLE_EXCEPTION: + case EXCEPTION_STACK_OVERFLOW: + case EXCEPTION_INVALID_DISPOSITION: + case EXCEPTION_GUARD_PAGE: + case EXCEPTION_INVALID_HANDLE: + return true; + }; + + return false; +} + +extern "C" EXCEPTION_DISPOSITION __stdcall exceptionHandler(struct _EXCEPTION_RECORD* exceptionRecord, void* /*establisherFrame*/, struct _CONTEXT* /*contextRecord*/, void* /*dispatcherContext*/) +{ + if (exceptionShouldTerminateProgram(exceptionRecord->ExceptionCode)) + abort(); + + return ExceptionContinueSearch; +} + +namespace WebCore { + +#pragma warning(push) +#pragma warning(disable: 4733) // Disable "not registered as safe handler" warning + +StructuredExceptionHandlerSuppressor::StructuredExceptionHandlerSuppressor(ExceptionRegistration& exceptionRegistration) +{ +#if defined(_M_IX86) + // Note: Windows requires that the EXCEPTION_REGISTRATION block (modeled here as our + // ExceptionRegistration struct) be stack allocated. Therefore we instantiated it prior + // to building this object so that Windows can still find it in stack memory when it + // attempts to use the handler. + + // Windows puts an __try/__except block around some calls, such as hooks. + // The exception handler then ignores system exceptions like invalid addresses + // and null pointers. This class can be used to remove this block and prevent + // it from catching the exception. Typically this will cause the exception to crash + // which is often desirable to allow crashlogs to be recorded for debugging purposed. + // While this class is in scope we replace the Windows exception handler with a custom + // handler that indicates exceptions that should not be handled. + // + // See http://www.microsoft.com/msj/0197/Exception/Exception.aspx, + // http://www.microsoft.com/msj/archive/S2CE.aspx + // http://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf + // http://www.codeproject.com/Articles/2126/How-a-C-compiler-implements-exception-handling + + // Windows doesn't like assigning to member variables, so we need to get the value into + // a local variable and store it afterwards. + void* registration; + + // Note: The FS register on Windows always holds the Thread Information Block. + // FS:[0] points to the structured exception handling chain (a chain of + // EXCEPTION_REGISTRATION structs). + // + // struct EXCEPTION_REGISTRATION + // { + // DWORD next; + // DWORD handler; + // }; + // + // The first four bytes of FS:[0] point to the 'Next' member in the chain. Grab it so we can restore it later. + __asm mov eax, FS:[0] + __asm mov [registration], eax + + exceptionRegistration.prev = (ExceptionRegistration*)registration; + exceptionRegistration.handler = (void*)exceptionHandlerThunk; + + void* erStructMem = &exceptionRegistration; + + __asm mov eax, erStructMem + __asm mov FS:[0], eax + + m_savedExceptionRegistration = registration; +#else + // 64-bit x64 no longer needs dynamic modification of the exception handlers. +#endif +} + +StructuredExceptionHandlerSuppressor::~StructuredExceptionHandlerSuppressor() +{ +#if defined(_M_IX86) + // Restore the exception handler + __asm mov eax, [m_savedExceptionRegistration] + __asm mov FS:[0], eax +#else +#endif +} + +#pragma warning(pop) + +} |