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 | #ifndef __DISASSEMBLER_H__ |
6 | #define __DISASSEMBLER_H__ |
7 | |
8 | #include "switches.h" |
9 | |
10 | #define USE_COREDISTOOLS_DISASSEMBLER 0 |
11 | #define USE_MSVC_DISASSEMBLER 0 |
12 | #ifdef HAVE_GCCOVER |
13 | // COREDISTOOLS disassembler only supports amd64 and x86, so if this is |
14 | // CoreCLR but not amd64 and not x86, we will fall out of this check and not |
15 | // set USE_DISASSEMBLER. |
16 | #if defined(_TARGET_AMD64_) || defined(_TARGET_X86_) |
17 | #undef USE_COREDISTOOLS_DISASSEMBLER |
18 | #define USE_COREDISTOOLS_DISASSEMBLER 1 |
19 | #endif |
20 | #endif // HAVE_GCCOVER |
21 | |
22 | #if USE_COREDISTOOLS_DISASSEMBLER |
23 | #include "coredistools.h" |
24 | #endif |
25 | |
26 | #if USE_COREDISTOOLS_DISASSEMBLER || USE_MSVC_DISASSEMBLER |
27 | #define USE_DISASSEMBLER 1 |
28 | #else |
29 | #define USE_DISASSEMBLER 0 |
30 | #endif |
31 | |
32 | #if USE_DISASSEMBLER |
33 | |
34 | #if USE_MSVC_DISASSEMBLER |
35 | #undef free |
36 | |
37 | // This pragma is needed because public\vc\inc\xiosbase contains |
38 | // a static local variable |
39 | #pragma warning(disable : 4640) |
40 | #include "msvcdis.h" |
41 | #pragma warning(default : 4640) |
42 | |
43 | #include "disx86.h" |
44 | |
45 | #define free(memblock) Use_free(memblock) |
46 | #endif // USE_MSVC_DISASSEMBLER |
47 | |
48 | enum class InstructionType : UINT8 |
49 | { |
50 | Unknown, |
51 | Call_DirectUnconditional, |
52 | Call_IndirectUnconditional, |
53 | Branch_IndirectUnconditional |
54 | }; |
55 | |
56 | class InstructionInfo; |
57 | |
58 | // Wraps the MSVC disassembler or the coredistools disassembler |
59 | class Disassembler |
60 | { |
61 | #if USE_COREDISTOOLS_DISASSEMBLER |
62 | private: |
63 | typedef CorDisasm ExternalDisassembler; |
64 | #elif USE_MSVC_DISASSEMBLER |
65 | private: |
66 | typedef DIS ExternalDisassembler; |
67 | #endif // USE_COREDISTOOLS_DISASSEMBLER || USE_MSVC_DISASSEMBLER |
68 | |
69 | #if defined(_TARGET_AMD64_) || defined(_TARGET_X86_) |
70 | public: |
71 | static bool IsRexPrefix(UINT8 potentialRexByte); |
72 | static UINT8 DecodeModFromModRm(UINT8 modRm); |
73 | static UINT8 DecodeRegOrOpCodeFromModRm(UINT8 modRm); |
74 | static UINT8 DecodeRmFromModRm(UINT8 modRm); |
75 | #endif // defined(_TARGET_AMD64_) || defined(_TARGET_X86_) |
76 | |
77 | public: |
78 | static bool IsAvailable(); |
79 | static void StaticInitialize(); |
80 | static void StaticClose(); |
81 | |
82 | public: |
83 | Disassembler(); |
84 | ~Disassembler(); |
85 | |
86 | public: |
87 | SIZE_T DisassembleInstruction(const UINT8 *code, SIZE_T codeLength, InstructionType *instructionTypeRef) const; |
88 | static InstructionType DetermineInstructionType( |
89 | #if USE_COREDISTOOLS_DISASSEMBLER |
90 | const UINT8 *instructionCode, SIZE_T instructionCodeLength |
91 | #elif USE_MSVC_DISASSEMBLER |
92 | ExternalDisassembler::TRMT terminationType |
93 | #endif // USE_COREDISTOOLS_DISASSEMBLER || USE_MSVC_DISASSEMBLER |
94 | ); |
95 | |
96 | #if USE_COREDISTOOLS_DISASSEMBLER |
97 | private: |
98 | static HMODULE s_libraryHandle; |
99 | static InitDisasm_t *External_InitDisasm; |
100 | static FinishDisasm_t *External_FinishDisasm; |
101 | static DisasmInstruction_t *External_DisasmInstruction; |
102 | #endif // USE_COREDISTOOLS_DISASSEMBLER |
103 | |
104 | private: |
105 | static ExternalDisassembler *s_availableExternalDisassembler; |
106 | ExternalDisassembler *m_externalDisassembler; |
107 | }; |
108 | |
109 | #endif // USE_DISASSEMBLER |
110 | #endif // __DISASSEMBLER_H__ |
111 | |