summaryrefslogtreecommitdiff
path: root/src/utilcode/format1.cpp
blob: 97cb95598b663bbde8188ac3ba7385483791c460 (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
113
114
115
116
117
118
119
120
// 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.

/***************************************************************************/
/* routines for parsing file format stuff ... */
/* this is split off from format.cpp because this uses meta-data APIs that
   are not present in many builds.  Thus if someone needs things in the format.cpp
   file but does not have the meta-data APIs, I want it to link */

#include "stdafx.h"
#include "cor.h"
#include "corpriv.h"

//---------------------------------------------------------------------------------------
// 
static LONG FilterAllExceptions(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam)
{
    if ((pExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) ||  
        (pExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_ARRAY_BOUNDS_EXCEEDED) ||
        (pExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_IN_PAGE_ERROR))
        return EXCEPTION_EXECUTE_HANDLER;

    return EXCEPTION_CONTINUE_SEARCH;
}

//---------------------------------------------------------------------------------------
// 
COR_ILMETHOD_DECODER::COR_ILMETHOD_DECODER(
    COR_ILMETHOD *  header, 
    void *          pInternalImport, 
    DecoderStatus * wbStatus)
{
    STATIC_CONTRACT_NOTHROW;
    STATIC_CONTRACT_FORBID_FAULT;
    
    // Can't put contract because of SEH
    // CONTRACTL
    // {
    //    NOTHROW;
    //    GC_NOTRIGGER;
    //    FORBID_FAULT;
    // }
    // CONTRACTL_END
    
    bool fErrorInInit = false;
    struct Param
    {
        COR_ILMETHOD_DECODER * pThis;
        COR_ILMETHOD * header;
    } param;
    param.pThis = this;
    param.header = header;
    
    PAL_TRY(Param *, pParam, &param)
    {
        // Decode the COR header into a more convenient form
        DecoderInit(pParam->pThis, pParam->header);
    }
    PAL_EXCEPT_FILTER(FilterAllExceptions)
    {
        fErrorInInit = true;
        Code = 0;
        SetLocalVarSigTok(0);
        if (wbStatus != NULL)
        {
            *wbStatus = FORMAT_ERROR;
        }
    }
    PAL_ENDTRY
    
    if (fErrorInInit)
    {
        return;
    }
    
    // If there is a local variable sig, fetch it into 'LocalVarSig'
    if ((GetLocalVarSigTok() != 0) && (pInternalImport != NULL))
    {
        IMDInternalImport * pMDI = reinterpret_cast<IMDInternalImport *>(pInternalImport);
        
        if (wbStatus != NULL)
        {
            if ((!pMDI->IsValidToken(GetLocalVarSigTok())) || 
                (TypeFromToken(GetLocalVarSigTok()) != mdtSignature) || 
                (RidFromToken(GetLocalVarSigTok()) == 0))
            {
                *wbStatus = FORMAT_ERROR;         // failure bad local variable signature token
                return;
            }
        }
        
        if (FAILED(pMDI->GetSigFromToken(GetLocalVarSigTok(), &cbLocalVarSig, &LocalVarSig)))
        {
            // Failure bad local variable signature token
            if (wbStatus != NULL)
            {
                *wbStatus = FORMAT_ERROR;
            }
            LocalVarSig = NULL;
            cbLocalVarSig = 0;
            return;
        }
        
        if (wbStatus != NULL)
        {
            if (FAILED(validateTokenSig(GetLocalVarSigTok(), LocalVarSig, cbLocalVarSig, 0, pMDI)) || 
                (*LocalVarSig != IMAGE_CEE_CS_CALLCONV_LOCAL_SIG))
            {
                *wbStatus = VERIFICATION_ERROR;   // failure validating local variable signature
                return;
            }
        }
    }
    
    if (wbStatus != NULL)
    {
        *wbStatus = SUCCESS;
    }
} // COR_ILMETHOD_DECODER::COR_ILMETHOD_DECODER