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 | |
12 | void 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 | } |
86 | void 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 | |
107 | void 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 | } |
903 | char* 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 | |
930 | void 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 | |
962 | int 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 | |