forked from dotnet/runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzapsig.h
196 lines (160 loc) · 7.76 KB
/
zapsig.h
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
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// ---------------------------------------------------------------------------
// zapsig.h
// ---------------------------------------------------------------------------
//
// This module contains helper functions used to encode and manipulate
// signatures for scenarios where runtime-specific signatures
// including specific generic instantiations are persisted,
// like Ready-To-Run decoding, and Multi-core JIT recording/playback
//
// ---------------------------------------------------------------------------
#ifndef ZAPSIG_H
#define ZAPSIG_H
#include "common.h"
typedef DWORD(*ENCODEMODULE_CALLBACK)(LPVOID pModuleContext, CORINFO_MODULE_HANDLE moduleHandle);
typedef DWORD (*EncodeModuleCallback)(void* pModuleContext, Module *pReferencedModule);
enum {
// return value when EncodeModule fails
ENCODE_MODULE_FAILED = 0xffffffff,
// no module index override is needed
MODULE_INDEX_NONE = 0xfffffffe
};
typedef void(*DEFINETOKEN_CALLBACK)(LPVOID pModuleContext, CORINFO_MODULE_HANDLE moduleHandle, DWORD index, mdTypeRef* token);
typedef void (*TokenDefinitionCallback)(void* pModuleContext, Module *pReferencedModule, DWORD index, mdToken* refToken);
class ZapSig
{
public:
enum ExternalTokens
{
IllegalValue,
NormalTokens,
MulticoreJitTokens
};
struct Context
{
ModuleBase * pInfoModule; // The tokens in this ZapSig are expressed relative to context.pInfoModule
// This is a code:Module* when we are resolving Ngen fixups or doing an Ibc Profiling run.
// And this is a MulticoreJitProfilePlayer or a MulticoreJitRecorder when we are doing multicorejit
void * pModuleContext;
// and is a code:ZapImportTable* when we are running ngen
ExternalTokens externalTokens; // When we see a ELEMENT_TYPE_MODULE_ZAPSIG this tells us what type of token follows.
Module * GetZapSigModule() const { return (Module*) pModuleContext; }
Context(
ModuleBase* _pInfoModule,
void* _pModuleContext, ExternalTokens _externalTokens)
: pInfoModule(_pInfoModule),
pModuleContext(_pModuleContext),
externalTokens(_externalTokens)
{ LIMITED_METHOD_CONTRACT; _ASSERTE(externalTokens != IllegalValue); }
Context(
ModuleBase* _pInfoModule,
Module* _pZapSigModule)
: pInfoModule(_pInfoModule),
pModuleContext((void*) _pZapSigModule),
externalTokens(NormalTokens)
{ }
};
public:
ZapSig(
ModuleBase * _pInfoModule,
void * _pModuleContext,
ExternalTokens _externalTokens,
EncodeModuleCallback _pfnEncodeModule,
TokenDefinitionCallback _pfnTokenDefinition)
: context(_pInfoModule, _pModuleContext, _externalTokens),
pfnEncodeModule(_pfnEncodeModule),
pfnTokenDefinition(_pfnTokenDefinition)
{}
// Static methods
// Compare a type handle with a signature whose tokens are resolved with respect to pModule
// pZapSigContext is used to resolve ELEMENT_TYPE_MODULE_ZAPSIG encodings
static BOOL CompareSignatureToTypeHandle(PCCOR_SIGNATURE pSig,
ModuleBase* pModule,
TypeHandle handle,
const ZapSig::Context * pZapSigContext);
// Instance methods
// Create a signature for a typeHandle
// It can be decoded using MetaSig::GetTypeHandleThrowing
// The tokens are espressed relative to this->pInfoModule
// When (handle.GetModule() != this->pInfoModule), we escape
// the signature with ELEMENT_TYPE_MODULE_ZAPSIG <id-num>
// followed by a <token> to encode a temporary change of module
// For Ibc Signatures the <token> is one of the ibc defined tokens
// For Ngen Fixup signatures the <token> is for the external module
//
BOOL GetSignatureForTypeHandle(TypeHandle typeHandle,
SigBuilder * pSigBuilder);
static BOOL CompareTypeHandleFieldToTypeHandle(TypeHandle *pTypeHnd, TypeHandle typeHnd2);
private:
BOOL GetSignatureForTypeDesc(TypeDesc * desc, SigBuilder * pSigBuilder);
// Returns element type when the typeHandle can be encoded using
// using a single CorElementType value
// This includes using ELEMENT_TYPE_CANON_ZAPSIG for the System.__Canon type
//
static CorElementType TryEncodeUsingShortcut(/* in */ MethodTable * pMT);
// Copy single type signature, adding ELEMENT_TYPE_MODULE_ZAPSIG to types that are encoded using tokens.
// The source signature originates from the module with index specified by the parameter moduleIndex.
// Passing moduleIndex set to MODULE_INDEX_NONE results in pure copy of the signature.
//
static void CopyTypeSignature(SigParser* pSigParser, SigBuilder* pSigBuilder, DWORD moduleIndex);
private:
ZapSig::Context context;
EncodeModuleCallback pfnEncodeModule; // Function Pointer to the EncodeModuleHelper
TokenDefinitionCallback pfnTokenDefinition; // Function Pointer to the DefineTokenHelper
public:
//--------------------------------------------------------------------
// Static helper encode/decode helper methods
static ModuleBase *DecodeModuleFromIndex(Module *fromModule,
DWORD index);
static ModuleBase *DecodeModuleFromIndexIfLoaded(Module *fromModule,
DWORD index);
// referencingModule is the module that references the type.
// fromModule is the module in which the type is defined.
// pBuffer contains the signature encoding for the type.
// level is the class load level (see classloadlevel.h) to which the type should be loaded
static TypeHandle DecodeType(
Module *referencingModule,
ModuleBase *fromModule,
PCCOR_SIGNATURE pBuffer,
ClassLoadLevel level = CLASS_LOADED,
PCCOR_SIGNATURE *ppAfterSig = NULL);
static MethodDesc *DecodeMethod(
Module *referencingModule,
ModuleBase *fromModule,
PCCOR_SIGNATURE pBuffer,
TypeHandle *ppTH = NULL);
static MethodDesc *DecodeMethod(
ModuleBase *pInfoModule,
PCCOR_SIGNATURE pBuffer,
SigTypeContext *pContext,
ZapSig::Context *pZapSigContext,
TypeHandle *ppTH = NULL,
PCCOR_SIGNATURE *ppOwnerTypeSpecWithVars = NULL,
PCCOR_SIGNATURE *ppMethodSpecWithVars = NULL,
PCCOR_SIGNATURE *ppAfterSig = NULL,
BOOL actualOwnerRequired = FALSE);
static FieldDesc *DecodeField(
Module *referencingModule,
ModuleBase *fromModule,
PCCOR_SIGNATURE pBuffer,
TypeHandle *ppTH = NULL);
static FieldDesc *DecodeField(
Module *pReferencingModule,
ModuleBase *pInfoModule,
PCCOR_SIGNATURE pBuffer,
SigTypeContext *pContext,
TypeHandle *ppTH = NULL);
static BOOL EncodeMethod(
MethodDesc *pMethod,
Module *pInfoModule,
SigBuilder *pSigBuilder,
LPVOID pReferencingModule,
ENCODEMODULE_CALLBACK pfnEncodeModule,
DEFINETOKEN_CALLBACK pfnDefineToken,
CORINFO_RESOLVED_TOKEN *pResolvedToken = NULL,
CORINFO_RESOLVED_TOKEN *pConstrainedResolvedToken = NULL,
BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE);
};
#endif // ZAPGSIG_H