Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2016-03-04 07:21:42 +0300
committerJan Kotas <jkotas@microsoft.com>2016-03-08 19:54:49 +0300
commitc2a2abeb5ec63c8329f56f78a1ccb7e8f7613164 (patch)
treece7283e4ff6a9f097b77f8070f95b39a1795b00e /src/Native/Runtime/EHHelpers.cpp
parenta15c0e8da841a8015093267bd98b8fb93e8a3e21 (diff)
Enable hardware exception handling on Windows
Diffstat (limited to 'src/Native/Runtime/EHHelpers.cpp')
-rw-r--r--src/Native/Runtime/EHHelpers.cpp108
1 files changed, 34 insertions, 74 deletions
diff --git a/src/Native/Runtime/EHHelpers.cpp b/src/Native/Runtime/EHHelpers.cpp
index 3ec63092d..a50bbf8b0 100644
--- a/src/Native/Runtime/EHHelpers.cpp
+++ b/src/Native/Runtime/EHHelpers.cpp
@@ -25,35 +25,38 @@
#include "thread.h"
#include "stressLog.h"
-// Find the module containing the given address, which might be a return address from a managed function. The
+// Find the code manager containing the given address, which might be a return address from a managed function. The
// address may be to another managed function, or it may be to an unmanaged function, or it may be to a GC
// hijack. The address may also refer to an EEType if we've been called from RhpGetClasslibFunction. If it is
-// a GC hijack, we will recgonize that and use the real return address, updating the address passed in.
-static Module * FindModuleRespectingReturnAddressHijacks(void * address)
+// a GC hijack, we will recognize that and use the real return address.
+static ICodeManager * FindCodeManagerRespectingReturnAddressHijacks(void * address)
{
RuntimeInstance * pRI = GetRuntimeInstance();
- // Try looking up the module assuming the address is for code first. This is expected to be most common.
- Module * pModule = pRI->FindModuleByCodeAddress(address);
- if (pModule == NULL)
+ // Try looking up the code manager assuming the address is for code first. This is expected to be most common.
+ ICodeManager * pCodeManager = pRI->FindCodeManagerByAddress(address);
+ if (pCodeManager != NULL)
+ return pCodeManager;
+
+ // @TODO: CORERT: Do we need to make this work for CoreRT?
+ // Less common, we will look for the address in any of the sections of the module. This is slower, but is
+ // necessary for EEType pointers and jump stubs.
+ Module * pModule = pRI->FindModuleByAddress(address);
+ if (pModule != NULL)
+ return pModule;
+
+ // Corner-case: The thread might be hijacked -- @TODO: this is a bit brittle because there is no validation that
+ // the hijacked return address from the thread is actually related to place where the caller got the hijack
+ // target.
+ Thread * pCurThread = ThreadStore::GetCurrentThread();
+ if (pCurThread->IsHijacked() && Thread::IsHijackTarget(address))
{
- // Less common, we will look for the address in any of the sections of the module. This is slower, but is
- // necessary for EEType pointers and jump stubs.
- pModule = pRI->FindModuleByAddress(address);
-
- // Corner-case: The thread might be hijacked -- @TODO: this is a bit brittle because there is no validation that
- // the hijacked return address from the thread is actually related to place where the caller got the hijack
- // target.
- Thread * pCurThread = ThreadStore::GetCurrentThread();
- if ((pModule == NULL) && pCurThread->IsHijacked() && Thread::IsHijackTarget(address))
- {
- pModule = pRI->FindModuleByCodeAddress(pCurThread->GetHijackedReturnAddress());
-
- ASSERT_MSG(pModule != NULL, "expected to find the module for a hijacked return address");
- }
+ ICodeManager * pCodeManagerForHijack = pRI->FindCodeManagerByAddress(pCurThread->GetHijackedReturnAddress());
+ ASSERT_MSG(pCodeManagerForHijack != NULL, "expected to find the module for a hijacked return address");
+ return pCodeManagerForHijack;
}
- return pModule;
+ return NULL;
}
COOP_PINVOKE_HELPER(Boolean, RhpEHEnumInitFromStackFrameIterator, (
@@ -70,68 +73,23 @@ COOP_PINVOKE_HELPER(Boolean, RhpEHEnumNext, (EHEnum* pEHEnum, EHClause* pEHClaus
return pEHEnum->m_pCodeManager->EHEnumNext(&pEHEnum->m_state, pEHClause);
}
-//------------------------------------------------------------------------------------------------------------
-// @TODO:EXCEPTIONS: the code below is related to throwing exceptions out of Rtm. If we did not have to throw
-// out of Rtm, then we would note have to have the code below to get a classlib exception object given
-// an exception id, or the special functions to back up the MDIL THROW_* instructions, or the allocation
-// failure helper. If we could move to a world where we never throw out of Rtm, perhaps by moving parts
-// of Rtm that do need to throw out to Bartok- or Binder-generated functions, then we could remove all of this.
-//------------------------------------------------------------------------------------------------------------
-
-
-// Constants used with RhpGetClasslibFunction, to indicate which classlib function
-// we are interested in.
-// Note: make sure you change the def in rtm\System\Runtime\exceptionhandling.cs if you change this!
-enum ClasslibFunctionId
-{
- GetRuntimeException = 0,
- FailFast = 1,
- UnhandledExceptionHandler = 2,
- AppendExceptionStackFrame = 3,
-};
-
// Unmanaged helper to locate one of two classlib-provided functions that the runtime needs to
// implement throwing of exceptions out of Rtm, and fail-fast. This may return NULL if the classlib
// found via the provided address does not have the necessary exports.
COOP_PINVOKE_HELPER(void *, RhpGetClasslibFunction, (void * address, ClasslibFunctionId functionId))
{
- // Find the module contianing the given address, which is an address into some managed module. It could
+ // Find the code manager for the given address, which is an address into some managed module. It could
// be code, or it could be an EEType. No matter what, it's an address into a managed module in some non-Rtm
// type system.
- Module * pModule = FindModuleRespectingReturnAddressHijacks(address);
-
+ ICodeManager * pCodeManager = FindCodeManagerRespectingReturnAddressHijacks(address);
+
// If the address isn't in a managed module then we have no classlib function.
- if (pModule == NULL)
+ if (pCodeManager == NULL)
{
return NULL;
}
- // Now, find the classlib module that the first module was compiled against. This one will contain definitions
- // for the classlib functions we need here at runtime.
- Module * pClasslibModule = pModule->GetClasslibModule();
- ASSERT(pClasslibModule != NULL);
-
- // Lookup the method and return it. If we don't find it, we just return NULL.
- void * pMethod = NULL;
-
- if (functionId == GetRuntimeException)
- {
- pMethod = pClasslibModule->GetClasslibRuntimeExceptionHelper();
- }
- else if (functionId == AppendExceptionStackFrame)
- {
- pMethod = pClasslibModule->GetClasslibAppendExceptionStackFrameHelper();
- }
- else if (functionId == FailFast)
- {
- pMethod = pClasslibModule->GetClasslibFailFastHelper();
- }
- else if (functionId == UnhandledExceptionHandler)
- {
- pMethod = pClasslibModule->GetClasslibUnhandledExceptionHandlerHelper();
- }
-
- return pMethod;
+ return pCodeManager->GetClasslibFunction(functionId);
}
COOP_PINVOKE_HELPER(void, RhpValidateExInfoStack, ())
@@ -437,7 +395,8 @@ Int32 __stdcall RhpVectoredExceptionHandler(PEXCEPTION_POINTERS pExPtrs)
return EXCEPTION_CONTINUE_EXECUTION;
}
- else
+
+#ifndef PLATFORM_UNIX
{
static UInt8 *s_pbRuntimeModuleLower = NULL;
static UInt8 *s_pbRuntimeModuleUpper = NULL;
@@ -466,9 +425,10 @@ Int32 __stdcall RhpVectoredExceptionHandler(PEXCEPTION_POINTERS pExPtrs)
ASSERT_UNCONDITIONALLY("Hardware exception raised inside the runtime.");
RhFailFast2(pExPtrs->ExceptionRecord, pExPtrs->ContextRecord);
}
-
- return EXCEPTION_CONTINUE_SEARCH;
}
+#endif // PLATFORM_UNIX
+
+ return EXCEPTION_CONTINUE_SEARCH;
}
COOP_PINVOKE_HELPER(void, RhpFallbackFailFast, ())