summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp')
-rw-r--r--Source/WebCore/platform/win/StructuredExceptionHandlerSuppressor.cpp143
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)
+
+}