summaryrefslogtreecommitdiff
path: root/src/vm/i386/excepcpu.h
blob: a97128b9fc21fa1b908f6f6ab7d3d58330591b48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

//
// EXCEPX86.H -
//
// This header file is optionally included from Excep.h if the target platform is x86
//


#ifndef __excepx86_h__
#define __excepx86_h__

#include "corerror.h"  // HResults for the COM+ Runtime

#include "../dlls/mscorrc/resource.h"

#define THROW_CONTROL_FOR_THREAD_FUNCTION  ThrowControlForThread

#define STATUS_CLR_GCCOVER_CODE         STATUS_PRIVILEGED_INSTRUCTION

#ifndef WIN64EXCEPTIONS
class Thread;

#if defined(_MSC_VER)
#pragma warning(disable:4733) // Inline asm assigning to `FS:0` : handler not registered as safe handler
                              // Actually, the handler getting set is properly registered
#endif

#define INSTALL_SEH_RECORD(record)                                        \
    {                                                                     \
       (record)->Next = (PEXCEPTION_REGISTRATION_RECORD)__readfsdword(0); \
       __writefsdword(0, (DWORD) (record));                               \
    }

#define UNINSTALL_SEH_RECORD(record)                                      \
    {                                                                     \
        __writefsdword(0, (DWORD) ((record)->Next));                      \
    }

#define INSTALL_EXCEPTION_HANDLING_RECORD(record)               \
    {                                                           \
        PEXCEPTION_REGISTRATION_RECORD __record = (record);     \
        _ASSERTE(__record < GetCurrentSEHRecord());             \
        INSTALL_SEH_RECORD(record);                             \
    }

//
// Note: this only pops a handler from the top of the stack. It will not remove a record from the middle of the
// chain, and I can assure you that you don't want to do that anyway.
//
#define UNINSTALL_EXCEPTION_HANDLING_RECORD(record)             \
    {                                                           \
        PEXCEPTION_REGISTRATION_RECORD __record = (record);     \
        _ASSERTE(__record == GetCurrentSEHRecord());            \
        UNINSTALL_SEH_RECORD(record);                           \
    }

// stackOverwriteBarrier is used to detect overwriting of stack which will mess up handler registration
#if defined(_DEBUG)
#define DECLARE_CPFH_EH_RECORD(pCurThread) \
    FrameHandlerExRecordWithBarrier *___pExRecordWithBarrier = (FrameHandlerExRecordWithBarrier *)_alloca(sizeof(FrameHandlerExRecordWithBarrier)); \
    for (int ___i =0; ___i < STACK_OVERWRITE_BARRIER_SIZE; ___i++) \
        ___pExRecordWithBarrier->m_StackOverwriteBarrier[___i] = STACK_OVERWRITE_BARRIER_VALUE; \
    FrameHandlerExRecord *___pExRecord = &(___pExRecordWithBarrier->m_ExRecord); \
    ___pExRecord->m_ExReg.Handler = (PEXCEPTION_ROUTINE)COMPlusFrameHandler; \
    ___pExRecord->m_pEntryFrame = (pCurThread)->GetFrame();

#else
#define DECLARE_CPFH_EH_RECORD(pCurThread) \
    FrameHandlerExRecord *___pExRecord = (FrameHandlerExRecord *)_alloca(sizeof(FrameHandlerExRecord)); \
    ___pExRecord->m_ExReg.Handler = (PEXCEPTION_ROUTINE)COMPlusFrameHandler; \
    ___pExRecord->m_pEntryFrame = (pCurThread)->GetFrame();

#endif


PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord();
PEXCEPTION_REGISTRATION_RECORD GetFirstCOMPlusSEHRecord(Thread*);

LPVOID COMPlusEndCatchWorker(Thread *pCurThread);
EXTERN_C LPVOID STDCALL COMPlusEndCatch(LPVOID ebp, DWORD ebx, DWORD edi, DWORD esi, LPVOID* pRetAddress);

#else // WIN64EXCEPTIONS
#define INSTALL_EXCEPTION_HANDLING_RECORD(record)
#define UNINSTALL_EXCEPTION_HANDLING_RECORD(record)
#define DECLARE_CPFH_EH_RECORD(pCurThread)

#endif // WIN64EXCEPTIONS

//
// Retrieves the redirected CONTEXT* from the stack frame of one of the
// RedirectedHandledJITCaseForXXX_Stub's.
//
PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(CONTEXT * pContext);
#ifdef WIN64EXCEPTIONS
PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_DISPATCHER_CONTEXT * pDispatcherContext);
#endif // WIN64EXCEPTIONS

// Determine the address of the instruction that made the current call.
inline
PCODE GetAdjustedCallAddress(PCODE returnAddress)
{
    LIMITED_METHOD_CONTRACT;
    return returnAddress - 5;
}

BOOL AdjustContextForVirtualStub(EXCEPTION_RECORD *pExceptionRecord, CONTEXT *pContext);

#endif // __excepx86_h__