1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | // --------------------------------------------------------------------------- |
6 | // zapsig.h |
7 | // --------------------------------------------------------------------------- |
8 | // |
9 | // This module contains helper functions used to encode and manipulate |
10 | // signatures for the zapper (ngen). |
11 | // |
12 | |
13 | // --------------------------------------------------------------------------- |
14 | |
15 | |
16 | #ifndef ZAPSIG_H |
17 | #define ZAPSIG_H |
18 | |
19 | #include "common.h" |
20 | |
21 | typedef DWORD(*ENCODEMODULE_CALLBACK)(LPVOID pModuleContext, CORINFO_MODULE_HANDLE moduleHandle); |
22 | typedef DWORD (*EncodeModuleCallback)(void* pModuleContext, Module *pReferencedModule); |
23 | enum { |
24 | // return value when EncodeModule fails |
25 | ENCODE_MODULE_FAILED = 0xffffffff, |
26 | }; |
27 | |
28 | typedef void(*DEFINETOKEN_CALLBACK)(LPVOID pModuleContext, CORINFO_MODULE_HANDLE moduleHandle, DWORD index, mdTypeRef* token); |
29 | typedef void (*TokenDefinitionCallback)(void* pModuleContext, Module *pReferencedModule, DWORD index, mdToken* refToken); |
30 | |
31 | class ZapSig |
32 | { |
33 | public: |
34 | enum ExternalTokens |
35 | { |
36 | IllegalValue, |
37 | NormalTokens, |
38 | IbcTokens |
39 | }; |
40 | |
41 | struct Context |
42 | { |
43 | Module * pInfoModule; // The tokens in this ZapSig are expressed relative to context.pInfoModule |
44 | void * pModuleContext; // This is a code:Module* when we are resolving Ngen fixups or doing an Ibc Profiling run |
45 | // and is a code:ZapImportTable* when we are running ngen |
46 | ExternalTokens externalTokens; // When we see a ELEMENT_TYPE_MODULE_ZAPSIG this tells us what type of token follows. |
47 | |
48 | Module * GetZapSigModule() const { return (Module*) pModuleContext; } |
49 | |
50 | Context( |
51 | Module* _pInfoModule, |
52 | void* _pModuleContext, ExternalTokens _externalTokens) |
53 | : pInfoModule(_pInfoModule), |
54 | pModuleContext(_pModuleContext), |
55 | externalTokens(_externalTokens) |
56 | { LIMITED_METHOD_CONTRACT; _ASSERTE(externalTokens != IllegalValue); } |
57 | |
58 | Context( |
59 | Module* _pInfoModule, |
60 | Module* _pZapSigModule) |
61 | : pInfoModule(_pInfoModule), |
62 | pModuleContext((void*) _pZapSigModule), |
63 | externalTokens(NormalTokens) |
64 | { } |
65 | }; |
66 | |
67 | public: |
68 | |
69 | ZapSig( |
70 | Module * _pInfoModule, |
71 | void * _pModuleContext, |
72 | ExternalTokens _externalTokens, |
73 | EncodeModuleCallback _pfnEncodeModule, |
74 | TokenDefinitionCallback _pfnTokenDefinition) |
75 | |
76 | : context(_pInfoModule, _pModuleContext, _externalTokens), |
77 | pfnEncodeModule(_pfnEncodeModule), |
78 | pfnTokenDefinition(_pfnTokenDefinition) |
79 | {} |
80 | |
81 | #ifdef FEATURE_PREJIT |
82 | |
83 | // Instance methods |
84 | |
85 | // Create a signature for a typeHandle |
86 | // It can be decoded using MetaSig::GetTypeHandleThrowing |
87 | // The tokens are espressed relative to this->pInfoModule |
88 | // When (handle.GetModule() != this->pInfoModule), we escape |
89 | // the signature with ELEMENT_TYPE_MODULE_ZAPSIG <id-num> |
90 | // followed by a <token> to encode a temporary change of module |
91 | // For Ibc Signatures the <token> is one of the ibc defined tokens |
92 | // For Ngen Fixup signatures the <token> is for the external module |
93 | // |
94 | BOOL GetSignatureForTypeHandle(TypeHandle typeHandle, |
95 | SigBuilder * pSigBuilder); |
96 | |
97 | // Static methods |
98 | |
99 | // Compare a type handle with a signature whose tokens are resolved with respect to pModule |
100 | // pZapSigContext is used to resolve ELEMENT_TYPE_MODULE_ZAPSIG encodings |
101 | static BOOL CompareSignatureToTypeHandle(PCCOR_SIGNATURE pSig, |
102 | Module* pModule, |
103 | TypeHandle handle, |
104 | const ZapSig::Context * pZapSigContext); |
105 | |
106 | // Compare a type handle with a tagged pointer. Ensure that the common path is inlined into the caller. |
107 | static FORCEINLINE BOOL CompareTaggedPointerToTypeHandle(Module * pModule, TADDR addr, TypeHandle handle) |
108 | { |
109 | WRAPPER_NO_CONTRACT; |
110 | if (handle.AsTAddr() == addr) |
111 | return TRUE; |
112 | if (!CORCOMPILE_IS_POINTER_TAGGED(addr)) |
113 | return FALSE; |
114 | return CompareFixupToTypeHandle(pModule, addr, handle); |
115 | } |
116 | |
117 | static BOOL CompareFixupToTypeHandle(Module * pModule, TADDR fixup, TypeHandle handle); |
118 | |
119 | static BOOL CompareTypeHandleFieldToTypeHandle(TypeHandle *pTypeHnd, TypeHandle typeHnd2); |
120 | |
121 | private: |
122 | BOOL GetSignatureForTypeDesc(TypeDesc * desc, SigBuilder * pSigBuilder); |
123 | |
124 | // Returns element type when the typeHandle can be encoded using |
125 | // using a single CorElementType value |
126 | // This includes using ELEMENT_TYPE_CANON_ZAPSIG for the System.__Canon type |
127 | // |
128 | static CorElementType TryEncodeUsingShortcut(/* in */ MethodTable * pMT); |
129 | |
130 | #endif // FEATURE_PREJIT |
131 | |
132 | private: |
133 | |
134 | ZapSig::Context context; |
135 | |
136 | EncodeModuleCallback pfnEncodeModule; // Function Pointer to the EncodeModuleHelper |
137 | TokenDefinitionCallback pfnTokenDefinition; // Function Pointer to the DefineTokenHelper |
138 | |
139 | public: |
140 | //-------------------------------------------------------------------- |
141 | // Static helper encode/decode helper methods |
142 | |
143 | static Module *DecodeModuleFromIndex(Module *fromModule, |
144 | DWORD index); |
145 | |
146 | static Module *DecodeModuleFromIndexIfLoaded(Module *fromModule, |
147 | DWORD index); |
148 | |
149 | // referencingModule is the module that references the type. |
150 | // fromModule is the module in which the type is defined. |
151 | // pBuffer contains the signature encoding for the type. |
152 | // level is the class load level (see classloadlevel.h) to which the type should be loaded |
153 | static TypeHandle DecodeType( |
154 | Module *referencingModule, |
155 | Module *fromModule, |
156 | PCCOR_SIGNATURE pBuffer, |
157 | ClassLoadLevel level = CLASS_LOADED); |
158 | |
159 | static MethodDesc *DecodeMethod( |
160 | Module *referencingModule, |
161 | Module *fromModule, |
162 | PCCOR_SIGNATURE pBuffer, |
163 | TypeHandle *ppTH = NULL); |
164 | |
165 | static MethodDesc *DecodeMethod( |
166 | Module *referencingModule, |
167 | Module *fromModule, |
168 | PCCOR_SIGNATURE pBuffer, |
169 | SigTypeContext *pContext, |
170 | TypeHandle *ppTH = NULL, |
171 | PCCOR_SIGNATURE *ppOwnerTypeSpecWithVars = NULL, |
172 | PCCOR_SIGNATURE *ppMethodSpecWithVars = NULL); |
173 | |
174 | static FieldDesc *DecodeField( |
175 | Module *referencingModule, |
176 | Module *fromModule, |
177 | PCCOR_SIGNATURE pBuffer, |
178 | TypeHandle *ppTH = NULL); |
179 | |
180 | static FieldDesc *DecodeField( |
181 | Module *pReferencingModule, |
182 | Module *pInfoModule, |
183 | PCCOR_SIGNATURE pBuffer, |
184 | SigTypeContext *pContext, |
185 | TypeHandle *ppTH = NULL); |
186 | |
187 | static BOOL EncodeMethod( |
188 | MethodDesc *pMethod, |
189 | Module *pInfoModule, |
190 | SigBuilder *pSigBuilder, |
191 | LPVOID pReferencingModule, |
192 | ENCODEMODULE_CALLBACK pfnEncodeModule, |
193 | DEFINETOKEN_CALLBACK pfnDefineToken, |
194 | CORINFO_RESOLVED_TOKEN *pResolvedToken = NULL, |
195 | CORINFO_RESOLVED_TOKEN *pConstrainedResolvedToken = NULL, |
196 | BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE); |
197 | |
198 | static void EncodeField( |
199 | FieldDesc *pField, |
200 | Module *pInfoModule, |
201 | SigBuilder *pSigBuilder, |
202 | LPVOID pReferencingModule, |
203 | ENCODEMODULE_CALLBACK pfnEncodeModule, |
204 | CORINFO_RESOLVED_TOKEN *pResolvedToken = NULL, |
205 | BOOL fEncodeUsingResolvedTokenSpecStreams = FALSE); |
206 | |
207 | }; |
208 | |
209 | #endif // ZAPGSIG_H |
210 | |