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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
|
// 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.
/*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XX XX
XX GCDecode XX
XX XX
XX Logic to decode the JIT method header and GC pointer tables XX
XX XX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
*/
#ifdef _TARGET_X86_
/* This file is shared between the VM and JIT/IL and SOS/Strike directories */
#include "gcinfotypes.h"
/*****************************************************************************/
/*
* This entire file depends upon GC2_ENCODING being set to 1
*
*****************************************************************************/
size_t FASTCALL decodeUnsigned(PTR_CBYTE src, unsigned* val)
{
LIMITED_METHOD_CONTRACT;
size_t size = 1;
BYTE byte = *src++;
unsigned value = byte & 0x7f;
while (byte & 0x80) {
size++;
byte = *src++;
value <<= 7;
value += byte & 0x7f;
}
*val = value;
return size;
}
size_t FASTCALL decodeUDelta(PTR_CBYTE src, unsigned* value, unsigned lastValue)
{
CONTRACTL {
NOTHROW;
GC_NOTRIGGER;
} CONTRACTL_END;
unsigned delta;
size_t size = decodeUnsigned(src, &delta);
*value = lastValue + delta;
return size;
}
size_t FASTCALL decodeSigned(PTR_CBYTE src, int* val)
{
CONTRACTL {
NOTHROW;
GC_NOTRIGGER;
} CONTRACTL_END;
size_t size = 1;
BYTE byte = *src++;
BYTE first = byte;
int value = byte & 0x3f;
while (byte & 0x80)
{
size++;
byte = *src++;
value <<= 7;
value += byte & 0x7f;
}
if (first & 0x40)
value = -value;
*val = value;
return size;
}
/*****************************************************************************/
#if defined(_MSC_VER)
#pragma optimize("tgy", on)
#endif
PTR_CBYTE FASTCALL decodeHeader(PTR_CBYTE table, UINT32 version, InfoHdr* header)
{
LIMITED_METHOD_DAC_CONTRACT;
BYTE nextByte = *table++;
BYTE encoding = nextByte & 0x7f;
GetInfoHdr(encoding, header);
while (nextByte & MORE_BYTES_TO_FOLLOW)
{
nextByte = *table++;
encoding = nextByte & ADJ_ENCODING_MAX;
// encoding here always corresponds to codes in InfoHdrAdjust set
if (encoding < NEXT_FOUR_START)
{
if (encoding < SET_ARGCOUNT)
{
header->frameSize = encoding - SET_FRAMESIZE;
}
else if (encoding < SET_PROLOGSIZE)
{
header->argCount = encoding - SET_ARGCOUNT;
}
else if (encoding < SET_EPILOGSIZE)
{
header->prologSize = encoding - SET_PROLOGSIZE;
}
else if (encoding < SET_EPILOGCNT)
{
header->epilogSize = encoding - SET_EPILOGSIZE;
}
else if (encoding < SET_UNTRACKED)
{
header->epilogCount = (encoding - SET_EPILOGCNT) / 2;
header->epilogAtEnd = ((encoding - SET_EPILOGCNT) & 1) == 1;
assert(!header->epilogAtEnd || (header->epilogCount == 1));
}
else if (encoding < FIRST_FLIP)
{
header->untrackedCnt = encoding - SET_UNTRACKED;
_ASSERTE(header->untrackedCnt != HAS_UNTRACKED);
}
else switch (encoding)
{
default:
assert(!"Unexpected encoding");
break;
case FLIP_EDI_SAVED:
header->ediSaved ^= 1;
break;
case FLIP_ESI_SAVED:
header->esiSaved ^= 1;
break;
case FLIP_EBX_SAVED:
header->ebxSaved ^= 1;
break;
case FLIP_EBP_SAVED:
header->ebpSaved ^= 1;
break;
case FLIP_EBP_FRAME:
header->ebpFrame ^= 1;
break;
case FLIP_INTERRUPTIBLE:
header->interruptible ^= 1;
break;
case FLIP_DOUBLE_ALIGN:
header->doubleAlign ^= 1;
break;
case FLIP_SECURITY:
header->security ^= 1;
break;
case FLIP_HANDLERS:
header->handlers ^= 1;
break;
case FLIP_LOCALLOC:
header->localloc ^= 1;
break;
case FLIP_EDITnCONTINUE:
header->editNcontinue ^= 1;
break;
case FLIP_VAR_PTR_TABLE_SZ:
header->varPtrTableSize ^= HAS_VARPTR;
break;
case FFFF_UNTRACKED_CNT:
header->untrackedCnt = HAS_UNTRACKED;
break;
case FLIP_VARARGS:
header->varargs ^= 1;
break;
case FLIP_PROF_CALLBACKS:
header->profCallbacks ^= 1;
break;
case FLIP_HAS_GENERICS_CONTEXT:
header->genericsContext ^= 1;
break;
case FLIP_GENERICS_CONTEXT_IS_METHODDESC:
header->genericsContextIsMethodDesc ^= 1;
break;
case FLIP_HAS_GS_COOKIE:
header->gsCookieOffset ^= HAS_GS_COOKIE_OFFSET;
break;
case FLIP_SYNC:
header->syncStartOffset ^= HAS_SYNC_OFFSET;
break;
case FLIP_REV_PINVOKE_FRAME:
_ASSERTE(GCInfoEncodesRevPInvokeFrame(version));
header->revPInvokeOffset ^= HAS_REV_PINVOKE_FRAME_OFFSET;
break;
case NEXT_OPCODE:
_ASSERTE((nextByte & MORE_BYTES_TO_FOLLOW) && "Must have another code");
nextByte = *table++;
encoding = nextByte & ADJ_ENCODING_MAX;
// encoding here always corresponds to codes in InfoHdrAdjust2 set
if (encoding < SET_RET_KIND_MAX)
{
_ASSERTE(GCInfoEncodesReturnKind(version));
header->returnKind = (ReturnKind)encoding;
}
else
{
assert(!"Unexpected encoding");
}
break;
}
}
else
{
unsigned char lowBits;
switch (encoding >> 4)
{
default:
assert(!"Unexpected encoding");
break;
case 5:
assert(NEXT_FOUR_FRAMESIZE == 0x50);
lowBits = encoding & 0xf;
header->frameSize <<= 4;
header->frameSize += lowBits;
break;
case 6:
assert(NEXT_FOUR_ARGCOUNT == 0x60);
lowBits = encoding & 0xf;
header->argCount <<= 4;
header->argCount += lowBits;
break;
case 7:
if ((encoding & 0x8) == 0)
{
assert(NEXT_THREE_PROLOGSIZE == 0x70);
lowBits = encoding & 0x7;
header->prologSize <<= 3;
header->prologSize += lowBits;
}
else
{
assert(NEXT_THREE_EPILOGSIZE == 0x78);
lowBits = encoding & 0x7;
header->epilogSize <<= 3;
header->epilogSize += lowBits;
}
break;
}
}
}
return table;
}
void FASTCALL decodeCallPattern(int pattern,
unsigned * argCnt,
unsigned * regMask,
unsigned * argMask,
unsigned * codeDelta)
{
CONTRACTL {
NOTHROW;
GC_NOTRIGGER;
SUPPORTS_DAC;
} CONTRACTL_END;
assert((pattern>=0) && (pattern<80));
CallPattern pat;
pat.val = callPatternTable[pattern];
*argCnt = pat.fld.argCnt;
*regMask = pat.fld.regMask; // EBP,EBX,ESI,EDI
*argMask = pat.fld.argMask;
*codeDelta = pat.fld.codeDelta;
}
#define YES HAS_VARPTR
const InfoHdrSmall infoHdrShortcut[128] = {
// Prolog size
// |
// | Epilog size
// | |
// | | Epilog count
// | | |
// | | | Epilog at end
// | | | |
// | | | | EDI saved
// | | | | |
// | | | | | ESI saved
// | | | | | |
// | | | | | | EBX saved
// | | | | | | |
// | | | | | | | EBP saved
// | | | | | | | |
// | | | | | | | | EBP-frame
// | | | | | | | | |
// | | | | | | | | | Interruptible method
// | | | | | | | | | |
// | | | | | | | | | | doubleAlign
// | | | | | | | | | | |
// | | | | | | | | | | | security flag
// | | | | | | | | | | | |
// | | | | | | | | | | | | handlers
// | | | | | | | | | | | | |
// | | | | | | | | | | | | | localloc
// | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | edit and continue
// | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | varargs
// | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | ProfCallbacks
// | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | genericsContext
// | | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | | genericsContextIsMethodDesc
// | | | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | | | returnKind
// | | | | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | | | | Arg count
// | | | | | | | | | | | | | | | | | | | | | Counted occurences
// | | | | | | | | | | | | | | | | | | | | | Frame size |
// | | | | | | | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | | | | | | untrackedCnt | Header encoding
// | | | | | | | | | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | | | | | | | varPtrTable | |
// | | | | | | | | | | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | | | | | | | | gsCookieOffs | |
// | | | | | | | | | | | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | | | | | | | | | syncOffs | |
// | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
// | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
// v v v v v v v v v v v v v v v v v v v v v v v v v v v v v
{ 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1139 00
{ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 128738 01
{ 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3696 02
{ 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 402 03
{ 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 4259 04
{ 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 3379 05
{ 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 2058 06
{ 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0 }, // 728 07
{ 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 984 08
{ 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0 }, // 606 09
{ 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0 }, // 1110 0a
{ 0, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 0 }, // 414 0b
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1553 0c
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, YES }, // 584 0d
{ 1, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 2182 0e
{ 1, 2, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3445 0f
{ 1, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1369 10
{ 1, 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 515 11
{ 1, 2, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 21127 12
{ 1, 2, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3517 13
{ 1, 2, 3, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 750 14
{ 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1876 15
{ 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1665 16
{ 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 729 17
{ 1, 4, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 484 18
{ 1, 4, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 331 19
{ 2, 3, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 361 1a
{ 2, 3, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 964 1b
{ 2, 3, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3713 1c
{ 2, 3, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 466 1d
{ 2, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1325 1e
{ 2, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 712 1f
{ 2, 3, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 588 20
{ 2, 3, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 20542 21
{ 2, 3, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 3802 22
{ 2, 3, 3, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 798 23
{ 2, 5, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1900 24
{ 2, 5, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 385 25
{ 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1617 26
{ 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1743 27
{ 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 909 28
{ 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0 }, // 602 29
{ 2, 5, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 352 2a
{ 2, 6, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 657 2b
{ 2, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 1283 2c
{ 2, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1286 2d
{ 3, 4, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1495 2e
{ 3, 4, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1989 2f
{ 3, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1154 30
{ 3, 4, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 9300 31
{ 3, 4, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 392 32
{ 3, 4, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1720 33
{ 3, 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1246 34
{ 3, 6, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 800 35
{ 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1179 36
{ 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 1368 37
{ 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 349 38
{ 3, 6, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0 }, // 505 39
{ 3, 6, 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 629 3a
{ 3, 8, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 2, YES }, // 365 3b
{ 4, 5, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 487 3c
{ 4, 5, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 1752 3d
{ 4, 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1959 3e
{ 4, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 2436 3f
{ 4, 5, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 861 40
{ 4, 7, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1459 41
{ 4, 7, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 950 42
{ 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 1491 43
{ 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 }, // 879 44
{ 4, 7, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0 }, // 408 45
{ 5, 4, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 4870 46
{ 5, 6, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 359 47
{ 5, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 915 48
{ 5, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, // 412 49
{ 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1288 4a
{ 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 1591 4b
{ 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, YES }, // 361 4c
{ 5, 6, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0, 0 }, // 623 4d
{ 5, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 }, // 1239 4e
{ 6, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 457 4f
{ 6, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 606 50
{ 6, 4, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 1073 51
{ 6, 4, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 508 52
{ 6, 6, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 330 53
{ 6, 6, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 1709 54
{ 6, 7, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 1164 55
{ 7, 4, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // 556 56
{ 7, 5, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 529 57
{ 7, 5, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 1423 58
{ 7, 8, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 2455 59
{ 7, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 956 5a
{ 7, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, YES }, // 1399 5b
{ 7, 8, 2, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, YES }, // 587 5c
{ 7, 10, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 1, YES }, // 743 5d
{ 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 0 }, // 1004 5e
{ 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, YES }, // 487 5f
{ 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0 }, // 337 60
{ 7, 10, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 0, YES }, // 361 61
{ 8, 3, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 560 62
{ 8, 6, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 1377 63
{ 9, 4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 877 64
{ 9, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0 }, // 3041 65
{ 9, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 349 66
{ 10, 5, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0 }, // 2061 67
{ 10, 5, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 }, // 577 68
{ 11, 6, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 0 }, // 1195 69
{ 12, 5, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }, // 491 6a
{ 13, 8, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, YES }, // 627 6b
{ 13, 8, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 0 }, // 1099 6c
{ 13, 10, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 6, 1, YES }, // 488 6d
{ 14, 7, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 574 6e
{ 16, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 1281 6f
{ 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, YES }, // 1881 70
{ 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 339 71
{ 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0 }, // 2594 72
{ 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0 }, // 339 73
{ 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 2107 74
{ 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 2372 75
{ 16, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, YES }, // 1078 76
{ 16, 7, 2, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, YES }, // 384 77
{ 16, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 4, 1, YES }, // 1541 78
{ 16, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, 4, 1, YES }, // 975 79
{ 19, 7, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 546 7a
{ 24, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, YES }, // 675 7b
{ 45, 9, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }, // 902 7c
{ 51, 7, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 0, YES }, // 432 7d
{ 51, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, YES }, // 361 7e
{ 51, 7, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0 }, // 703 7f
};
bool InfoHdrSmall::isHeaderMatch(const InfoHdr& target) const
{
#ifdef _ASSERTE
// target cannot have place-holder values.
_ASSERTE(target.untrackedCnt != HAS_UNTRACKED &&
target.varPtrTableSize != HAS_VARPTR &&
target.gsCookieOffset != HAS_GS_COOKIE_OFFSET &&
target.syncStartOffset != HAS_SYNC_OFFSET &&
target.revPInvokeOffset != HAS_REV_PINVOKE_FRAME_OFFSET);
#endif
// compare two InfoHdr's up to but not including the untrackCnt field
if (memcmp(this, &target, offsetof(InfoHdr, untrackedCnt)) != 0)
return false;
if (untrackedCnt != target.untrackedCnt) {
if (target.untrackedCnt <= SET_UNTRACKED_MAX)
return false;
else if (untrackedCnt != HAS_UNTRACKED)
return false;
}
if (varPtrTableSize != target.varPtrTableSize) {
if ((varPtrTableSize != 0) != (target.varPtrTableSize != 0))
return false;
}
if (target.gsCookieOffset != INVALID_GS_COOKIE_OFFSET)
return false;
if (target.syncStartOffset != INVALID_SYNC_OFFSET)
return false;
if (target.revPInvokeOffset!= INVALID_REV_PINVOKE_OFFSET)
return false;
return true;
}
const unsigned callCommonDelta[4] = { 6,8,10,12 };
/*
* In the callPatternTable each 32-bit unsigned value represents four bytes:
*
* byte0,byte1,byte2,byte3 => codeDelta,argMask,regMask,argCnt
* for example 0x0c000301 => codeDelta of 12, argMask of 0,
* regMask of 0x3, argCnt of 1
*
* Furthermore within the table the following maximum values are in place:
*
* codeDelta <= CP_MAX_CODE_DELTA // (0x23)
* argCnt <= CP_MAX_ARG_CNT // (0x02)
* argMask <= CP_MAX_ARG_MASK // (0x00)
*
* Note that ARG_CNT is the count of pushed args for a nested call site.
* And since the first two arguments are always passed in registers
* an ARG_CNT of 1 would mean that the nested call site had three arguments
*
* Note that ARG_MASK is the mask of pushed args that contain GC pointers
* since the first two arguments are always passed in registers it is
* a fairly rare occurance to push a GC pointer as an argument, since it
* only occurs for nested calls, when the third or later argument for the
* outer call contains a GC ref.
*
* Additionally the encoding of the regMask uses the following bits:
* EDI = 0x1, ESI = 0x2, EBX = 0x4, EBP = 0x8
*
*/
const unsigned callPatternTable[80] = { // # of occurences
0x0a000200, // 30109
0x0c000200, // 22970
0x0c000201, // 19005
0x0a000300, // 12193
0x0c000300, // 10614
0x0e000200, // 10253
0x10000200, // 9746
0x0b000200, // 9698
0x0d000200, // 9625
0x08000200, // 8909
0x0c000301, // 8522
0x11000200, // 7382
0x0e000300, // 7357
0x12000200, // 7139
0x10000300, // 7062
0x11000300, // 6970
0x0a000201, // 6842
0x0a000100, // 6803
0x0f000200, // 6795
0x13000200, // 6559
0x08000300, // 6079
0x15000200, // 5874
0x0d000201, // 5492
0x0c000100, // 5193
0x0d000300, // 5165
0x23000200, // 5143
0x1b000200, // 5035
0x14000200, // 4872
0x0f000300, // 4850
0x0a000700, // 4781
0x09000200, // 4560
0x12000300, // 4496
0x16000200, // 4180
0x07000200, // 4021
0x09000300, // 4012
0x0c000700, // 3988
0x0c000600, // 3946
0x0e000100, // 3823
0x1a000200, // 3764
0x18000200, // 3744
0x17000200, // 3736
0x1f000200, // 3671
0x13000300, // 3559
0x0a000600, // 3214
0x0e000600, // 3109
0x08000201, // 2984
0x0b000300, // 2928
0x0a000301, // 2859
0x07000100, // 2826
0x13000100, // 2782
0x09000301, // 2644
0x19000200, // 2638
0x11000700, // 2618
0x21000200, // 2518
0x0d000202, // 2484
0x10000100, // 2480
0x0f000600, // 2413
0x14000300, // 2363
0x0c000500, // 2362
0x08000301, // 2285
0x20000200, // 2245
0x10000700, // 2240
0x0f000100, // 2236
0x1e000200, // 2214
0x0c000400, // 2193
0x16000300, // 2171
0x12000600, // 2132
0x22000200, // 2011
0x1d000200, // 2011
0x0c000f00, // 1996
0x0e000700, // 1971
0x0a000400, // 1970
0x09000201, // 1932
0x10000600, // 1903
0x15000300, // 1847
0x0a000101, // 1814
0x0a000b00, // 1771
0x0c000601, // 1737
0x09000700, // 1737
0x07000300, // 1684
};
#endif // _TARGET_X86_
|