--- /dev/null
+// 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.
+
+//===--------- coredistools.h - Dissassembly tools for CoreClr ------------===//
+//
+// Core Disassembly Tools API Version 1.0.1-prerelease
+// Disassembly tools required by CoreCLR for utilities like
+// GCStress and SuperPMI
+//===----------------------------------------------------------------------===//
+
+#if !defined(_COREDISTOOLS_H_)
+#define _COREDISTOOLS_H_
+
+#include <stdint.h>
+
+#if defined(__cplusplus)
+#define EXTERN_C extern "C"
+#else
+#define EXTERN_C
+#endif // defined(__cplusplus)
+
+#if defined(_MSC_VER)
+#if defined(DllInterfaceExporter)
+#define DllIface EXTERN_C __declspec(dllexport)
+#else
+#define DllIface EXTERN_C __declspec(dllimport)
+#endif // defined(DllInterfaceExporter)
+#else
+#define DllIface EXTERN_C
+#endif // defined(_MSC_VER)
+
+enum TargetArch {
+ Target_Host, // Target is the same as host architecture
+ Target_X86,
+ Target_X64,
+ Target_Thumb,
+ Target_Arm64
+};
+
+struct CorDisasm;
+struct CorAsmDiff;
+
+// The custom print functionality to be provide by the
+// users of this Library
+typedef void(*Printer)(const char *msg, ...);
+struct PrintControl {
+ const Printer Error;
+ const Printer Warning;
+ const Printer Log;
+ const Printer Dump;
+};
+
+// The type of a custom function provided by the user to determine
+// if two offsets are considered equivalent wrt diffing code blocks.
+// Offset1 and Offset2 are the two offsets to be compared.
+// BlockOffset is the offest of the instructions (that contain Offset1
+// and Offset2) from the beginning of their respective code blocks.
+// InstructionLength is the length of the current instruction being
+// compared for equivalency.
+typedef bool(*OffsetComparator)(const void *UserData, size_t BlockOffset,
+ size_t InstructionLength, uint64_t Offset1,
+ uint64_t Offset2);
+
+// The Export/Import definitions for CoreDistools library are defined below.
+// A typedef for each interface function's type is defined in order to aid
+// the importer.
+
+// Initialize the disassembler, using default print controls
+typedef CorDisasm *InitDisasm_t(enum TargetArch Target);
+DllIface InitDisasm_t InitDisasm;
+
+// Initialize the disassembler using custom print controls
+typedef CorDisasm *NewDisasm_t(enum TargetArch Target,
+ const PrintControl *PControl);
+DllIface NewDisasm_t NewDisasm;
+
+// Delete the disassembler
+typedef void FinishDisasm_t(const CorDisasm *Disasm);
+DllIface FinishDisasm_t FinishDisasm;
+
+// DisasmInstruction -- Disassemble one instruction
+// Arguments:
+// Disasm -- The Disassembler
+// Address -- The address at which the bytes of the instruction
+// are intended to execute
+// Bytes -- Pointer to the actual bytes which need to be disassembled
+// MaxLength -- Number of bytes available in Bytes buffer
+// Returns:
+// -- The Size of the disassembled instruction
+// -- Zero on failure
+typedef size_t DisasmInstruction_t(const CorDisasm *Disasm,
+ const uint8_t *Address,
+ const uint8_t *Bytes, size_t Maxlength);
+DllIface DisasmInstruction_t DisasmInstruction;
+
+// Initialize the Code Differ
+typedef CorAsmDiff *NewDiffer_t(enum TargetArch Target,
+ const PrintControl *PControl,
+ const OffsetComparator Comparator);
+DllIface NewDiffer_t NewDiffer;
+
+// Delete the Code Differ
+typedef void FinishDiff_t(const CorAsmDiff *AsmDiff);
+DllIface FinishDiff_t FinishDiff;
+
+// NearDiffCodeBlocks -- Compare two code blocks for semantic
+// equivalence
+// Arguments:
+// AsmDiff -- The Asm-differ
+// UserData -- Any data the user wishes to pass through into
+// the OffsetComparator
+// Address1 -- Address at which first block will execute
+// Bytes1 -- Pointer to the actual bytes of the first block
+// Size1 -- The size of the first block
+// Address2 -- Address at which second block will execute
+// Bytes2 -- Pointer to the actual bytes of the second block
+// Size2 -- The size of the second block
+// Returns:
+// -- true if the two blocks are equivalent, false if not.
+typedef bool NearDiffCodeBlocks_t(const CorAsmDiff *AsmDiff,
+ const void *UserData,
+ const uint8_t *Address1,
+ const uint8_t *Bytes1, size_t Size1,
+ const uint8_t *Address2,
+ const uint8_t *Bytes2, size_t Size2);
+DllIface NearDiffCodeBlocks_t NearDiffCodeBlocks;
+
+// Print a code block according to the Disassembler's Print Controls
+typedef void DumpCodeBlock_t(const CorDisasm *Disasm, const uint8_t *Address,
+ const uint8_t *Bytes, size_t Size);
+DllIface DumpCodeBlock_t DumpCodeBlock;
+
+// Print the two code blocks being diffed, according to
+// AsmDiff's PrintControls.
+typedef void DumpDiffBlocks_t(const CorAsmDiff *AsmDiff,
+ const uint8_t *Address1, const uint8_t *Bytes1,
+ size_t Size1, const uint8_t *Address2,
+ const uint8_t *Bytes2, size_t Size2);
+DllIface DumpDiffBlocks_t DumpDiffBlocks;
+
+#endif // !defined(_COREDISTOOLS_H_)
#if USE_COREDISTOOLS_DISASSEMBLER
HMODULE Disassembler::s_libraryHandle = nullptr;
-
-Disassembler::CorDisasm *(*Disassembler::External_InitDisasm)(enum TargetArch Target) = nullptr;
-SIZE_T(*Disassembler::External_DisasmInstruction)(const Disassembler::CorDisasm *Disasm, size_t Address,
- const uint8_t *Bytes, size_t Maxlength,
- bool PrintAssembly) = nullptr;
-void(*Disassembler::External_FinishDisasm)(const Disassembler::CorDisasm *Disasm) = nullptr;
+InitDisasm_t *Disassembler::External_InitDisasm = nullptr;
+FinishDisasm_t *Disassembler::External_FinishDisasm = nullptr;
+DisasmInstruction_t *Disassembler::External_DisasmInstruction = nullptr;
#endif // USE_COREDISTOOLS_DISASSEMBLER
Disassembler::ExternalDisassembler *Disassembler::s_availableExternalDisassembler = nullptr;
_ASSERTE(IsAvailable());
#if USE_COREDISTOOLS_DISASSEMBLER
- SIZE_T instructionLength = External_DisasmInstruction(m_externalDisassembler, reinterpret_cast<SIZE_T>(code), code, codeLength, false /* PrintAssembly */);
+ SIZE_T instructionLength = External_DisasmInstruction(m_externalDisassembler, code, code, codeLength);
#elif USE_MSVC_DISASSEMBLER
SIZE_T instructionLength =
m_externalDisassembler->CbDisassemble(reinterpret_cast<ExternalDisassembler::ADDR>(code), code, codeLength);
#endif // defined(FEATURE_CORECLR) || defined(_TARGET_AMD64_) || defined(_TARGET_X86_)
#endif // HAVE_GCCOVER
+#if USE_COREDISTOOLS_DISASSEMBLER
+#include "coredistools.h"
+#endif
+
#if USE_COREDISTOOLS_DISASSEMBLER || USE_MSVC_DISASSEMBLER
#define USE_DISASSEMBLER 1
#else
{
#if USE_COREDISTOOLS_DISASSEMBLER
private:
- class CorDisasm;
typedef CorDisasm ExternalDisassembler;
#elif USE_MSVC_DISASSEMBLER
private:
#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);
+ static InitDisasm_t *External_InitDisasm;
+ static FinishDisasm_t *External_FinishDisasm;
+ static DisasmInstruction_t *External_DisasmInstruction;
#endif // USE_COREDISTOOLS_DISASSEMBLER
private: