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 "asmdumper.h"
8
9void ASMDumper::DumpToFile(HANDLE hFile, MethodContext* mc, CompileResult* cr)
10{
11 CORINFO_METHOD_INFO info;
12 unsigned flags = 0;
13 mc->repCompileMethod(&info, &flags);
14
15#define bufflen 4096
16 DWORD bytesWritten;
17 char buff[bufflen];
18
19 int buff_offset = 0;
20 ZeroMemory(buff, bufflen * sizeof(char));
21 buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset,
22 ";;Generated from SuperPMI on original input '%s'", cr->repProcessName());
23 buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, "\r\n Method Name \"%s\"",
24 mc->repGetMethodName(info.ftn, nullptr));
25 WriteFile(hFile, buff, buff_offset * sizeof(char), &bytesWritten, nullptr);
26
27 ULONG hotCodeSize;
28 ULONG coldCodeSize;
29 ULONG roDataSize;
30 ULONG xcptnsCount;
31 CorJitAllocMemFlag flag;
32 unsigned char* hotCodeBlock;
33 unsigned char* coldCodeBlock;
34 unsigned char* roDataBlock;
35 void* orig_hotCodeBlock;
36 void* orig_coldCodeBlock;
37 void* orig_roDataBlock;
38
39 cr->repAllocMem(&hotCodeSize, &coldCodeSize, &roDataSize, &xcptnsCount, &flag, &hotCodeBlock, &coldCodeBlock,
40 &roDataBlock, &orig_hotCodeBlock, &orig_coldCodeBlock, &orig_roDataBlock);
41 cr->applyRelocs(hotCodeBlock, hotCodeSize, orig_hotCodeBlock);
42 cr->applyRelocs(coldCodeBlock, coldCodeSize, orig_coldCodeBlock);
43 cr->applyRelocs(roDataBlock, roDataSize, orig_roDataBlock);
44
45#ifdef USE_MSVCDIS
46
47#ifdef _TARGET_AMD64_
48 DIS* disasm = DIS::PdisNew(DIS::distX8664);
49#elif _TARGET_X86_
50 DIS* disasm = DIS::PdisNew(DIS::distX86);
51#endif
52 size_t offset = 0;
53 while (offset < hotCodeSize)
54 {
55 buff_offset = 0;
56 ZeroMemory(buff, bufflen * sizeof(char));
57
58 DIS::INSTRUCTION instr;
59 DIS::OPERAND ops[3];
60
61 size_t instrSize = disasm->CbDisassemble(0, (void*)(hotCodeBlock + offset), 15);
62 if (instrSize == 0)
63 {
64 LogWarning("Zero sized instruction");
65 break;
66 }
67 disasm->FDecode(&instr, ops, 3);
68
69 wchar_t instrMnemonic[64]; // I never know how much to allocate...
70 disasm->CchFormatInstr(instrMnemonic, 64);
71 buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, "\r\n%p %S",
72 (void*)((size_t)orig_hotCodeBlock + offset), instrMnemonic);
73 buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, " ; ");
74 for (unsigned int i = 0; i < instrSize; i++)
75 buff_offset +=
76 sprintf_s(&buff[buff_offset], bufflen - buff_offset, "%02x ", *((BYTE*)(hotCodeBlock + offset + i)));
77 WriteFile(hFile, buff, buff_offset * sizeof(char), &bytesWritten, nullptr);
78 offset += instrSize;
79 }
80
81 delete disasm;
82
83#else // !USE_MSVCDIS
84
85 buff_offset = 0;
86 ZeroMemory(buff, bufflen * sizeof(char));
87 buff_offset += sprintf_s(&buff[buff_offset], bufflen - buff_offset, ";; No disassembler available");
88 WriteFile(hFile, buff, buff_offset * sizeof(char), &bytesWritten, nullptr);
89
90#endif // !USE_MSVCDIS
91
92 FlushFileBuffers(hFile);
93}