diff options
author | Bruce Forstall <brucefo@microsoft.com> | 2017-08-17 18:29:20 -0700 |
---|---|---|
committer | Bruce Forstall <brucefo@microsoft.com> | 2017-08-17 18:40:11 -0700 |
commit | c024d72af6e7110dab147b2ed3bd3808bacf9fe6 (patch) | |
tree | 48c7432d9d3ebb746ead2a87309513ceca36971b | |
parent | 23abbb6d2c4d6f9c370559a2666f81be0d0aa7ff (diff) | |
download | coreclr-c024d72af6e7110dab147b2ed3bd3808bacf9fe6.tar.gz coreclr-c024d72af6e7110dab147b2ed3bd3808bacf9fe6.tar.bz2 coreclr-c024d72af6e7110dab147b2ed3bd3808bacf9fe6.zip |
Enable SuperPMI asm diffs using CoreDisTools
Change SuperPMI to dynamically load coredistools.dll on demand.
-rw-r--r-- | src/ToolBox/superpmi/superpmi/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi/commandline.cpp | 13 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi/commandline.h | 6 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi/neardiffer.cpp | 83 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi/neardiffer.h | 7 | ||||
-rw-r--r-- | src/ToolBox/superpmi/superpmi/superpmi.cpp | 5 |
6 files changed, 92 insertions, 27 deletions
diff --git a/src/ToolBox/superpmi/superpmi/CMakeLists.txt b/src/ToolBox/superpmi/superpmi/CMakeLists.txt index eb3f08a3e5..5b9897e02b 100644 --- a/src/ToolBox/superpmi/superpmi/CMakeLists.txt +++ b/src/ToolBox/superpmi/superpmi/CMakeLists.txt @@ -5,6 +5,7 @@ remove_definitions(-D_UNICODE) add_definitions(-DFEATURE_NO_HOST) add_definitions(-DSELF_NO_HOST) +add_definitions(-DUSE_COREDISTOOLS) if(WIN32) #use static crt @@ -14,10 +15,6 @@ endif(WIN32) include_directories(.) include_directories(../superpmi-shared) -# When it is ready (the build works on all platforms, referencing the coredistools -# package), define this: -# add_definitions(-DUSE_COREDISTOOLS) - set(SUPERPMI_SOURCES commandline.cpp coreclrcallbacks.cpp diff --git a/src/ToolBox/superpmi/superpmi/commandline.cpp b/src/ToolBox/superpmi/superpmi/commandline.cpp index 8546afae7c..c77337f6be 100644 --- a/src/ToolBox/superpmi/superpmi/commandline.cpp +++ b/src/ToolBox/superpmi/superpmi/commandline.cpp @@ -108,11 +108,16 @@ void CommandLine::DumpHelp(const char* program) printf(" Used by the assembly differences calculator. This specifies the target\n"); printf(" architecture for cross-compilation. Currently allowed <target> value: arm64\n"); printf("\n"); -#ifdef USE_COREDISTOOLS printf(" -coredistools\n"); printf(" Use disassembly tools from the CoreDisTools library\n"); +#if defined(USE_MSVCDIS) + printf(" Default: use MSVCDIS.\n"); +#elif defined(USE_COREDISTOOLS) + printf(" Ignored: MSVCDIS is not available, so CoreDisTools will be used.\n"); +#else + printf(" Ignored: neither MSVCDIS nor CoreDisTools is available.\n"); +#endif printf("\n"); -#endif // USE_COREDISTOOLS printf("Inputs are case sensitive.\n"); printf("\n"); printf("SuperPMI method contexts are stored in files with extension .MC, implying\n"); @@ -353,12 +358,12 @@ bool CommandLine::Parse(int argc, char* argv[], /* OUT */ Options* o) o->compileList = argv[i]; // Save this in case we need it for -parallel. } -#ifdef USE_COREDISTOOLS else if ((_strnicmp(&argv[i][1], "coredistools", argLen) == 0)) { +#ifndef USE_COREDISTOOLS // If USE_COREDISTOOLS is not defined, then allow the switch, but ignore it. o->useCoreDisTools = true; - } #endif // USE_COREDISTOOLS + } else if ((_strnicmp(&argv[i][1], "matchHash", argLen) == 0)) { if (++i >= argc) diff --git a/src/ToolBox/superpmi/superpmi/commandline.h b/src/ToolBox/superpmi/superpmi/commandline.h index 9937c3c036..87034476d6 100644 --- a/src/ToolBox/superpmi/superpmi/commandline.h +++ b/src/ToolBox/superpmi/superpmi/commandline.h @@ -25,7 +25,11 @@ public: , breakOnAssert(false) , applyDiff(false) , parallel(false) - , useCoreDisTools(false) +#if !defined(USE_MSVCDIS) && defined(USE_COREDISTOOLS) + , useCoreDisTools(true) // if CoreDisTools is available (but MSVCDIS is not), use it. +#else + , useCoreDisTools(false) // Otherwise, use MSVCDIS if that is available (else no diffs are available). +#endif , skipCleanup(false) , workerCount(-1) , indexCount(-1) diff --git a/src/ToolBox/superpmi/superpmi/neardiffer.cpp b/src/ToolBox/superpmi/superpmi/neardiffer.cpp index d3ccae5ccc..d31a4066b6 100644 --- a/src/ToolBox/superpmi/superpmi/neardiffer.cpp +++ b/src/ToolBox/superpmi/superpmi/neardiffer.cpp @@ -29,38 +29,89 @@ static void LogFromCoreDisToolsHelper(LogLevel level, const char* msg, va_list a } #define LOGGER(L) \ - \ -static void Log##L(const char* msg, ...) \ - \ -{ \ - va_list argList; \ - va_start(argList, msg); \ - LogFromCoreDisToolsHelper(LOGLEVEL_##L, msg, argList); \ - va_end(argList); \ - \ +static void __cdecl CorDisToolsLog##L(const char* msg, ...) \ +{ \ + va_list argList; \ + va_start(argList, msg); \ + LogFromCoreDisToolsHelper(LOGLEVEL_##L, msg, argList); \ + va_end(argList); \ } LOGGER(VERBOSE) LOGGER(ERROR) LOGGER(WARNING) -const PrintControl CorPrinter = {LogERROR, LogWARNING, LogVERBOSE, LogVERBOSE}; +const PrintControl CorPrinter = {CorDisToolsLogERROR, CorDisToolsLogWARNING, CorDisToolsLogVERBOSE, CorDisToolsLogVERBOSE}; #endif // USE_COREDISTOOLS +#ifdef USE_COREDISTOOLS +NewDiffer_t* g_PtrNewDiffer = nullptr; +FinishDiff_t* g_PtrFinishDiff = nullptr; +NearDiffCodeBlocks_t* g_PtrNearDiffCodeBlocks = nullptr; +DumpDiffBlocks_t* g_PtrDumpDiffBlocks = nullptr; +#endif // USE_COREDISTOOLS + // -// The NearDiff Disassembler Initialization +// The NearDiff Disassembler initialization. +// +// Returns true on success, false on failure. // -void NearDiffer::InitAsmDiff() +bool NearDiffer::InitAsmDiff() { #ifdef USE_COREDISTOOLS + if (UseCoreDisTools) { - corAsmDiff = NewDiffer(Target_Host, &CorPrinter, NearDiffer::compareOffsets); + const char* coreDisToolsLibrary = MAKEDLLNAME_A("coredistools"); + + HMODULE hCoreDisToolsLib = ::LoadLibraryA(coreDisToolsLibrary); + if (hCoreDisToolsLib == 0) + { + LogError("LoadLibrary(%s) failed (0x%08x)", coreDisToolsLibrary, ::GetLastError()); + return false; + } + g_PtrNewDiffer = (NewDiffer_t*)::GetProcAddress(hCoreDisToolsLib, "NewDiffer"); + if (g_PtrNewDiffer == nullptr) + { + LogError("GetProcAddress 'NewDiffer' failed (0x%08x)", ::GetLastError()); + return false; + } + g_PtrFinishDiff = (FinishDiff_t*)::GetProcAddress(hCoreDisToolsLib, "FinishDiff"); + if (g_PtrFinishDiff == nullptr) + { + LogError("GetProcAddress 'FinishDiff' failed (0x%08x)", ::GetLastError()); + return false; + } + g_PtrNearDiffCodeBlocks = (NearDiffCodeBlocks_t*)::GetProcAddress(hCoreDisToolsLib, "NearDiffCodeBlocks"); + if (g_PtrNearDiffCodeBlocks == nullptr) + { + LogError("GetProcAddress 'NearDiffCodeBlocks' failed (0x%08x)", ::GetLastError()); + return false; + } + g_PtrDumpDiffBlocks = (DumpDiffBlocks_t*)::GetProcAddress(hCoreDisToolsLib, "DumpDiffBlocks"); + if (g_PtrDumpDiffBlocks == nullptr) + { + LogError("GetProcAddress 'DumpDiffBlocks' failed (0x%08x)", ::GetLastError()); + return false; + } + + corAsmDiff = (*g_PtrNewDiffer)(Target_Host, &CorPrinter, NearDiffer::CoreDisCompareOffsetsCallback); } #endif // USE_COREDISTOOLS + + return true; } +#ifdef USE_COREDISTOOLS +// static +bool __cdecl NearDiffer::CoreDisCompareOffsetsCallback( + const void* payload, size_t blockOffset, size_t instrLen, uint64_t offset1, uint64_t offset2) +{ + return compareOffsets(payload, blockOffset, instrLen, offset1, offset2); +} +#endif // USE_COREDISTOOLS + // // The NearDiff destructor // @@ -69,7 +120,7 @@ NearDiffer::~NearDiffer() #ifdef USE_COREDISTOOLS if (corAsmDiff != nullptr) { - FinishDiff(corAsmDiff); + (*g_PtrFinishDiff)(corAsmDiff); } #endif // USE_COREDISTOOLS } @@ -403,12 +454,12 @@ bool NearDiffer::compareCodeSection(MethodContext* mc, #ifdef USE_COREDISTOOLS if (UseCoreDisTools) { - bool areSame = NearDiffCodeBlocks(corAsmDiff, &data, (const uint8_t*)originalBlock1, block1, blocksize1, + bool areSame = (*g_PtrNearDiffCodeBlocks)(corAsmDiff, &data, (const uint8_t*)originalBlock1, block1, blocksize1, (const uint8_t*)originalBlock2, block2, blocksize2); if (!areSame) { - DumpDiffBlocks(corAsmDiff, (const uint8_t*)originalBlock1, block1, blocksize1, + (*g_PtrDumpDiffBlocks)(corAsmDiff, (const uint8_t*)originalBlock1, block1, blocksize1, (const uint8_t*)originalBlock2, block2, blocksize2); } diff --git a/src/ToolBox/superpmi/superpmi/neardiffer.h b/src/ToolBox/superpmi/superpmi/neardiffer.h index 100f87cce2..a2c7f8f648 100644 --- a/src/ToolBox/superpmi/superpmi/neardiffer.h +++ b/src/ToolBox/superpmi/superpmi/neardiffer.h @@ -26,7 +26,7 @@ public: ~NearDiffer(); - void InitAsmDiff(); + bool InitAsmDiff(); bool compare(MethodContext* mc, CompileResult* cr1, CompileResult* cr2); @@ -74,7 +74,12 @@ private: const void* payload, size_t blockOffset, size_t instrLen, uint64_t offset1, uint64_t offset2); #ifdef USE_COREDISTOOLS + + static bool __cdecl CoreDisCompareOffsetsCallback( + const void* payload, size_t blockOffset, size_t instrLen, uint64_t offset1, uint64_t offset2); + CorAsmDiff* corAsmDiff; + #endif // USE_COREDISTOOLS #ifdef USE_MSVCDIS diff --git a/src/ToolBox/superpmi/superpmi/superpmi.cpp b/src/ToolBox/superpmi/superpmi/superpmi.cpp index c1225e419e..58d77879e9 100644 --- a/src/ToolBox/superpmi/superpmi/superpmi.cpp +++ b/src/ToolBox/superpmi/superpmi/superpmi.cpp @@ -240,7 +240,10 @@ int __cdecl main(int argc, char* argv[]) if (o.applyDiff) { - nearDiffer.InitAsmDiff(); + if (!nearDiffer.InitAsmDiff()) + { + return -1; + } } while (true) |