[x86/linux] Add IsIPinVirtualStub() on x86/linux (dotnet/coreclr#9844)
authorYongseop Kim <yons.kim@samsung.com>
Wed, 1 Mar 2017 14:52:35 +0000 (23:52 +0900)
committerJan Vorlicek <janvorli@microsoft.com>
Wed, 1 Mar 2017 14:52:35 +0000 (15:52 +0100)
* [x86/linux] Add IsIPinVirtualStub() on x86/linux dotnet/coreclr#9691

To pass Loader.classloader.methodoverriding.regressions.549411.exploit
test failure on x86/linux. This patch is from dotnet/coreclr#5542.

Commit migrated from https://github.com/dotnet/coreclr/commit/e491a912e393610f1c987f1f814fdd3d04160479

src/coreclr/src/vm/arm/exceparm.cpp
src/coreclr/src/vm/arm/excepcpu.h
src/coreclr/src/vm/exceptionhandling.cpp

index 6852adc..9b14d41 100644 (file)
@@ -54,38 +54,6 @@ FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame (T_DISPATCHER_CONTE
     return (FaultingExceptionFrame*)((TADDR)pDispatcherContext->ContextRecord->R4);
 }
 
-//Return TRUE if pContext->Pc is in VirtualStub
-BOOL IsIPinVirtualStub(PCODE f_IP)
-{
-    LIMITED_METHOD_CONTRACT;
-
-    Thread * pThread = GetThread();
-
-    // We may not have a managed thread object. Example is an AV on the helper thread.
-    // (perhaps during StubManager::IsStub)
-    if (pThread == NULL)
-    {
-        return FALSE;
-    }
-
-    VirtualCallStubManager::StubKind sk;
-    VirtualCallStubManager::FindStubManager(f_IP, &sk);
-
-    if (sk == VirtualCallStubManager::SK_DISPATCH)
-    {
-        return TRUE;
-    }
-    else if (sk == VirtualCallStubManager::SK_RESOLVE)
-    {
-        return TRUE;
-    }
-
-    else {
-        return FALSE;
-    }
-}
-
-
 // Returns TRUE if caller should resume execution.
 BOOL
 AdjustContextForVirtualStub(
index f13d81f..fc0c44e 100644 (file)
@@ -46,6 +46,5 @@ PCODE GetAdjustedCallAddress(PCODE returnAddress)
 }
 
 BOOL AdjustContextForVirtualStub(EXCEPTION_RECORD *pExceptionRecord, T_CONTEXT *pContext);
-BOOL IsIPinVirtualStub(PCODE f_IP);
 
 #endif // __excepcpu_h__
index bb30ee4..69bb1f1 100644 (file)
@@ -5042,6 +5042,39 @@ BOOL IsSafeToCallExecutionManager()
            GCStress<cfg_instr_ngen>::IsEnabled();
 }
 
+#if defined(_TARGET_ARM_) || defined(_TARGET_X86_)
+//Return TRUE if pContext->Pc is in VirtualStub
+static BOOL IsIPinVirtualStub(PCODE f_IP)
+{
+    LIMITED_METHOD_CONTRACT;
+
+    Thread * pThread = GetThread();
+
+    // We may not have a managed thread object. Example is an AV on the helper thread.
+    // (perhaps during StubManager::IsStub)
+    if (pThread == NULL)
+    {
+        return FALSE;
+    }
+
+    VirtualCallStubManager::StubKind sk;
+    VirtualCallStubManager::FindStubManager(f_IP, &sk);
+
+    if (sk == VirtualCallStubManager::SK_DISPATCH)
+    {
+        return TRUE;
+    }
+    else if (sk == VirtualCallStubManager::SK_RESOLVE)
+    {
+        return TRUE;
+    }
+
+    else {
+        return FALSE;
+    }
+}
+#endif
+
 BOOL IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord)
 {
     PCODE controlPc = GetIP(contextRecord);
@@ -5049,7 +5082,7 @@ BOOL IsSafeToHandleHardwareException(PCONTEXT contextRecord, PEXCEPTION_RECORD e
         exceptionRecord->ExceptionCode == STATUS_BREAKPOINT || 
         exceptionRecord->ExceptionCode == STATUS_SINGLE_STEP ||
         (IsSafeToCallExecutionManager() && ExecutionManager::IsManagedCode(controlPc)) ||
-#ifdef _TARGET_ARM_
+#if defined(_TARGET_ARM_) || defined(_TARGET_X86_)
         IsIPinVirtualStub(controlPc) ||  // access violation comes from DispatchStub of Interface call
 #endif
         IsIPInMarkedJitHelper(controlPc));
@@ -5100,7 +5133,7 @@ BOOL HandleHardwareException(PAL_SEHException* ex)
                 PAL_VirtualUnwind(ex->GetContextRecord(), NULL);
                 ex->GetExceptionRecord()->ExceptionAddress = (PVOID)GetIP(ex->GetContextRecord());
             }
-#ifdef _TARGET_ARM_
+#if defined(_TARGET_ARM_) || defined(_TARGET_X86_)
             else if (IsIPinVirtualStub(controlPc)) 
             {
                 AdjustContextForVirtualStub(ex->GetExceptionRecord(), ex->GetContextRecord());