1//
2// Copyright (c) Microsoft. All rights reserved.
3// Licensed under the MIT license. See LICENSE file in the project root for full license information.
4//
5
6#include "standardpch.h"
7#include "simpletimer.h"
8#include "methodcontext.h"
9#include "methodcontextiterator.h"
10#include "verbildump.h"
11
12void DumpPrimToConsoleBare(MethodContext* mc, CorInfoType prim, DWORDLONG classHandle)
13{
14 switch (prim)
15 {
16 case CORINFO_TYPE_VOID:
17 printf("void");
18 return;
19 case CORINFO_TYPE_BOOL:
20 printf("bool");
21 return;
22 case CORINFO_TYPE_CHAR:
23 printf("char");
24 return;
25 case CORINFO_TYPE_BYTE:
26 printf("int8");
27 return;
28 case CORINFO_TYPE_UBYTE:
29 printf("unsigned int8");
30 return;
31 case CORINFO_TYPE_SHORT:
32 printf("int16");
33 return;
34 case CORINFO_TYPE_USHORT:
35 printf("unsigned int16");
36 return;
37 case CORINFO_TYPE_INT:
38 printf("int32");
39 return;
40 case CORINFO_TYPE_UINT:
41 printf("unsigned int32");
42 return;
43 case CORINFO_TYPE_LONG:
44 printf("int64");
45 return;
46 case CORINFO_TYPE_ULONG:
47 printf("unsigned int64");
48 return;
49 case CORINFO_TYPE_NATIVEINT:
50 printf("native int");
51 return;
52 case CORINFO_TYPE_NATIVEUINT:
53 printf("native unsigned int");
54 return;
55 case CORINFO_TYPE_FLOAT:
56 printf("float32");
57 return;
58 case CORINFO_TYPE_DOUBLE:
59 printf("float64");
60 return;
61 // case CORINFO_TYPE_STRING: printf("string"); return;
62 case CORINFO_TYPE_PTR:
63 printf("ptr");
64 return;
65 case CORINFO_TYPE_BYREF:
66 printf("byref");
67 return;
68 case CORINFO_TYPE_VALUECLASS:
69 printf("valueclass %s", mc->repGetClassName((CORINFO_CLASS_HANDLE)classHandle));
70 return;
71 case CORINFO_TYPE_CLASS:
72 printf("class %s", mc->repGetClassName((CORINFO_CLASS_HANDLE)classHandle));
73 return;
74 case CORINFO_TYPE_REFANY:
75 printf("refany");
76 return;
77 case CORINFO_TYPE_VAR:
78 printf("var");
79 return;
80 default:
81 LogWarning("unknown type in PrimToString(0x%x)", prim);
82 __debugbreak();
83 return;
84 }
85}
86void DumpSigToConsoleBare(MethodContext* mc, CORINFO_SIG_INFO* pSig)
87{
88 CORINFO_ARG_LIST_HANDLE currentItem = pSig->args;
89 DWORD exceptionCode;
90
91 for (int i = 0; i < (int)pSig->numArgs; i++)
92 {
93 DWORDLONG dl;
94 CorInfoTypeWithMod type = mc->repGetArgType(pSig, currentItem, (CORINFO_CLASS_HANDLE*)&dl, &exceptionCode);
95 CorInfoType cit = strip(type);
96 if (cit == CORINFO_TYPE_CLASS)
97 dl = (DWORDLONG)mc->repGetArgClass(pSig, currentItem, &exceptionCode);
98 if ((type & CORINFO_TYPE_MOD_PINNED) == CORINFO_TYPE_MOD_PINNED)
99 printf("pinned ");
100 DumpPrimToConsoleBare(mc, cit, dl);
101 currentItem = mc->repGetArgNext(currentItem);
102 if (i + 1 < (int)pSig->numArgs)
103 printf(", ");
104 }
105}
106
107void DumpILToConsoleBare(unsigned char* ilCode, int len)
108{
109 int i, j, k;
110 for (i = 0; i < len; i++)
111 {
112 printf("IL_%04x: ", i);
113 switch (ilCode[i])
114 {
115 case 0x00:
116 printf("nop");
117 continue;
118 case 0x01:
119 printf("break");
120 continue;
121 case 0x02:
122 printf("ldarg.0");
123 continue;
124 case 0x03:
125 printf("ldarg.1");
126 continue;
127 case 0x04:
128 printf("ldarg.2");
129 continue;
130 case 0x05:
131 printf("ldarg.3");
132 continue;
133 case 0x06:
134 printf("ldloc.0");
135 continue;
136 case 0x07:
137 printf("ldloc.1");
138 continue;
139 case 0x08:
140 printf("ldloc.2");
141 continue;
142 case 0x09:
143 printf("ldloc.3");
144 continue;
145 case 0x0a:
146 printf("stloc.0");
147 continue;
148 case 0x0b:
149 printf("stloc.1");
150 continue;
151 case 0x0c:
152 printf("stloc.2");
153 continue;
154 case 0x0d:
155 printf("stloc.3");
156 continue;
157 case 0x0e: // ldarg.s X
158 printf("ldarg.s 0x%02x", ilCode[i + 1]);
159 i += 1;
160 continue;
161 case 0x0f: // ldarga.s X
162 printf("ldarga.s 0x%02x", ilCode[i + 1]);
163 i += 1;
164 continue;
165 case 0x10: // starg.s X
166 printf("starg.s 0x%02x", ilCode[i + 1]);
167 i += 1;
168 continue;
169 case 0x11: // ldloc.s X
170 printf("ldloc.s 0x%02x", ilCode[i + 1]);
171 i += 1;
172 continue;
173 case 0x12: // ldloca.s X
174 printf("ldloca.s 0x%02x", ilCode[i + 1]);
175 i += 1;
176 continue;
177 case 0x13: // stloc.s X
178 printf("stloc.s 0x%02x", ilCode[i + 1]);
179 i += 1;
180 continue;
181 case 0x14:
182 printf("ldnull");
183 continue;
184 case 0x15:
185 printf("ldc.i4.m1");
186 continue;
187 case 0x16:
188 printf("ldc.i4.0");
189 continue;
190 case 0x17:
191 printf("ldc.i4.1");
192 continue;
193 case 0x18:
194 printf("ldc.i4.2");
195 continue;
196 case 0x19:
197 printf("ldc.i4.3");
198 continue;
199 case 0x1a:
200 printf("ldc.i4.4");
201 continue;
202 case 0x1b:
203 printf("ldc.i4.5");
204 continue;
205 case 0x1c:
206 printf("ldc.i4.6");
207 continue;
208 case 0x1d:
209 printf("ldc.i4.7");
210 continue;
211 case 0x1e:
212 printf("ldc.i4.8");
213 continue;
214 case 0x1f: // ldc.i4.s X
215 printf("ldc.i4.s 0x%02x", ilCode[i + 1]);
216 i += 1;
217 continue;
218 case 0x20: // ldc.i4 XXXX
219 printf("ldc.i4 0x%02x%02x%02x%02x", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
220 i += 4;
221 continue;
222 case 0x21: // ldc.i8 XXXXXXXX
223 printf("ldc.i8 0x%02x%02x%02x%02x%02x%02x%02x%02x", ilCode[i + 8], ilCode[i + 7], ilCode[i + 6],
224 ilCode[i + 5], ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
225 i += 8;
226 continue;
227 case 0x22: // ldc.r4 XXXX
228 printf("ldc.r4 float32(0x%02x%02x%02x%02x)", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2],
229 ilCode[i + 1]);
230 i += 4;
231 continue;
232 case 0x23: // ldc.r8 XXXXXXXX
233 printf("ldc.r8 float64(0x%02x%02x%02x%02x%02x%02x%02x%02x)", ilCode[i + 8], ilCode[i + 7],
234 ilCode[i + 6], ilCode[i + 5], ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
235 i += 8;
236 continue;
237 case 0x25:
238 printf("dup");
239 continue;
240 case 0x26:
241 printf("pop");
242 continue;
243 case 0x27: // JMP <T>
244 printf("jmp <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
245 i += 4;
246 continue;
247 case 0x28: // call <T>
248 printf("call <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
249 i += 4;
250 continue;
251 case 0x29: // calli <T>
252 printf("calli <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
253 i += 4;
254 continue;
255 case 0x2a:
256 printf("ret");
257 continue;
258 case 0x2b: // br.s X
259 printf("br.s IL_%04x", i + 2 + ilCode[i + 1]);
260 ;
261 i += 1;
262 continue;
263 case 0x2c: // brfalse.s X
264 printf("brfalse.s IL_%04x", i + 2 + ilCode[i + 1]);
265 ;
266 i += 1;
267 continue;
268 case 0x2d: // brtrue.s X
269 printf("brtrue.s IL_%04x", i + 2 + ilCode[i + 1]);
270 ;
271 i += 1;
272 continue;
273 case 0x2e: // beq.s X
274 printf("beq.s IL_%04x", i + 2 + ilCode[i + 1]);
275 ;
276 i += 1;
277 continue;
278 case 0x2f: // bgt.s X
279 printf("bgt.s IL_%04x", i + 2 + ilCode[i + 1]);
280 ;
281 i += 1;
282 continue;
283 case 0x30: // bgt.s X
284 printf("bgt.s IL_%04x", i + 2 + ilCode[i + 1]);
285 ;
286 i += 1;
287 continue;
288 case 0x31: // ble.s X
289 printf("ble.s IL_%04x", i + 2 + ilCode[i + 1]);
290 ;
291 i += 1;
292 continue;
293 case 0x32: // blt.s X
294 printf("blt.s IL_%04x", i + 2 + ilCode[i + 1]);
295 ;
296 i += 1;
297 continue;
298 case 0x33: // bne.un.s X
299 printf("bne.un.s IL_%04x", i + 2 + ilCode[i + 1]);
300 ;
301 i += 1;
302 continue;
303 case 0x34: // bge.un.s X
304 printf("bge.un.s IL_%04x", i + 2 + ilCode[i + 1]);
305 ;
306 i += 1;
307 continue;
308 case 0x35: // bgt.un.s X
309 printf("bgt.un.s IL_%04x", i + 2 + ilCode[i + 1]);
310 ;
311 i += 1;
312 continue;
313 case 0x36: // ble.un.s X
314 printf("ble.un.s IL_%04x", i + 2 + ilCode[i + 1]);
315 ;
316 i += 1;
317 continue;
318 case 0x37: // blt.un.s X
319 printf("blt.un.s IL_%04x", i + 2 + ilCode[i + 1]);
320 ;
321 i += 1;
322 continue;
323 case 0x38: // br XXXX
324 printf("br IL_%04x",
325 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
326 i += 4;
327 continue;
328 case 0x39: // brfalse XXXX
329 printf("brfalse IL_%04x",
330 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
331 i += 4;
332 continue;
333 case 0x3a: // brtrue XXXX
334 printf("brtrue IL_%04x",
335 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
336 i += 4;
337 continue;
338 case 0x3b: // beq XXXX
339 printf("beq IL_%04x",
340 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
341 i += 4;
342 continue;
343 case 0x3c: // bgt XXXX
344 printf("bgt IL_%04x",
345 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
346 i += 4;
347 continue;
348 case 0x3d: // bgt XXXX
349 printf("bgt IL_%04x",
350 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
351 i += 4;
352 continue;
353 case 0x3e: // ble XXXX
354 printf("ble IL_%04x",
355 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
356 i += 4;
357 continue;
358 case 0x3f: // blt XXXX
359 printf("blt IL_%04x",
360 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
361 i += 4;
362 continue;
363 case 0x40: // bne.un XXXX
364 printf("bne.un IL_%04x",
365 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
366 i += 4;
367 continue;
368 case 0x41: // bge.un XXXX
369 printf("bge.un IL_%04x",
370 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
371 i += 4;
372 continue;
373 case 0x42: // bgt.un XXXX
374 printf("bgt.un IL_%04x",
375 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
376 i += 4;
377 continue;
378 case 0x43: // ble.un XXXX
379 printf("ble.un IL_%04x",
380 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
381 i += 4;
382 continue;
383 case 0x44: // blt.un XXXX
384 printf("blt.un IL_%04x",
385 i + 5 + (ilCode[i + 4] << 24 | ilCode[i + 3] << 16 | ilCode[i + 2] << 8 | ilCode[i + 1]));
386 i += 4;
387 continue;
388 case 0x45: // switch NNNN NNNN*XXXX
389 printf("switch (0x%02x%02x%02x%02x)", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
390 k = (ilCode[i + 4] << 24) | (ilCode[i + 3] << 16) | (ilCode[i + 2] << 8) | (ilCode[i + 1] << 0);
391 i += 4;
392 for (j = 0; j < k; j++)
393 {
394 printf(" <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
395 i += 4;
396 }
397 continue;
398 case 0x46:
399 printf("ldind.i1");
400 continue;
401 case 0x47:
402 printf("ldind.u1");
403 continue;
404 case 0x48:
405 printf("ldind.i2");
406 continue;
407 case 0x49:
408 printf("ldind.u2");
409 continue;
410 case 0x4a:
411 printf("ldind.i4");
412 continue;
413 case 0x4b:
414 printf("ldind.u4");
415 continue;
416 case 0x4c:
417 printf("ldind.i8");
418 continue;
419 case 0x4d:
420 printf("ldind.u8");
421 continue;
422 case 0x4e:
423 printf("ldind.r4");
424 continue;
425 case 0x4f:
426 printf("ldind.r8");
427 continue;
428 case 0x50:
429 printf("ldind.ref");
430 continue;
431 case 0x51:
432 printf("stind.ref");
433 continue;
434 case 0x52:
435 printf("stind.i1");
436 continue;
437 case 0x53:
438 printf("stind.i2");
439 continue;
440 case 0x54:
441 printf("stind.i4");
442 continue;
443 case 0x55:
444 printf("stind.i8");
445 continue;
446 case 0x56:
447 printf("stind.r4");
448 continue;
449 case 0x57:
450 printf("stind.r8");
451 continue;
452 case 0x58:
453 printf("add");
454 continue;
455 case 0x59:
456 printf("sub");
457 continue;
458 case 0x5a:
459 printf("mul");
460 continue;
461 case 0x5b:
462 printf("div");
463 continue;
464 case 0x5c:
465 printf("div.un");
466 continue;
467 case 0x5d:
468 printf("rem");
469 continue;
470 case 0x5e:
471 printf("rem.un");
472 continue;
473 case 0x5f:
474 printf("and");
475 continue;
476 case 0x60:
477 printf("or");
478 continue;
479 case 0x61:
480 printf("xor");
481 continue;
482 case 0x62:
483 printf("shl");
484 continue;
485 case 0x63:
486 printf("shr");
487 continue;
488 case 0x64:
489 printf("shr.un");
490 continue;
491 case 0x65:
492 printf("neg");
493 continue;
494 case 0x66:
495 printf("not");
496 continue;
497 case 0x67:
498 printf("conv.i1");
499 continue;
500 case 0x68:
501 printf("conv.i2");
502 continue;
503 case 0x69:
504 printf("conv.i4");
505 continue;
506 case 0x6a:
507 printf("conv.i8");
508 continue;
509 case 0x6b:
510 printf("conv.r4");
511 continue;
512 case 0x6c:
513 printf("conv.r8");
514 continue;
515 case 0x6d:
516 printf("conv.u4");
517 continue;
518 case 0x6e:
519 printf("conv.u8");
520 continue;
521 case 0x6f: // callvirt <T>
522 printf("callvirt <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
523 i += 4;
524 continue;
525 case 0x70: // cpobj <T>
526 printf("cpobj <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
527 i += 4;
528 continue;
529 case 0x71: // ldobj <T>
530 printf("ldobj <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
531 i += 4;
532 continue;
533 case 0x72: // ldstr <T>
534 printf("ldstr <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
535 i += 4;
536 continue;
537 case 0x73: // newobj <T>
538 printf("newobj <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
539 i += 4;
540 continue;
541 case 0x74: // castclass <T>
542 printf("castclass <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
543 i += 4;
544 continue;
545 case 0x75: // isinst <T>
546 printf("isinst <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
547 i += 4;
548 continue;
549 case 0x76:
550 printf("conv.r.un");
551 continue;
552 case 0x79: // unbox <T>
553 printf("unbox <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
554 i += 4;
555 continue;
556 case 0x7a:
557 printf("throw");
558 continue;
559 case 0x7b: // ldfld <T>
560 printf("ldfld <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
561 i += 4;
562 continue;
563 case 0x7c: // ldflda <T>
564 printf("ldflda <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
565 i += 4;
566 continue;
567 case 0x7d: // stfld <T>
568 printf("stfld <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
569 i += 4;
570 continue;
571 case 0x7e: // ldsfld <T>
572 printf("ldsfld <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
573 i += 4;
574 continue;
575 case 0x7f: // ldsflda <T>
576 printf("ldsflda <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
577 i += 4;
578 continue;
579 case 0x80: // stsfld <T>
580 printf("stsfld <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
581 i += 4;
582 continue;
583 case 0x81: // stobj <T>
584 printf("stobj <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
585 i += 4;
586 continue;
587 case 0x82:
588 printf("conv.ovf.i1.un");
589 continue;
590 case 0x83:
591 printf("conv.ovf.i2.un");
592 continue;
593 case 0x84:
594 printf("conv.ovf.i4.un");
595 continue;
596 case 0x85:
597 printf("conv.ovf.i8.un");
598 continue;
599 case 0x86:
600 printf("conv.ovf.u1.un");
601 continue;
602 case 0x87:
603 printf("conv.ovf.u2.un");
604 continue;
605 case 0x88:
606 printf("conv.ovf.u4.un");
607 continue;
608 case 0x89:
609 printf("conv.ovf.u8.un");
610 continue;
611 case 0x8a:
612 printf("conv.ovf.i.un");
613 continue;
614 case 0x8b:
615 printf("conv.ovf.u.un");
616 continue;
617 case 0x8c: // box <T>
618 printf("box <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
619 i += 4;
620 continue;
621 case 0x8d: // newarr <T>
622 printf("newarr <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
623 i += 4;
624 continue;
625 case 0x8e:
626 printf("ldlen");
627 continue;
628 case 0x8f:
629 printf("ldelema <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
630 i += 4;
631 continue;
632 case 0x90:
633 printf("ldelem.i1");
634 continue;
635 case 0x91:
636 printf("ldelem.u1");
637 continue;
638 case 0x92:
639 printf("ldelem.i2");
640 continue;
641 case 0x93:
642 printf("ldelem.u2");
643 continue;
644 case 0x94:
645 printf("ldelem.i4");
646 continue;
647 case 0x95:
648 printf("ldelem.u4");
649 continue;
650 case 0x96:
651 printf("ldelem.i8");
652 continue;
653 case 0x97:
654 printf("ldelem.i");
655 continue;
656 case 0x98:
657 printf("ldelem.r4");
658 continue;
659 case 0x99:
660 printf("ldelem.r8");
661 continue;
662 case 0x9a:
663 printf("ldelem.ref");
664 continue;
665 case 0x9b:
666 printf("stelem.i");
667 continue;
668 case 0x9c:
669 printf("stelem.i1");
670 continue;
671 case 0x9d:
672 printf("stelem.i2");
673 continue;
674 case 0x9e:
675 printf("stelem.i4");
676 continue;
677 case 0x9f:
678 printf("stelem.i8");
679 continue;
680 case 0xa0:
681 printf("stelem.r4");
682 continue;
683 case 0xa1:
684 printf("stelem.r8");
685 continue;
686 case 0xa2:
687 printf("stelem.ref");
688 continue;
689 case 0xa3:
690 printf("stelem <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
691 i += 4;
692 continue;
693 case 0xa4:
694 printf("stelem <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
695 i += 4;
696 continue;
697 case 0xa5:
698 printf("unbox.any <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
699 i += 4;
700 continue;
701 case 0xb3:
702 printf("conv.ovf.i1");
703 continue;
704 case 0xb4:
705 printf("conv.ovf.u1");
706 continue;
707 case 0xb5:
708 printf("conv.ovf.i2");
709 continue;
710 case 0xb6:
711 printf("conv.ovf.u2");
712 continue;
713 case 0xb7:
714 printf("conv.ovf.i4");
715 continue;
716 case 0xb8:
717 printf("conv.ovf.u4");
718 continue;
719 case 0xb9:
720 printf("conv.ovf.i8");
721 continue;
722 case 0xba:
723 printf("conv.ovf.u8");
724 continue;
725 case 0xc2: // refanyval <T>
726 printf("refanyval <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
727 i += 4;
728 continue;
729 case 0xc3:
730 printf("ckfinite");
731 continue;
732 case 0xc6: // mkrefany <T>
733 printf("mkrefany <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
734 i += 4;
735 continue;
736 case 0xd0: // ldtoken <T>
737 printf("ldtoken <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
738 i += 4;
739 continue;
740 case 0xd1:
741 printf("conv.u2");
742 continue;
743 case 0xd2:
744 printf("conv.u1");
745 continue;
746 case 0xd3:
747 printf("conv.i");
748 continue;
749 case 0xd4:
750 printf("conv.ovf.i");
751 continue;
752 case 0xd5:
753 printf("conv.ovf.u");
754 continue;
755 case 0xd6:
756 printf("add.ovf");
757 continue;
758 case 0xd7:
759 printf("add.ovf.un");
760 continue;
761 case 0xd8:
762 printf("mul.ovf");
763 continue;
764 case 0xd9:
765 printf("mul.ovf.un");
766 continue;
767 case 0xda:
768 printf("sub.ovf");
769 continue;
770 case 0xdb:
771 printf("sub.ovf.un");
772 continue;
773 case 0xdc:
774 printf("endfinally");
775 continue;
776 case 0xdd: // leave XXXX
777 printf("leave 0x%02x%02x%02x%02x", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2], ilCode[i + 1]);
778 i += 4;
779 continue;
780 case 0xde: // leave.s X
781 printf("leave 0x%02x", ilCode[i + 1]);
782 i += 1;
783 continue;
784 case 0xdf:
785 printf("stind.i");
786 continue;
787 case 0xe0:
788 printf("conv.u");
789 continue;
790 case 0xfe:
791 i++;
792 switch (ilCode[i])
793 {
794 case 0x00:
795 printf("arglist");
796 continue;
797 case 0x01:
798 printf("ceq");
799 continue;
800 case 0x02:
801 printf("cgt");
802 continue;
803 case 0x03:
804 printf("cgt.un");
805 continue;
806 case 0x04:
807 printf("clt");
808 continue;
809 case 0x05:
810 printf("clt.un");
811 continue;
812 case 0x06: // ldftn <T>
813 printf("ldftn <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2],
814 ilCode[i + 1]);
815 i += 4;
816 continue;
817 case 0x07: // ldvirtftn <T>
818 printf("ldvirtftn <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2],
819 ilCode[i + 1]);
820 i += 4;
821 continue;
822 case 0x09: // ldarg XX
823 printf("ldarg 0x%02x%02x", ilCode[i + 2], ilCode[i + 1]);
824 i += 2;
825 continue;
826 case 0x0a: // ldarga XX
827 printf("ldarga 0x%02x%02x", ilCode[i + 2], ilCode[i + 1]);
828 i += 2;
829 continue;
830 case 0x0b: // starg XX
831 printf("starg 0x%02x%02x", ilCode[i + 2], ilCode[i + 1]);
832 i += 2;
833 continue;
834 case 0x0c: // ldloc XX
835 printf("ldloc 0x%02x%02x", ilCode[i + 2], ilCode[i + 1]);
836 i += 2;
837 continue;
838 case 0x0d: // ldloca XX
839 printf("ldloca 0x%02x%02x", ilCode[i + 2], ilCode[i + 1]);
840 i += 2;
841 continue;
842 case 0x0e: // stloc XX
843 printf("stloc 0x%02x%02x", ilCode[i + 2], ilCode[i + 1]);
844 i += 2;
845 continue;
846 case 0x0f:
847 printf("localloc");
848 continue;
849 case 0x11:
850 printf("endfilter");
851 continue;
852 case 0x12: // unaligned X
853 printf("unaligned. 0x%02x", ilCode[i + 1]);
854 i += 1;
855 continue;
856 case 0x13:
857 printf("volatile.");
858 continue;
859 case 0x14:
860 printf("tail.");
861 continue;
862 case 0x15: // initobj <T>
863 printf("initobj <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2],
864 ilCode[i + 1]);
865 i += 4;
866 continue;
867 case 0x16: // incomplete?
868 printf("constrained. <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2],
869 ilCode[i + 1]);
870 i += 4;
871 continue;
872 case 0x17:
873 printf("cpblk");
874 continue;
875 case 0x18:
876 printf("initblk");
877 continue;
878 case 0x19:
879 printf("no.");
880 continue; // incomplete?
881 case 0x1a:
882 printf("rethrow");
883 continue;
884 case 0x1c: // sizeof <T>
885 printf("sizeof <0x%02x%02x%02x%02x>", ilCode[i + 4], ilCode[i + 3], ilCode[i + 2],
886 ilCode[i + 1]);
887 i += 4;
888 continue;
889 case 0x1d:
890 printf("refanytype");
891 continue;
892 default:
893 LogError("unknown ilCode 0xfe%2x at offset %d in MethodGen::PrettyPrint", ilCode[i], i);
894 break;
895 }
896 default:
897 LogError("unknown ilCode 0x%02x at offset %d in MethodGen::PrettyPrint", ilCode[i], i);
898 break;
899 }
900 printf("\n");
901 }
902}
903char* DumpAttributeToConsoleBare(DWORD attribute)
904{
905 const char* s_static = "static";
906 const char* s_dontInline = "$dontInline ";
907 const char* s_constructor = "$constructor";
908 const char* s_cfnw = "$noSecurityWrap";
909
910#define ifPrint(s, t) \
911 else if ((s & attribute) == s) \
912 { \
913 printf(t); \
914 printf(" "); \
915 }
916
917 if (0)
918 ;
919 ifPrint(CORINFO_FLG_STATIC, s_static) ifPrint(CORINFO_FLG_DONT_INLINE, s_dontInline)
920 ifPrint(CORINFO_FLG_CONSTRUCTOR, s_constructor) ifPrint(CORINFO_FLG_NOSECURITYWRAP, s_cfnw) else
921 {
922 LogError("unknown attribute %x", attribute);
923 __debugbreak();
924 }
925 return nullptr;
926
927#undef ifPrint
928}
929
930void DumpIL(MethodContext* mc)
931{
932 CORINFO_METHOD_INFO cmi;
933 unsigned int flags = 0;
934
935 mc->repCompileMethod(&cmi, &flags);
936
937 const char* moduleName = nullptr;
938 const char* methodName = mc->repGetMethodName(cmi.ftn, &moduleName);
939 const char* className = mc->repGetClassName(mc->repGetMethodClass(cmi.ftn));
940
941 printf("// ProcessName - '%s'\n", mc->cr->repProcessName());
942 printf(".assembly extern mscorlib{}\n");
943 printf(".assembly %s{}\n", moduleName);
944 printf(".class %s\n", className);
945 printf("{\n");
946 printf(" .method ");
947 DumpAttributeToConsoleBare(mc->repGetMethodAttribs(cmi.ftn));
948 DumpPrimToConsoleBare(mc, cmi.args.retType, (DWORDLONG)cmi.args.retTypeClass);
949 printf(" %s(", methodName);
950 DumpSigToConsoleBare(mc, &cmi.args);
951 printf(")\n");
952 printf(" {\n");
953 printf(" .maxstack %u\n", cmi.maxStack);
954 printf(" .locals%s(", (((cmi.options & CORINFO_OPT_INIT_LOCALS) == CORINFO_OPT_INIT_LOCALS) ? " init " : " "));
955 DumpSigToConsoleBare(mc, &cmi.locals);
956 printf(")\n");
957 DumpILToConsoleBare(cmi.ILCode, cmi.ILCodeSize);
958 printf(" }\n");
959 printf("}\n");
960}
961
962int verbILDump::DoWork(const char* nameOfInput, int indexCount, const int* indexes)
963{
964 LogVerbose("// Reading from '%s' dumping raw IL for MC Indexes to console", nameOfInput);
965
966 MethodContextIterator mci(indexCount, indexes);
967 if (!mci.Initialize(nameOfInput))
968 return -1;
969
970 int dumpedCount = 0;
971
972 while (mci.MoveNext())
973 {
974 MethodContext* mc = mci.Current();
975 DumpIL(mc);
976 dumpedCount++;
977 }
978
979 LogInfo("// Dumped %d", dumpedCount);
980
981 if (!mci.Destroy())
982 return -1;
983
984 return 0;
985}
986