From c69bd28f8ca769a242db8e96c11f6fdadde356a2 Mon Sep 17 00:00:00 2001 From: Swaroop Sridhar Date: Tue, 22 Mar 2016 17:17:58 -0700 Subject: [PATCH] Add CoreDisTools header CoreCLR uses the CoreDisTools library for utilities like GCStress and SuperPMI. To aid these utilities, this change adds the CoreDisTools header to CoreCLR repository. This cleans up duplication of type/enum definitions in CoreDisTools and CoreCLR sources, and provides for a cleaner way to use the interface. The understanding here is that CoreCLR defines the required CoreDisTools interface, and will publish the header into the cmake-install directory. Any repository can pick up this header and supply implementations for the imported functions. [Currently the only implementation is the one that uses LLVM disassembler in the LLILC tree]. Two other changes: 1) Define TypeDefs for exported function types in cordistools.h to avoid duplicating the signature in importing code. 2) Move to the libcoredistools version 1.0.1, and use the new interface in disassembler.cpp --- src/inc/CMakeLists.txt | 1 + src/inc/coredistools.h | 142 +++++++++++++++++++++++++++++++++++ src/vm/disassembler.cpp | 11 +-- src/vm/disassembler.h | 25 ++---- tests/setup-runtime-dependencies.cmd | 2 +- tests/setup-runtime-dependencies.sh | 2 +- 6 files changed, 156 insertions(+), 27 deletions(-) create mode 100644 src/inc/coredistools.h diff --git a/src/inc/CMakeLists.txt b/src/inc/CMakeLists.txt index 9328773..87d7536 100644 --- a/src/inc/CMakeLists.txt +++ b/src/inc/CMakeLists.txt @@ -74,6 +74,7 @@ add_library(corguids ${CORGUIDS_SOURCES}) install (FILES cfi.h cor.h cordebuginfo.h + coredistools.h corhdr.h corinfo.h corjit.h diff --git a/src/inc/coredistools.h b/src/inc/coredistools.h new file mode 100644 index 0000000..92c9d9a --- /dev/null +++ b/src/inc/coredistools.h @@ -0,0 +1,142 @@ +// 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 + +#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_) diff --git a/src/vm/disassembler.cpp b/src/vm/disassembler.cpp index ea44c61..86a277a 100755 --- a/src/vm/disassembler.cpp +++ b/src/vm/disassembler.cpp @@ -13,12 +13,9 @@ #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; @@ -239,7 +236,7 @@ SIZE_T Disassembler::DisassembleInstruction(const UINT8 *code, SIZE_T codeLength _ASSERTE(IsAvailable()); #if USE_COREDISTOOLS_DISASSEMBLER - SIZE_T instructionLength = External_DisasmInstruction(m_externalDisassembler, reinterpret_cast(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(code), code, codeLength); diff --git a/src/vm/disassembler.h b/src/vm/disassembler.h index f0be83b..e3536ba 100644 --- a/src/vm/disassembler.h +++ b/src/vm/disassembler.h @@ -24,6 +24,10 @@ #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 @@ -61,7 +65,6 @@ class Disassembler { #if USE_COREDISTOOLS_DISASSEMBLER private: - class CorDisasm; typedef CorDisasm ExternalDisassembler; #elif USE_MSVC_DISASSEMBLER private: @@ -98,23 +101,9 @@ public: #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: diff --git a/tests/setup-runtime-dependencies.cmd b/tests/setup-runtime-dependencies.cmd index e1ec0f1..0913399 100755 --- a/tests/setup-runtime-dependencies.cmd +++ b/tests/setup-runtime-dependencies.cmd @@ -78,7 +78,7 @@ REM ============================================================================ REM Write dependency information to project.json echo { ^ "dependencies": { ^ - "runtime.win7-%__Arch%.Microsoft.NETCore.CoreDisTools": "1.0.0-prerelease-00001" ^ + "runtime.win7-%__Arch%.Microsoft.NETCore.CoreDisTools": "1.0.1-prerelease-00001" ^ }, ^ "frameworks": { "dnxcore50": { } } ^ } > "%__JasonFilePath%" diff --git a/tests/setup-runtime-dependencies.sh b/tests/setup-runtime-dependencies.sh index 457636c..3db178c 100755 --- a/tests/setup-runtime-dependencies.sh +++ b/tests/setup-runtime-dependencies.sh @@ -119,7 +119,7 @@ fi packageName='runtime.'$rid'.Microsoft.NETCore.CoreDisTools' echo { \ \"dependencies\": { \ - \"$packageName\": \"1.0.0-prerelease-00001\" \ + \"$packageName\": \"1.0.1-prerelease-00001\" \ }, \ \"frameworks\": { \"dnxcore50\": { } } \ } > $jsonFilePath -- 2.7.4