summaryrefslogtreecommitdiff
path: root/src/vm/disassembler.h
blob: 5a7976a44f44399309b8b513559eda23e533e559 (plain)
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
// 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
        // COREDISTOOLS disassembler only supports amd64 and x86, so if this is
        // CoreCLR but not amd64 and not x86, we will fall out of this check and not
        // set USE_DISASSEMBLER.
        #if defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
            #undef USE_COREDISTOOLS_DISASSEMBLER
            #define USE_COREDISTOOLS_DISASSEMBLER 1
        #endif
#endif // HAVE_GCCOVER

#if USE_COREDISTOOLS_DISASSEMBLER
#include "coredistools.h"
#endif

#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:
    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;
    static InitDisasm_t *External_InitDisasm;
    static FinishDisasm_t *External_FinishDisasm;
    static DisasmInstruction_t *External_DisasmInstruction;
#endif // USE_COREDISTOOLS_DISASSEMBLER

private:
    static ExternalDisassembler *s_availableExternalDisassembler;
    ExternalDisassembler *m_externalDisassembler;
};

#endif // USE_DISASSEMBLER
#endif // __DISASSEMBLER_H__