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 | |
7 | // |
8 | // This file defines tables for references between VM and mscorlib. |
9 | // |
10 | // When compiling crossgen, this file is compiled with the FEATURE_XXX define settings matching the target. |
11 | // It allows us to strip features (e.g. refection only load) from crossgen without stripping them from the target. |
12 | // |
13 | |
14 | #ifdef CROSSGEN_MSCORLIB |
15 | // Use minimal set of headers for crossgen |
16 | #include "windows.h" |
17 | #include "corinfo.h" |
18 | #else |
19 | #include "common.h" |
20 | #include "ecall.h" |
21 | #endif // CROSSGEN_MSCORLIB |
22 | |
23 | #ifndef CROSSGEN_COMPILE |
24 | // |
25 | // Headers for all ECall entrypoints |
26 | // |
27 | #include "arraynative.h" |
28 | #include "stringnative.h" |
29 | #include "objectnative.h" |
30 | #include "comdelegate.h" |
31 | #include "customattribute.h" |
32 | #include "comdynamic.h" |
33 | #include "excep.h" |
34 | #include "fcall.h" |
35 | #include "clrconfignative.h" |
36 | #include "commodule.h" |
37 | #include "marshalnative.h" |
38 | #include "nativelibrarynative.h" |
39 | #include "system.h" |
40 | #include "comutilnative.h" |
41 | #include "comsynchronizable.h" |
42 | #include "floatdouble.h" |
43 | #include "floatsingle.h" |
44 | #include "comdatetime.h" |
45 | #include "compatibilityswitch.h" |
46 | #include "debugdebugger.h" |
47 | #include "assemblyname.hpp" |
48 | #include "assemblynative.hpp" |
49 | #include "comthreadpool.h" |
50 | #include "comwaithandle.h" |
51 | #include "nativeoverlapped.h" |
52 | |
53 | #include "proftoeeinterfaceimpl.h" |
54 | |
55 | #include "appdomainnative.hpp" |
56 | #include "arrayhelpers.h" |
57 | #include "runtimehandles.h" |
58 | #include "reflectioninvocation.h" |
59 | #include "managedmdimport.hpp" |
60 | #include "synchronizationcontextnative.h" |
61 | #include "commemoryfailpoint.h" |
62 | #include "typestring.h" |
63 | #include "comdependenthandle.h" |
64 | #include "weakreferencenative.h" |
65 | #include "varargsnative.h" |
66 | |
67 | #ifdef MDA_SUPPORTED |
68 | #include "mdaassistants.h" |
69 | #endif |
70 | |
71 | #ifdef FEATURE_COMINTEROP |
72 | #include "variant.h" |
73 | #include "oavariant.h" |
74 | #include "registration.h" |
75 | #include "mngstdinterfaces.h" |
76 | #include "extensibleclassfactory.h" |
77 | #endif // FEATURE_COMINTEROP |
78 | |
79 | #include "stubhelpers.h" |
80 | #include "ilmarshalers.h" |
81 | |
82 | #ifdef FEATURE_MULTICOREJIT |
83 | #include "multicorejit.h" |
84 | #endif |
85 | |
86 | #if defined(FEATURE_EVENTSOURCE_XPLAT) |
87 | #include "nativeeventsource.h" |
88 | #include "eventpipe.h" |
89 | #endif //defined(FEATURE_EVENTSOURCE_XPLAT) |
90 | |
91 | #ifdef FEATURE_PERFTRACING |
92 | #include "eventpipe.h" |
93 | #endif //FEATURE_PERFTRACING |
94 | |
95 | #endif // CROSSGEN_MSCORLIB |
96 | |
97 | |
98 | #ifdef CROSSGEN_MSCORLIB |
99 | |
100 | /////////////////////////////////////////////////////////////////////////////// |
101 | // |
102 | // Duplicate definitions of constants and datastructures required to define the tables |
103 | // |
104 | |
105 | #define NumItems(s) (sizeof(s) / sizeof(s[0])) |
106 | |
107 | #define GetEEFuncEntryPoint(pfn) 0x1001 |
108 | |
109 | enum { |
110 | FCFuncFlag_EndOfArray = 0x01, |
111 | FCFuncFlag_HasSignature = 0x02, |
112 | FCFuncFlag_Unreferenced = 0x04, // Suppress unused fcall check |
113 | FCFuncFlag_QCall = 0x08, // QCall - mscorlib.dll to mscorwks.dll transition implemented as PInvoke |
114 | }; |
115 | |
116 | struct ECClass |
117 | { |
118 | LPCSTR m_szClassName; |
119 | LPCSTR m_szNameSpace; |
120 | const LPVOID * m_pECFunc; |
121 | }; |
122 | |
123 | struct HardCodedMetaSig |
124 | { |
125 | const BYTE* m_pMetaSig; // metasig prefixed with INT8 length: |
126 | // length > 0 - resolved, lenght < 0 - has unresolved type references |
127 | }; |
128 | |
129 | enum BinderClassID |
130 | { |
131 | #define TYPEINFO(e,ns,c,s,g,ia,ip,if,im,gv) CLASS__ ## e, |
132 | #include "cortypeinfo.h" |
133 | #undef TYPEINFO |
134 | |
135 | #define DEFINE_CLASS(i,n,s) CLASS__ ## i, |
136 | #include "mscorlib.h" |
137 | |
138 | CLASS__MSCORLIB_COUNT, |
139 | |
140 | CLASS__VOID = CLASS__ELEMENT_TYPE_VOID, |
141 | CLASS__BOOLEAN = CLASS__ELEMENT_TYPE_BOOLEAN, |
142 | CLASS__CHAR = CLASS__ELEMENT_TYPE_CHAR, |
143 | CLASS__BYTE = CLASS__ELEMENT_TYPE_U1, |
144 | CLASS__SBYTE = CLASS__ELEMENT_TYPE_I1, |
145 | CLASS__INT16 = CLASS__ELEMENT_TYPE_I2, |
146 | CLASS__UINT16 = CLASS__ELEMENT_TYPE_U2, |
147 | CLASS__INT32 = CLASS__ELEMENT_TYPE_I4, |
148 | CLASS__UINT32 = CLASS__ELEMENT_TYPE_U4, |
149 | CLASS__INT64 = CLASS__ELEMENT_TYPE_I8, |
150 | CLASS__UINT64 = CLASS__ELEMENT_TYPE_U8, |
151 | CLASS__SINGLE = CLASS__ELEMENT_TYPE_R4, |
152 | CLASS__DOUBLE = CLASS__ELEMENT_TYPE_R8, |
153 | CLASS__STRING = CLASS__ELEMENT_TYPE_STRING, |
154 | CLASS__TYPED_REFERENCE = CLASS__ELEMENT_TYPE_TYPEDBYREF, |
155 | CLASS__INTPTR = CLASS__ELEMENT_TYPE_I, |
156 | CLASS__UINTPTR = CLASS__ELEMENT_TYPE_U, |
157 | CLASS__OBJECT = CLASS__ELEMENT_TYPE_OBJECT |
158 | }; |
159 | |
160 | struct MscorlibClassDescription |
161 | { |
162 | LPCSTR nameSpace; |
163 | LPCSTR name; |
164 | }; |
165 | |
166 | struct MscorlibMethodDescription |
167 | { |
168 | BinderClassID classID; |
169 | LPCSTR name; |
170 | const HardCodedMetaSig * sig; |
171 | }; |
172 | |
173 | struct MscorlibFieldDescription |
174 | { |
175 | BinderClassID classID; |
176 | LPCSTR name; |
177 | }; |
178 | |
179 | #endif // CROSSGEN_MSCORLIB |
180 | |
181 | |
182 | #ifdef CROSSGEN_MSCORLIB |
183 | // When compiling crossgen this namespace creates the second version of the tables than matches the target |
184 | namespace CrossGenMscorlib { |
185 | #endif |
186 | |
187 | |
188 | /////////////////////////////////////////////////////////////////////////////// |
189 | // |
190 | // Hardcoded Meta-Sig |
191 | // |
192 | |
193 | // |
194 | // Helper enum with metasig lengths |
195 | // |
196 | // iterate over the metasig recursing into the complex types |
197 | #define DEFINE_METASIG(body) body, |
198 | #define METASIG_ATOM(x) + 1 |
199 | #define METASIG_RECURSE 1 |
200 | #define SM(varname, args, retval) gsigl_SM_ ## varname = 1 + 1 retval args |
201 | #define IM(varname, args, retval) gsigl_IM_ ## varname = 1 + 1 retval args |
202 | #define GM(varname, conv, n, args, retval) gsigl_GM_ ## varname = 1 + 1 + 1 + retval args |
203 | #define Fld(varname, val) gsigl_Fld_ ## varname = 1 val |
204 | enum _gsigl { |
205 | #include "metasig.h" |
206 | }; |
207 | |
208 | // |
209 | // Helper enum with metasig argcount |
210 | // |
211 | // iterate over the metasig without recursing into the complex types |
212 | #define DEFINE_METASIG(body) body, |
213 | #define METASIG_ATOM(x) + 1 |
214 | #define METASIG_RECURSE 0 |
215 | #define SM(varname, args, retval) gsigc_SM_ ## varname = 0 args |
216 | #define IM(varname, args, retval) gsigc_IM_ ## varname = 0 args |
217 | #define GM(varname, conv, n, args, retval) gsigc_GM_ ## varname = 0 args |
218 | #define Fld(varname, val) gsigc_Fld_ ## varname = 0 |
219 | enum _gsigc { |
220 | #include "metasig.h" |
221 | }; |
222 | |
223 | |
224 | // |
225 | // The actual array with the hardcoded metasig: |
226 | // |
227 | // There are 3 variations of the macros for Fields, Static Methods and Instance Methods. |
228 | // |
229 | // Each of them has 2 flavors: one for the fully baked signatures, and the other |
230 | // for the signatures with unresolved type references |
231 | // |
232 | // The signatures with unresolved type references are marked with negative size, |
233 | // and the pointer to them is non-const because of it will be overwritten with |
234 | // the pointer to the resolved signature at runtime. |
235 | // |
236 | |
237 | #define DEFINE_METASIG(body) body |
238 | #define DEFINE_METASIG_T(body) _##body |
239 | #define METASIG_ATOM(x) x, |
240 | #define METASIG_RECURSE 1 |
241 | |
242 | // define gsig_ ## varname before gsige_ ## varname to give a hint to the compiler about the desired layout |
243 | |
244 | #define SM(varname, args, retval) extern const BYTE gsige_SM_ ## varname[]; \ |
245 | const HardCodedMetaSig gsig_SM_ ## varname = { gsige_SM_ ## varname }; \ |
246 | const BYTE gsige_SM_ ## varname[] = { gsigl_SM_ ## varname, \ |
247 | IMAGE_CEE_CS_CALLCONV_DEFAULT, gsigc_SM_ ## varname, retval args }; |
248 | |
249 | #define IM(varname, args, retval) extern const BYTE gsige_IM_ ## varname[]; \ |
250 | const HardCodedMetaSig gsig_IM_ ## varname = { gsige_IM_ ## varname }; \ |
251 | const BYTE gsige_IM_ ## varname[] = { gsigl_IM_ ## varname, \ |
252 | IMAGE_CEE_CS_CALLCONV_HASTHIS, gsigc_IM_ ## varname, retval args }; |
253 | |
254 | #define GM(varname, conv, n, args, retval) extern const BYTE gsige_GM_ ## varname[]; \ |
255 | const HardCodedMetaSig gsig_GM_ ## varname = { gsige_GM_ ## varname }; \ |
256 | const BYTE gsige_GM_ ## varname[] = { gsigl_GM_ ## varname, \ |
257 | conv | IMAGE_CEE_CS_CALLCONV_GENERIC, n, gsigc_GM_ ## varname, retval args }; |
258 | |
259 | #define Fld(varname, val) extern const BYTE gsige_Fld_ ## varname[]; \ |
260 | const HardCodedMetaSig gsig_Fld_ ## varname = { gsige_Fld_ ## varname }; \ |
261 | const BYTE gsige_Fld_ ## varname[] = { gsigl_Fld_ ## varname, \ |
262 | IMAGE_CEE_CS_CALLCONV_FIELD, val }; |
263 | |
264 | #define _SM(varname, args, retval) extern const BYTE gsige_SM_ ## varname[]; \ |
265 | HardCodedMetaSig gsig_SM_ ## varname = { gsige_SM_ ## varname }; \ |
266 | const BYTE gsige_SM_ ## varname[] = { (BYTE) -gsigl_SM_ ## varname, \ |
267 | IMAGE_CEE_CS_CALLCONV_DEFAULT, gsigc_SM_ ## varname, retval args }; |
268 | |
269 | #define _IM(varname, args, retval) extern const BYTE gsige_IM_ ## varname[]; \ |
270 | HardCodedMetaSig gsig_IM_ ## varname = { gsige_IM_ ## varname }; \ |
271 | const BYTE gsige_IM_ ## varname[] = { (BYTE) -gsigl_IM_ ## varname, \ |
272 | IMAGE_CEE_CS_CALLCONV_HASTHIS, gsigc_IM_ ## varname, retval args }; |
273 | |
274 | #define _Fld(varname, val) extern const BYTE gsige_Fld_ ## varname[]; \ |
275 | HardCodedMetaSig gsig_Fld_ ## varname = { gsige_Fld_ ## varname }; \ |
276 | const BYTE gsige_Fld_ ## varname[] = { (BYTE) -gsigl_Fld_ ## varname, \ |
277 | IMAGE_CEE_CS_CALLCONV_FIELD, val }; |
278 | |
279 | #include "metasig.h" |
280 | |
281 | #undef _SM |
282 | #undef _IM |
283 | #undef _Fld |
284 | |
285 | |
286 | |
287 | #ifdef _DEBUG |
288 | |
289 | // |
290 | // Make sure DEFINE_METASIG is used for signatures that do not reference other types |
291 | // |
292 | // counts number of type references in the signature and C_ASSERTs that |
293 | // it is zero. An assertion failure results in error C2118: negative subscript. |
294 | #define DEFINE_METASIG(body) body |
295 | #define DEFINE_METASIG_T(body) |
296 | #define METASIG_BODY(varname, types) C_ASSERT(types 0 == 0); |
297 | #define METASIG_ATOM(x) 0+ |
298 | #define METASIG_RECURSE 1 |
299 | #define C(x) 1+ |
300 | #define g(x) 1+ |
301 | #define Q(x) 1+ |
302 | #include "metasig.h" |
303 | |
304 | // |
305 | // Make sure DEFINE_METASIG_T is used only for signatures that reference |
306 | // other types. |
307 | // |
308 | // counts number of type references in the signature and C_ASSERTs that |
309 | // it is non zero. An assertion failure results in error C2118: negative subscript. |
310 | #define DEFINE_METASIG(body) |
311 | #define DEFINE_METASIG_T(body) body |
312 | #define METASIG_BODY(varname, types) C_ASSERT(types 0 != 0); |
313 | #define METASIG_ATOM(x) 0+ |
314 | #define METASIG_RECURSE 1 |
315 | #define C(x) 1+ |
316 | #define g(x) 1+ |
317 | #define Q(x) 1+ |
318 | #include "metasig.h" |
319 | |
320 | #endif |
321 | |
322 | |
323 | |
324 | |
325 | |
326 | /////////////////////////////////////////////////////////////////////////////// |
327 | // |
328 | // Mscorlib binder |
329 | // |
330 | |
331 | // Extern definitions so that binder.cpp can see these tables |
332 | extern const MscorlibClassDescription c_rgMscorlibClassDescriptions[]; |
333 | extern const USHORT c_nMscorlibClassDescriptions; |
334 | |
335 | extern const MscorlibMethodDescription c_rgMscorlibMethodDescriptions[]; |
336 | extern const USHORT c_nMscorlibMethodDescriptions; |
337 | |
338 | extern const MscorlibFieldDescription c_rgMscorlibFieldDescriptions[]; |
339 | extern const USHORT c_nMscorlibFieldDescriptions; |
340 | |
341 | const MscorlibClassDescription c_rgMscorlibClassDescriptions[] = |
342 | { |
343 | #define TYPEINFO(e,ns,c,s,g,ia,ip,if,im,gv) { ns, c }, |
344 | #include "cortypeinfo.h" |
345 | #undef TYPEINFO |
346 | |
347 | #define DEFINE_CLASS(i,n,s) { g_ ## n ## NS, # s }, |
348 | #include "namespace.h" |
349 | #include "mscorlib.h" |
350 | |
351 | // Include all exception types here that are defined in mscorlib. Omit exceptions defined elsewhere. |
352 | #define DEFINE_EXCEPTION(ns, reKind, bHRformessage, ...) { ns , # reKind }, |
353 | #define DEFINE_EXCEPTION_HR_WINRT_ONLY(ns, reKind, ...) |
354 | #define DEFINE_EXCEPTION_IN_OTHER_FX_ASSEMBLY(ns, reKind, assemblySimpleName, publicKeyToken, bHRformessage, ...) |
355 | #include "rexcep.h" |
356 | }; |
357 | const USHORT c_nMscorlibClassDescriptions = NumItems(c_rgMscorlibClassDescriptions); |
358 | |
359 | #define gsig_NoSig (*(HardCodedMetaSig *)NULL) |
360 | |
361 | const MscorlibMethodDescription c_rgMscorlibMethodDescriptions[] = |
362 | { |
363 | #define DEFINE_METHOD(c,i,s,g) { CLASS__ ## c , # s, & gsig_ ## g }, |
364 | #include "mscorlib.h" |
365 | }; |
366 | const USHORT c_nMscorlibMethodDescriptions = NumItems(c_rgMscorlibMethodDescriptions) + 1; |
367 | |
368 | const MscorlibFieldDescription c_rgMscorlibFieldDescriptions[] = |
369 | { |
370 | #define DEFINE_FIELD(c,i,s) { CLASS__ ## c , # s }, |
371 | #include "mscorlib.h" |
372 | }; |
373 | const USHORT c_nMscorlibFieldDescriptions = NumItems(c_rgMscorlibFieldDescriptions) + 1; |
374 | |
375 | |
376 | |
377 | |
378 | |
379 | /////////////////////////////////////////////////////////////////////////////// |
380 | // |
381 | // ECalls |
382 | // |
383 | |
384 | // When compiling crossgen, we only need the target version of the ecall tables |
385 | #if !defined(CROSSGEN_COMPILE) || defined(CROSSGEN_MSCORLIB) |
386 | |
387 | #ifdef CROSSGEN_COMPILE |
388 | |
389 | #define QCFuncElement(name,impl) \ |
390 | FCFuncFlag_QCall + FCFuncFlags(CORINFO_INTRINSIC_Illegal, ECall::InvalidDynamicFCallId), NULL, (LPVOID)name, |
391 | |
392 | #define FCFuncFlags(intrinsicID, dynamicID) \ |
393 | (BYTE*)( (((BYTE)intrinsicID) << 16) ) |
394 | |
395 | #else |
396 | |
397 | #define QCFuncElement(name,impl) \ |
398 | FCFuncFlag_QCall + FCFuncFlags(CORINFO_INTRINSIC_Illegal, ECall::InvalidDynamicFCallId), (LPVOID)(impl), (LPVOID)name, |
399 | |
400 | #define FCFuncFlags(intrinsicID, dynamicID) \ |
401 | (BYTE*)( (((BYTE)intrinsicID) << 16) + (((BYTE)dynamicID) << 24) ) |
402 | |
403 | #endif |
404 | |
405 | #define FCFuncElement(name, impl) FCFuncFlags(CORINFO_INTRINSIC_Illegal, ECall::InvalidDynamicFCallId), \ |
406 | (LPVOID)GetEEFuncEntryPoint(impl), (LPVOID)name, |
407 | |
408 | #define FCFuncElementSig(name,sig,impl) \ |
409 | FCFuncFlag_HasSignature + FCFuncElement(name, impl) (LPVOID)sig, |
410 | |
411 | #define FCIntrinsic(name,impl,intrinsicID) FCFuncFlags(intrinsicID, ECall::InvalidDynamicFCallId), \ |
412 | (LPVOID)GetEEFuncEntryPoint(impl), (LPVOID)name, |
413 | |
414 | #define FCIntrinsicSig(name,sig,impl,intrinsicID) \ |
415 | FCFuncFlag_HasSignature + FCIntrinsic(name,impl,intrinsicID) (LPVOID)sig, |
416 | |
417 | #define FCDynamic(name,intrinsicID,dynamicID) FCFuncFlags(intrinsicID, dynamicID), \ |
418 | NULL, (LPVOID)name, |
419 | |
420 | #define FCDynamicSig(name,sig,intrinsicID,dynamicID) \ |
421 | FCFuncFlag_HasSignature + FCDynamic(name,intrinsicID,dynamicID) (LPVOID)sig, |
422 | |
423 | #define FCUnreferenced FCFuncFlag_Unreferenced + |
424 | |
425 | #define FCFuncStart(name) static const LPVOID name[] = { |
426 | #define FCFuncEnd() FCFuncFlag_EndOfArray + FCFuncFlags(CORINFO_INTRINSIC_Illegal, ECall::InvalidDynamicFCallId) }; |
427 | |
428 | #include "ecalllist.h" |
429 | |
430 | |
431 | // Extern definitions so that ecall.cpp can see these tables |
432 | extern const ECClass c_rgECClasses[]; |
433 | extern const int c_nECClasses; |
434 | |
435 | const ECClass c_rgECClasses[] = |
436 | { |
437 | #define FCClassElement(name,namespace,funcs) {name, namespace, funcs}, |
438 | #include "ecalllist.h" |
439 | }; // c_rgECClasses[] |
440 | |
441 | const int c_nECClasses = NumItems(c_rgECClasses); |
442 | |
443 | #endif // !CROSSGEN_COMPILE && CROSSGEN_MSCORLIB |
444 | |
445 | |
446 | #ifdef CROSSGEN_MSCORLIB |
447 | }; // namespace CrossGenMscorlib |
448 | #endif |
449 | |