1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#ifndef __DISASSEMBLER_H__
#define __DISASSEMBLER_H__
#include "switches.h"
#define USE_COREDISTOOLS_DISASSEMBLER 0
#define USE_MSVC_DISASSEMBLER 0
#ifdef HAVE_GCCOVER
#if defined(FEATURE_CORECLR)
// COREDISTOOLS disassembler only supports amd64, so if this is
// CoreCLR but not amd64, we will fall out of this check and not
// set USE_DISASSEMBLER.
#if defined(_TARGET_AMD64_)
#undef USE_COREDISTOOLS_DISASSEMBLER
#define USE_COREDISTOOLS_DISASSEMBLER 1
#endif
#elif defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
#undef USE_MSVC_DISASSEMBLER
#define USE_MSVC_DISASSEMBLER 1
#endif // defined(FEATURE_CORECLR) || defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
#endif // HAVE_GCCOVER
#if USE_COREDISTOOLS_DISASSEMBLER || USE_MSVC_DISASSEMBLER
#define USE_DISASSEMBLER 1
#else
#define USE_DISASSEMBLER 0
#endif
#if USE_DISASSEMBLER
#if USE_MSVC_DISASSEMBLER
#undef free
// This pragma is needed because public\vc\inc\xiosbase contains
// a static local variable
#pragma warning(disable : 4640)
#include "msvcdis.h"
#pragma warning(default : 4640)
#include "disx86.h"
#define free(memblock) Use_free(memblock)
#endif // USE_MSVC_DISASSEMBLER
enum class InstructionType : UINT8
{
Unknown,
Call_DirectUnconditional,
Call_IndirectUnconditional,
Branch_IndirectUnconditional
};
class InstructionInfo;
// Wraps the MSVC disassembler or the coredistools disassembler
class Disassembler
{
#if USE_COREDISTOOLS_DISASSEMBLER
private:
class CorDisasm;
typedef CorDisasm ExternalDisassembler;
#elif USE_MSVC_DISASSEMBLER
private:
typedef DIS ExternalDisassembler;
#endif // USE_COREDISTOOLS_DISASSEMBLER || USE_MSVC_DISASSEMBLER
#if defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
public:
static bool IsRexPrefix(UINT8 potentialRexByte);
static UINT8 DecodeModFromModRm(UINT8 modRm);
static UINT8 DecodeRegOrOpCodeFromModRm(UINT8 modRm);
static UINT8 DecodeRmFromModRm(UINT8 modRm);
#endif // defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
public:
static bool IsAvailable();
static void StaticInitialize();
static void StaticClose();
public:
Disassembler();
~Disassembler();
public:
SIZE_T DisassembleInstruction(const UINT8 *code, SIZE_T codeLength, InstructionType *instructionTypeRef) const;
static InstructionType DetermineInstructionType(
#if USE_COREDISTOOLS_DISASSEMBLER
const UINT8 *instructionCode, SIZE_T instructionCodeLength
#elif USE_MSVC_DISASSEMBLER
ExternalDisassembler::TRMT terminationType
#endif // USE_COREDISTOOLS_DISASSEMBLER || USE_MSVC_DISASSEMBLER
);
#if USE_COREDISTOOLS_DISASSEMBLER
private:
static HMODULE s_libraryHandle;
// 'coredistools' library exports
private:
enum TargetArch {
Target_Host, // Target is the same as host architecture
Target_X86,
Target_X64,
Target_Thumb,
Target_Arm64
};
static CorDisasm *(*External_InitDisasm)(enum TargetArch Target);
static SIZE_T (*External_DisasmInstruction)(const CorDisasm *Disasm, size_t Address,
const uint8_t *Bytes, size_t Maxlength,
bool PrintAssembly);
static void (*External_FinishDisasm)(const CorDisasm *Disasm);
#endif // USE_COREDISTOOLS_DISASSEMBLER
private:
static ExternalDisassembler *s_availableExternalDisassembler;
ExternalDisassembler *m_externalDisassembler;
};
#endif // USE_DISASSEMBLER
#endif // __DISASSEMBLER_H__
|