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
48enum class InstructionType : UINT8
49{
50 Unknown,
51 Call_DirectUnconditional,
52 Call_IndirectUnconditional,
53 Branch_IndirectUnconditional
54};
55
56class InstructionInfo;
57
58// Wraps the MSVC disassembler or the coredistools disassembler
59class Disassembler
60{
61#if USE_COREDISTOOLS_DISASSEMBLER
62private:
63 typedef CorDisasm ExternalDisassembler;
64#elif USE_MSVC_DISASSEMBLER
65private:
66 typedef DIS ExternalDisassembler;
67#endif // USE_COREDISTOOLS_DISASSEMBLER || USE_MSVC_DISASSEMBLER
68
69#if defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
70public:
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
77public:
78 static bool IsAvailable();
79 static void StaticInitialize();
80 static void StaticClose();
81
82public:
83 Disassembler();
84 ~Disassembler();
85
86public:
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
97private:
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
104private:
105 static ExternalDisassembler *s_availableExternalDisassembler;
106 ExternalDisassembler *m_externalDisassembler;
107};
108
109#endif // USE_DISASSEMBLER
110#endif // __DISASSEMBLER_H__
111