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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
// 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.
//*****************************************************************************
// NewMerger.h
//
//
// Contains utility code for MD directory
//
//*****************************************************************************
#ifndef __NEWMERGER__h__
#define __NEWMERGER__h__
class RegMeta;
class MDTOKENMAP;
// module-level awareness of Security critical annotions
typedef BYTE InputScopeSecurityCriticalStatus;
#define ISSCS_Unknown 0x0
#define ISSCS_SecurityCritical 0x1
#define ISSCS_SecurityCriticalEverything (ISSCS_SecurityCritical | 0x2)
#define ISSCS_SecurityCriticalExplicit (ISSCS_SecurityCritical)
#define ISSCS_SecurityTransparent 0x4
#define ISSCS_SecurityTreatAsSafe 0x8
#define ISSCS_SECURITYCRITICAL_LEGACY (ISSCS_SecurityCriticalEverything | ISSCS_SecurityTreatAsSafe)
#define ISSCS_SECURITYCRITICAL_FLAGS (ISSCS_SecurityCriticalEverything | ISSCS_SecurityTransparent)
//*********************************************************************
// MergeImportData
//*********************************************************************
class MergeImportData
{
public:
RegMeta *m_pRegMetaImport;
IUnknown *m_pHandler;
IMapToken *m_pHostMapToken;
MDTOKENMAP *m_pMDTokenMap;
MergeImportData *m_pNextImportData;
mdMemberRef m_tkSuppressMergeCheckCtor; // caches the SuppressMergeCheckAttribute's .ctor token
mdMemberRef m_tkHandleProcessCorruptedStateCtor; // caches the memberRef token to HandleProcessCorruptedStateExceptionsAttribute's .ctor token
// import contains assembly-level SecurityTransparent or SecurityCritical
InputScopeSecurityCriticalStatus m_isscsSecurityCriticalStatus;
#if _DEBUG
int m_iImport; // debug only. This is the ith import for merge.
#endif // _DEBUG
};
//*********************************************************************
// MergeTypeData
//*********************************************************************
struct MergeTypeData
{
ULONG m_cMethods;
ULONG m_cFields;
ULONG m_cEvents;
ULONG m_cProperties;
BOOL m_bSuppressMergeCheck;
};
//*********************************************************************
// Class to handle merge
//*********************************************************************
class NEWMERGER
{
friend class RegMeta;
public:
NEWMERGER();
~NEWMERGER();
HRESULT Init(RegMeta *pRegMetaDest);
HRESULT AddImport(
IMetaDataImport2 *pImport, // [IN] The scope to be merged.
IMapToken *pHostMapToken, // [IN] Host IMapToken interface to receive token remap notification
IUnknown *pHandler); // [IN] An object to receive to receive error notification.
HRESULT Merge(MergeFlags flags, CorRefToDefCheck optimizeRefToDef);
protected:
CMiniMdRW *GetMiniMdEmit();
HRESULT InitMergeTypeData();
HRESULT MergeTypeDefNamesOnly();
HRESULT MergeModuleRefs();
HRESULT MergeAssemblyRefs();
HRESULT MergeTypeRefs();
HRESULT CompleteMergeTypeDefs();
HRESULT CopyTypeDefPartially(
TypeDefRec *pRecEmit, // [IN] the emit record to fill
CMiniMdRW *pMiniMdImport, // [IN] the importing scope
TypeDefRec *pRecImp); // [IN] the record to import
// helpers for merging tables
HRESULT MergeModule( );
HRESULT MergeTypeDefChildren();
HRESULT MergeInterfaceImpls( );
HRESULT MergeMemberRefs( );
HRESULT MergePinvoke();
HRESULT MergeConstants( );
HRESULT MergeCustomAttributes( );
HRESULT MergeFieldMarshals( );
HRESULT MergeDeclSecuritys( );
HRESULT MergeClassLayouts( );
HRESULT MergeFieldLayouts( );
HRESULT MergeFieldRVAs();
HRESULT MergeMethodImpls( );
HRESULT MergeStandAloneSigs();
HRESULT MergeMethodSpecs();
HRESULT MergeTypeSpecs();
HRESULT MergeSourceFiles( );
HRESULT MergeBlocks( );
HRESULT MergeScopes( );
HRESULT MergeLocalVariables( );
HRESULT MergeStrings( );
HRESULT MergeAssembly();
HRESULT MergeFiles();
HRESULT MergeExportedTypes();
HRESULT MergeManifestResources();
// helpers for SecurityCritical-related merging
InputScopeSecurityCriticalStatus CheckInputScopeIsCritical(MergeImportData* pImportData, HRESULT& hr);
HRESULT RetrieveStandardSecurityCriticalMetaData(
mdAssemblyRef& tkMscorlib,
mdTypeRef& securityEnum,
BYTE*& rgSigBytesSecurityCriticalEverythingCtor,
DWORD& dwSigEverythingSize,
BYTE*& rgSigBytesSecurityCriticalExplicitCtor,
DWORD& dwSigExplicitSize);
HRESULT MergeSecurityCriticalModuleLevelAttributes(
MergeImportData* pImportData,
mdToken tkParentImp, TOKENREC* pTypeRec,
mdToken mrSecurityTreatAsSafeAttributeCtor,
mdToken mrSecurityTransparentAttributeCtor,
mdToken mrSecurityCriticalExplicitAttributeCtor,
mdToken mrSecurityCriticalEverythingAttributeCtor);
HRESULT MergeSecurityCriticalAttributes();
// copy over a interfaceimpl record
HRESULT CopyInterfaceImpl(
InterfaceImplRec *pRecEmit, // [IN] the emit record to fill
MergeImportData *pImportData, // [IN] the importing context
InterfaceImplRec *pRecImp); // [IN] the record to import
// verification helpers
HRESULT VerifyMethods(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
HRESULT VerifyFields(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
HRESULT VerifyEvents(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
HRESULT VerifyProperties(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
HRESULT VerifyParams(MergeImportData *pImportData, mdMethodDef mdImp, mdMethodDef mdEmit);
HRESULT VerifyGenericParams(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
HRESULT VerifyGenericParamConstraints(MergeImportData *pImportData, mdGenericParam gpImp, mdGenericParam gpEmit);
// Copy helpers
HRESULT CopyMethods(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
HRESULT CopyFields(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
HRESULT CopyEvents(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
HRESULT CopyProperties(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
HRESULT CopyParams(MergeImportData *pImportData, mdMethodDef mdImp, mdMethodDef mdEmit);
HRESULT CopyGenericParams(MergeImportData *pImportData, mdToken tkImp, mdToken tkEmit);
HRESULT CopyGenericParamConstraints(MergeImportData *pImportData, mdGenericParam gpImp, mdGenericParam gpEmit);
HRESULT CopyMethod(
MergeImportData *pImportData, // [IN] import scope
MethodRec *pRecImp, // [IN] the record to import
MethodRec *pRecEmit); // [IN] the emit record to fill
HRESULT CopyField(
MergeImportData *pImportData, // [IN] import scope
FieldRec *pRecImp, // [IN] the record to import
FieldRec *pRecEmit); // [IN] the emit record to fill
HRESULT CopyEvent(
MergeImportData *pImportData, // [IN] import scope
EventRec *pRecImp, // [IN] the record to import
EventRec *pRecEmit); // [IN] the emit record to fill
HRESULT CopyProperty(
MergeImportData *pImportData, // [IN] import scope
PropertyRec *pRecImp, // [IN] the record to import
PropertyRec *pRecEmit); // [IN] the emit record to fill
HRESULT CopyParam(
MergeImportData *pImportData, // [IN] import scope
ParamRec *pRecImp, // [IN] the record to import
ParamRec *pRecEmit); // [IN] the emit record to fill
HRESULT CopyMethodSemantics(
MergeImportData *pImportData,
mdToken tkImport, // Event or property in the import scope
mdToken tkEmit); // corresponding event or property in the emitting scope
HRESULT VerifyMethod(
MergeImportData *pImportData,
mdMethodDef mdImp, // [IN] the emit record to fill
mdMethodDef mdEmit); // [IN] the record to import
HRESULT OnError(HRESULT hr, MergeImportData *pImportData, mdToken token);
private:
RegMeta *m_pRegMetaEmit;
MergeImportData *m_pImportDataList;
MergeImportData **m_pImportDataTail;
MergeFlags m_dwMergeFlags;
BOOL m_fDupCheck;
CorRefToDefCheck m_optimizeRefToDef;
// the combined value of the Security Critical input scopes (e.g. UNION of each scope's attributes)
// if ANY of the scopes have a bit set, then we must do some merging
InputScopeSecurityCriticalStatus m_isscsSecurityCritical;
// the common values of the Security Critical input scopes (e.g. INTERSECTION of each scope's attributes)
// if all scopes have the same bit set, then we can emit one bit at the final output scope
InputScopeSecurityCriticalStatus m_isscsSecurityCriticalAllScopes;
CDynArray<MergeTypeData> m_rMTDs;
#if _DEBUG
int m_iImport; // debug only. To count how many import scopes to be merged.
#endif // _DEBUG
};
#define CheckContinuableErrorEx(EXPR, HANDLER, TOKEN) \
{ \
HRESULT hrOnErr, hrExpr; \
hrExpr = EXPR; \
\
hrOnErr = OnError(hrExpr, HANDLER, TOKEN); \
if (hrOnErr != S_OK) \
{ \
if (hrOnErr == S_FALSE) \
{ \
hr = hrExpr; \
} \
else if (SUCCEEDED(hrOnErr)) \
{ \
hr = E_UNEXPECTED; \
} \
else if (FAILED(hrOnErr)) \
{ \
hr = hrOnErr; \
} \
IfFailGo(hr); \
} \
}
#endif // __NEWMERGER__h__
|