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 | * CorBBTProf.h - File format for profile data * |
8 | * * |
9 | * Version 1.0 * |
10 | ******************************************************************************* |
11 | * * |
12 | * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY * |
13 | * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * |
14 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR * |
15 | * PURPOSE. * |
16 | * * |
17 | \*****************************************************************************/ |
18 | |
19 | #ifndef _COR_BBTPROF_H_ |
20 | #define _COR_BBTPROF_H_ |
21 | |
22 | #include <cor.h> |
23 | #include <corinfo.h> |
24 | |
25 | const CorTokenType ibcExternalNamespace = CorTokenType(0x61000000); |
26 | const CorTokenType ibcExternalType = CorTokenType(0x62000000); |
27 | const CorTokenType ibcExternalSignature = CorTokenType(0x63000000); |
28 | const CorTokenType ibcExternalMethod = CorTokenType(0x64000000); |
29 | const CorTokenType ibcTypeSpec = CorTokenType(0x68000000); |
30 | const CorTokenType ibcMethodSpec = CorTokenType(0x69000000); |
31 | |
32 | typedef mdToken idExternalNamespace; // External Namespace token in the IBC data |
33 | typedef mdToken idExternalType; // External Type token in the IBC data |
34 | typedef mdToken idExternalSignature; // External Signature token in the IBC data |
35 | typedef mdToken idExternalMethod; // External Method token in the IBC data |
36 | typedef mdToken idTypeSpec; // TypeSpec token in the IBC data |
37 | typedef mdToken idMethodSpec; // MethodSpec token in the IBC data |
38 | |
39 | #define idExternalNamespaceNil ((idExternalNamespace) ibcExternalNamespace) |
40 | #define idExternalTypeNil ((idExternalType) ibcExternalType) |
41 | #define idExternalSignatureNil ((idExternalSignature) ibcExternalSignature) |
42 | #define idExternalMethodNil ((idExternalMethod) ibcExternalMethod) |
43 | #define idTypeSpecNil ((idTypeSpec) ibcTypeSpec) |
44 | #define idMethodSpecNil ((idMethodSpec) ibcMethodSpec) |
45 | |
46 | // |
47 | // File format: |
48 | // |
49 | // CORBBTPROF_FILE_HEADER |
50 | // CORBBTPROF_SECTION_TABLE_HEADER |
51 | // CORBBTPROF_SECTION_TABLE_ENTRY |
52 | // ... (can be multiple entries) |
53 | // |
54 | // Method block counts section: |
55 | // CORBBTPROF_METHOD_BLOCK_COUNTS_SECTION_HEADER |
56 | // CORBBTPROF_METHOD_HEADER |
57 | // CORBBTPROF_BLOCK_DATA |
58 | // ... (can be multiple method header/block data entries) |
59 | // |
60 | // Method load order section: |
61 | // CORBBTPROF_TOKEN_LIST_SECTION_HEADER |
62 | // ... (list of tokens) |
63 | // |
64 | // Type token usage information |
65 | // CORBBTPROF_TOKEN_LIST_SECTION_HEADER |
66 | // ... (list of tokens) |
67 | // |
68 | |
69 | // MethodDef token usage information |
70 | // CORBBTPROF_TOKEN_LIST_SECTION_HEADER |
71 | // ... (list of tokens) |
72 | // |
73 | |
74 | // RIDs to not use slim headers section |
75 | // CORBBTPROF_TOKEN_LIST_SECTION_HEADER |
76 | // ... (list of tokens) |
77 | // |
78 | |
79 | // Metadata hints to re-order some tables |
80 | // Instantiated TypeSPecs to re-order EEClasses |
81 | // |
82 | // The header for the profile data file. |
83 | // ... (list of CORBBTPROF_BLOB_ENTRY) |
84 | // terminated by null |
85 | |
86 | struct |
87 | { |
88 | DWORD ; |
89 | DWORD ; |
90 | DWORD ; |
91 | GUID ; |
92 | }; |
93 | |
94 | // Optional in V1 and V2. Usually present in V2. Must be present in V3. |
95 | struct |
96 | { |
97 | DWORD ; // Including the size field |
98 | DWORD ; |
99 | DWORD ; // Only in V3 or later |
100 | // future fields |
101 | }; |
102 | |
103 | enum CORBBTPROF_FILE_FLAGS |
104 | { |
105 | CORBBTPROF_FILE_FLAG_MINIFIED = 1, |
106 | CORBBTPROF_FILE_FLAG_PARTIAL_NGEN = 2 |
107 | }; |
108 | |
109 | enum |
110 | { |
111 | CORBBTPROF_V0_VERSION = 0, |
112 | CORBBTPROF_V1_VERSION = 1, |
113 | CORBBTPROF_V2_VERSION = 2, |
114 | CORBBTPROF_V3_VERSION = 3, |
115 | CORBBTPROF_CURRENT_VERSION = CORBBTPROF_V2_VERSION, // V3 is opt-in |
116 | CORBBTPROF_MAGIC = 0xb1d0f11e, |
117 | CORBBTPROF_END_TOKEN = 0xb4356f98 |
118 | }; |
119 | |
120 | // |
121 | // The profile data can be mapped anywhere in memory. So instead of using pointers, |
122 | // to denote sections, we will instead use offsets from the beginning of the file. |
123 | // |
124 | |
125 | struct Section |
126 | { |
127 | DWORD Offset; |
128 | DWORD Size; |
129 | }; |
130 | |
131 | // |
132 | // Section types, where various sections contains different types of profile data. |
133 | // |
134 | |
135 | #define CORBBTPROF_TOKEN_MAX_NUM_FLAGS 32 |
136 | |
137 | enum TypeProfilingDataFlags |
138 | { |
139 | // Important: update toolbox\ibcmerge\ibcmerge.cs if you change these |
140 | ReadMethodTable = 0, // 0x00001 |
141 | ReadEEClass = 1, // 0x00002 |
142 | WriteEEClass = 2, // 0x00004 |
143 | // ReadStoredEnumData = 3, // 0x00008 // obsolete |
144 | ReadFieldDescs = 4, // 0x00010 |
145 | ReadCCtorInfo = 5, // 0x00020 |
146 | ReadClassHashTable = 6, // 0x00040 |
147 | ReadDispatchMap = 7, // 0x00080 |
148 | ReadDispatchTable = 8, // 0x00100 |
149 | ReadMethodTableWriteableData = 9, // 0x00200 |
150 | ReadFieldMarshalers = 10, // 0x00400 |
151 | // WriteDispatchTable = 11, // 0x00800 // obsolete |
152 | // WriteMethodTable = 12, // 0x01000 // obsolete |
153 | WriteMethodTableWriteableData = 13, // 0x02000 |
154 | ReadTypeDesc = 14, // 0x04000 |
155 | WriteTypeDesc = 15, // 0x08000 |
156 | ReadTypeHashTable = 16, // 0x10000 |
157 | // WriteTypeHashTable = 17, // 0x20000 // obsolete |
158 | // ReadDictionary = 18, // 0x40000 // obsolete |
159 | // WriteDictionary = 19, // 0x80000 // obsolete |
160 | ReadNonVirtualSlots = 20, // 0x100000 |
161 | }; |
162 | |
163 | enum MethodProfilingDataFlags |
164 | { |
165 | // Important: update toolbox\ibcmerge\ibcmerge.cs if you change these |
166 | ReadMethodCode = 0, // 0x00001 // Also means the method was executed |
167 | ReadMethodDesc = 1, // 0x00002 |
168 | RunOnceMethod = 2, // 0x00004 |
169 | RunNeverMethod = 3, // 0x00008 |
170 | // MethodStoredDataAccess = 4, // 0x00010 // obsolete |
171 | WriteMethodDesc = 5, // 0x00020 |
172 | // ReadFCallHash = 6, // 0x00040 // obsolete |
173 | ReadGCInfo = 7, // 0x00080 |
174 | CommonReadGCInfo = 8, // 0x00100 |
175 | // ReadMethodDefRidMap = 9, // 0x00200 // obsolete |
176 | ReadCerMethodList = 10, // 0x00400 |
177 | ReadMethodPrecode = 11, // 0x00800 |
178 | WriteMethodPrecode = 12, // 0x01000 |
179 | ExcludeHotMethodCode = 13, // 0x02000 // Hot method should be excluded from the ReadyToRun image |
180 | ExcludeColdMethodCode = 14, // 0x04000 // Cold method should be excluded from the ReadyToRun image |
181 | DisableInlining = 15, // 0x08000 // Disable inlining of this method in optimized AOT native code |
182 | }; |
183 | |
184 | enum GeneralProfilingDataFlags |
185 | { |
186 | // Important: update ibcmerge.cs if you change these |
187 | // ZapImage.h depends on 0xFFFFFFFF being an invalid flag value. If this |
188 | // changes, update ReadFlagWithMemory in that file. |
189 | // Important: make sure these don't collide with TypeProfilingDataFlags or MethodProfilingDataFlags |
190 | // These grow downward from CORBBTPROF_TOKEN_MAX_NUM_FLAGS-1 to minimize the chance of collision |
191 | ProfilingFlags_MetaData = 31, // 0x800... |
192 | CommonMetaData = 30, // 0x400... |
193 | RidMap = 29, // 0x200... |
194 | RVAFieldData = 28, // 0x100... |
195 | ProfilingFlags_MetaDataSearch = 27, // 0x080... |
196 | }; |
197 | |
198 | enum BlobType |
199 | { |
200 | /* IMPORTANT: Keep the first four enums together in the same order and at |
201 | the very begining of this enum. See MetaModelPub.h for the order */ |
202 | MetadataStringPool = 0, |
203 | MetadataGuidPool = 1, |
204 | MetadataBlobPool = 2, |
205 | MetadataUserStringPool = 3, |
206 | |
207 | FirstMetadataPool = 0, |
208 | LastMetadataPool = 3, |
209 | |
210 | // SectionFormat only supports tokens, which have to already exist in the module. |
211 | // For instantiated paramterized types, there may be no corresponding token |
212 | // in the module, if a dependent module caused the type to be instantiated. |
213 | // For such instantiated types, we save a blob/signature to identify the type. |
214 | // |
215 | ParamTypeSpec = 4, // Instantiated Type Signature |
216 | ParamMethodSpec = 5, // Instantiated Method Signature |
217 | ExternalNamespaceDef = 6, // External Namespace Token Definition |
218 | ExternalTypeDef = 7, // External Type Token Definition |
219 | ExternalSignatureDef = 8, // External Signature Definition |
220 | ExternalMethodDef = 9, // External Method Token Definition |
221 | |
222 | IllegalBlob = 10, // Failed to allocate the blob |
223 | |
224 | EndOfBlobStream = -1 |
225 | }; |
226 | |
227 | enum SectionFormat |
228 | { |
229 | // Important: update ibcmerge.cs if you change these |
230 | ScenarioInfo = 0, |
231 | MethodBlockCounts = 1, // Basic-block counts. Cold blocks will be placed in the cold-code section |
232 | BlobStream = 2, // metadata access, inst-type-spec and inst-method-spec blobs |
233 | |
234 | FirstTokenFlagSection = 3, |
235 | |
236 | ModuleProfilingData = FirstTokenFlagSection + (mdtModule >> 24), |
237 | TypeRefProfilingData = FirstTokenFlagSection + (mdtTypeRef >> 24), |
238 | TypeProfilingData = FirstTokenFlagSection + (mdtTypeDef >> 24), |
239 | FieldDefProfilingData = FirstTokenFlagSection + (mdtFieldDef >> 24), |
240 | MethodProfilingData = FirstTokenFlagSection + (mdtMethodDef >> 24), |
241 | ParamDefProfilingData = FirstTokenFlagSection + (mdtParamDef >> 24), |
242 | InterfaceImplProfilingData = FirstTokenFlagSection + (mdtInterfaceImpl >> 24), |
243 | MemberRefProfilingData = FirstTokenFlagSection + (mdtMemberRef >> 24), |
244 | CustomAttributeProfilingData = FirstTokenFlagSection + (mdtCustomAttribute >> 24), |
245 | PermissionProfilingData = FirstTokenFlagSection + (mdtPermission >> 24), |
246 | SignatureProfilingData = FirstTokenFlagSection + (mdtSignature >> 24), |
247 | EventProfilingData = FirstTokenFlagSection + (mdtEvent >> 24), |
248 | PropertyProfilingData = FirstTokenFlagSection + (mdtProperty >> 24), |
249 | ModuleRefProfilingData = FirstTokenFlagSection + (mdtModuleRef >> 24), |
250 | TypeSpecProfilingData = FirstTokenFlagSection + (mdtTypeSpec >> 24), |
251 | AssemblyProfilingData = FirstTokenFlagSection + (mdtAssembly >> 24), |
252 | AssemblyRefProfilingData = FirstTokenFlagSection + (mdtAssemblyRef >> 24), |
253 | FileProfilingData = FirstTokenFlagSection + (mdtFile >> 24), |
254 | ExportedTypeProfilingData = FirstTokenFlagSection + (mdtExportedType >> 24), |
255 | ManifestResourceProfilingData = FirstTokenFlagSection + (mdtManifestResource >> 24), |
256 | GenericParamProfilingData = FirstTokenFlagSection + (mdtGenericParam >> 24), |
257 | MethodSpecProfilingData = FirstTokenFlagSection + (mdtMethodSpec >> 24), |
258 | GenericParamConstraintProfilingData = FirstTokenFlagSection + (mdtGenericParamConstraint >> 24), |
259 | |
260 | StringPoolProfilingData, |
261 | GuidPoolProfilingData, |
262 | BlobPoolProfilingData, |
263 | UserStringPoolProfilingData, |
264 | |
265 | FirstMetadataPoolSection = StringPoolProfilingData, |
266 | LastMetadataPoolSection = UserStringPoolProfilingData, |
267 | LastTokenFlagSection = LastMetadataPoolSection, |
268 | |
269 | IbcTypeSpecSection, |
270 | IbcMethodSpecSection, |
271 | |
272 | GenericTypeProfilingData = 63, // Deprecated with V2 IBC data |
273 | SectionFormatCount = 64, // 0x40 |
274 | |
275 | SectionFormatInvalid = -1 |
276 | }; |
277 | |
278 | struct CORBBTPROF_SECTION_TABLE_ENTRY |
279 | { |
280 | SectionFormat FormatID; |
281 | Section Data; |
282 | }; |
283 | |
284 | struct |
285 | { |
286 | DWORD ; |
287 | CORBBTPROF_SECTION_TABLE_ENTRY [0]; |
288 | }; |
289 | |
290 | // |
291 | // ScenarioInfo section |
292 | // |
293 | |
294 | struct CORBBTPROF_SCENARIO_RUN |
295 | { |
296 | FILETIME runTime; // the FILETIME when the scenario was cnt |
297 | GUID mvid; // The GUID of this assembly when the scenario was run (useful for incremental ibcdata) |
298 | DWORD cCmdLine; // the count of WCHAR's in the cmdLine for this run of the scenario |
299 | DWORD cSystemInfo; // the count of WCHAR's in the systemInfo string for this run of the scenario |
300 | WCHAR cmdLine[0]; // the command line used, the array is 'cName' in length |
301 | // WCHAR systemInfo[]; // the system information, the array is 'cSystemInfo' in length |
302 | |
303 | DWORD sizeofCmdLine() |
304 | { |
305 | return (cCmdLine * (DWORD)sizeof(WCHAR)); |
306 | } |
307 | |
308 | DWORD sizeofSystemInfo() |
309 | { |
310 | return (cSystemInfo * (DWORD)sizeof(WCHAR)); |
311 | } |
312 | |
313 | DWORD Size() |
314 | { |
315 | return (DWORD)sizeof(CORBBTPROF_SCENARIO_RUN) + sizeofCmdLine() + sizeofSystemInfo(); |
316 | } |
317 | |
318 | CORBBTPROF_SCENARIO_RUN* GetNextRun() |
319 | { |
320 | return reinterpret_cast< CORBBTPROF_SCENARIO_RUN* >( |
321 | reinterpret_cast< PBYTE >( this + 1 ) + Size() ); |
322 | } |
323 | }; |
324 | |
325 | struct CORBBTPROF_SCENARIO_INFO |
326 | { |
327 | DWORD ordinal; // the id number for this scenario |
328 | DWORD mask; // the one-bit mask use to identify this scenario |
329 | DWORD priority; // the priority of this scenario |
330 | DWORD numRuns; // the number of times this scenario was run |
331 | DWORD cName; // the count of WCHAR's in name[] |
332 | WCHAR name[0]; // the name of this scenario, the array is 'cName' in length |
333 | // CORBBTPROF_SCENARIO_RUN run[]; // the array is 'numRuns' in length |
334 | |
335 | DWORD sizeofName() |
336 | { |
337 | return (DWORD) (cName * sizeof(WCHAR)); |
338 | } |
339 | |
340 | DWORD Size() |
341 | { |
342 | return (DWORD) sizeof(CORBBTPROF_SCENARIO_INFO) + sizeofName() + sizeofRuns(); |
343 | } |
344 | |
345 | CORBBTPROF_SCENARIO_RUN* GetScenarioRun() |
346 | { |
347 | return reinterpret_cast< CORBBTPROF_SCENARIO_RUN* >( |
348 | reinterpret_cast< PBYTE >( this ) + (DWORD)sizeof(CORBBTPROF_SCENARIO_INFO) + sizeofName()); |
349 | } |
350 | |
351 | DWORD sizeofRuns() |
352 | { |
353 | DWORD sum = 0; |
354 | if (numRuns > 0) |
355 | { |
356 | DWORD cnt = 1; |
357 | CORBBTPROF_SCENARIO_RUN* pRun = GetScenarioRun(); |
358 | do |
359 | { |
360 | sum += pRun->Size(); |
361 | if (cnt == numRuns) |
362 | break; |
363 | cnt++; |
364 | pRun = pRun->GetNextRun(); |
365 | } |
366 | while (true); |
367 | } |
368 | return sum; |
369 | } |
370 | }; |
371 | |
372 | struct |
373 | { |
374 | DWORD ; // Size to skip to get to the next CORBBTPROF_SCENARIO_HEADER |
375 | CORBBTPROF_SCENARIO_INFO ; |
376 | |
377 | DWORD () |
378 | { |
379 | return (DWORD) sizeof(CORBBTPROF_SCENARIO_HEADER) + scenario.sizeofName() + scenario.sizeofRuns(); |
380 | } |
381 | }; |
382 | |
383 | struct |
384 | { |
385 | DWORD ; |
386 | DWORD ; |
387 | // CORBBTPROF_SCENARIO_HEADER scenario[0]; // array is 'NumScenarios' in length |
388 | }; |
389 | |
390 | // |
391 | // MethodBlockCounts section |
392 | // |
393 | |
394 | struct |
395 | { |
396 | DWORD ; |
397 | DWORD ; |
398 | }; |
399 | |
400 | struct |
401 | { |
402 | DWORD ; |
403 | }; |
404 | |
405 | struct CORBBTPROF_BLOCK_DATA // Also defined here code:ICorJitInfo.ProfileBuffer |
406 | { |
407 | DWORD ILOffset; |
408 | DWORD ExecutionCount; |
409 | }; |
410 | |
411 | struct |
412 | { |
413 | DWORD ; // Size to skip to get to the next CORBBTPROF_METHOD_DETAIL_HEADER at this level |
414 | DWORD ; // Identifier that specifies what kind this CORBBTPROF_METHOD_DETAIL_HEADER actually represents |
415 | |
416 | size_t () |
417 | { |
418 | return size; |
419 | } |
420 | }; |
421 | |
422 | // |
423 | // This struct records the basic block execution counts for a method |
424 | // |
425 | struct CORBBTPROF_METHOD_INFO |
426 | { |
427 | DWORD token; // token for this method |
428 | DWORD ILSize; // IL size for this method |
429 | DWORD cBlock; // count for block[] |
430 | CORBBTPROF_BLOCK_DATA block[0]; // actually 'cBlock' in length |
431 | |
432 | size_t Size() |
433 | { |
434 | return sizeof(CORBBTPROF_METHOD_INFO) + sizeofBlock(); |
435 | } |
436 | |
437 | size_t sizeofBlock() |
438 | { |
439 | return cBlock * sizeof(CORBBTPROF_BLOCK_DATA); |
440 | } |
441 | }; |
442 | |
443 | struct |
444 | { |
445 | DWORD ; |
446 | mdToken ; |
447 | DWORD ; |
448 | }; |
449 | |
450 | struct |
451 | { |
452 | DWORD ; // Size to skip to get to the next CORBBTPROF_METHOD_HEADER |
453 | DWORD ; // the count of CORBBTPROF_METHOD_DETAIL_HEADER records that folow this record |
454 | CORBBTPROF_METHOD_INFO ; // Basic block execution counts for a method |
455 | // ... followed by 'cDetail' occurances of CORBBTPROF_METHOD_DETAIL_HEADER |
456 | |
457 | size_t () |
458 | { |
459 | return sizeof(CORBBTPROF_METHOD_HEADER) + method.sizeofBlock(); |
460 | } |
461 | }; |
462 | |
463 | |
464 | struct |
465 | { |
466 | DWORD ; |
467 | }; |
468 | |
469 | struct CORBBTPROF_TOKEN_LIST_ENTRY_V1 |
470 | { |
471 | mdToken token; |
472 | DWORD flags; |
473 | }; |
474 | |
475 | struct CORBBTPROF_TOKEN_INFO // Was CORBBTPROF_TOKEN_LIST_ENTRY |
476 | { |
477 | mdToken token; |
478 | DWORD flags; |
479 | DWORD scenarios; // Could use UINT64 instead |
480 | |
481 | CORBBTPROF_TOKEN_INFO() |
482 | : token(0) |
483 | , flags(0) |
484 | , scenarios(0) |
485 | {} |
486 | |
487 | CORBBTPROF_TOKEN_INFO( mdToken t, DWORD f = 0, DWORD s = 0) |
488 | : token(t) |
489 | , flags(f) |
490 | , scenarios(s) |
491 | {} |
492 | |
493 | CORBBTPROF_TOKEN_INFO( CORBBTPROF_TOKEN_INFO const & right ) |
494 | : token(right.token) |
495 | , flags(right.flags) |
496 | , scenarios(right.scenarios) |
497 | {} |
498 | |
499 | CORBBTPROF_TOKEN_INFO operator=( CORBBTPROF_TOKEN_INFO const & right ) |
500 | { |
501 | token = right.token; |
502 | flags = right.flags; |
503 | scenarios = right.scenarios; |
504 | return *this; |
505 | } |
506 | |
507 | bool operator<( CORBBTPROF_TOKEN_INFO const & right ) const |
508 | { |
509 | return token < right.token; |
510 | } |
511 | }; |
512 | |
513 | struct CORBBTPROF_BLOB_ENTRY_V1 |
514 | { |
515 | BlobType blobType; |
516 | DWORD flags; |
517 | DWORD cBuffer; |
518 | BYTE pBuffer[0]; // actually 'cBuffer' in length |
519 | |
520 | CORBBTPROF_BLOB_ENTRY_V1 * GetNextEntry() |
521 | { |
522 | return reinterpret_cast< CORBBTPROF_BLOB_ENTRY_V1* >( |
523 | reinterpret_cast< PBYTE >( this + 1 ) + cBuffer ); |
524 | } |
525 | }; |
526 | |
527 | struct CORBBTPROF_BLOB_ENTRY |
528 | { |
529 | DWORD size; |
530 | BlobType type; |
531 | mdToken token; // The code:CORBBTPROF_BLOB_ENTRY.token field is not a real meta-data token |
532 | // but a look-alike that IBCMerge makes to represent blob entry |
533 | |
534 | bool TypeIsValid() |
535 | { |
536 | return (type >= MetadataStringPool) && (type < IllegalBlob); |
537 | } |
538 | |
539 | CORBBTPROF_BLOB_ENTRY * GetNextEntry() |
540 | { |
541 | return reinterpret_cast< CORBBTPROF_BLOB_ENTRY* >( |
542 | reinterpret_cast< PBYTE >( this ) + size); |
543 | } |
544 | }; |
545 | |
546 | struct CORBBTPROF_BLOB_PARAM_SIG_ENTRY |
547 | { |
548 | CORBBTPROF_BLOB_ENTRY blob; |
549 | DWORD cSig; |
550 | COR_SIGNATURE sig[0]; // actually 'cSig' in length |
551 | }; |
552 | |
553 | struct CORBBTPROF_BLOB_NAMESPACE_DEF_ENTRY |
554 | { |
555 | CORBBTPROF_BLOB_ENTRY blob; |
556 | DWORD cName; |
557 | CHAR name[0]; // actually cName in length |
558 | }; |
559 | |
560 | struct CORBBTPROF_BLOB_TYPE_DEF_ENTRY |
561 | { |
562 | CORBBTPROF_BLOB_ENTRY blob; |
563 | mdToken assemblyRefToken; |
564 | mdToken nestedClassToken; |
565 | mdToken nameSpaceToken; |
566 | DWORD cName; |
567 | CHAR name[0]; // actually cName in length |
568 | }; |
569 | |
570 | struct CORBBTPROF_BLOB_SIGNATURE_DEF_ENTRY |
571 | { |
572 | CORBBTPROF_BLOB_ENTRY blob; |
573 | DWORD cSig; |
574 | COR_SIGNATURE sig[0]; // actually 'cSig' in length |
575 | }; |
576 | |
577 | struct CORBBTPROF_BLOB_METHOD_DEF_ENTRY |
578 | { |
579 | CORBBTPROF_BLOB_ENTRY blob; |
580 | mdToken nestedClassToken; |
581 | mdToken signatureToken; |
582 | DWORD cName; |
583 | CHAR name[0]; // actually cName in length |
584 | }; |
585 | |
586 | struct CORBBTPROF_BLOB_POOL_ENTRY |
587 | { |
588 | CORBBTPROF_BLOB_ENTRY blob; |
589 | DWORD cBuffer; |
590 | BYTE buffer[0]; // actually 'cBuffer' in length |
591 | }; |
592 | #endif /* COR_BBTPROF_H_ */ |
593 | |