summaryrefslogtreecommitdiff
path: root/src/ToolBox
diff options
context:
space:
mode:
authorBruce Forstall <brucefo@microsoft.com>2017-08-17 18:29:20 -0700
committerBruce Forstall <brucefo@microsoft.com>2017-08-17 18:40:11 -0700
commitc024d72af6e7110dab147b2ed3bd3808bacf9fe6 (patch)
tree48c7432d9d3ebb746ead2a87309513ceca36971b /src/ToolBox
parent23abbb6d2c4d6f9c370559a2666f81be0d0aa7ff (diff)
downloadcoreclr-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.
Diffstat (limited to 'src/ToolBox')
-rw-r--r--src/ToolBox/superpmi/superpmi/CMakeLists.txt5
-rw-r--r--src/ToolBox/superpmi/superpmi/commandline.cpp13
-rw-r--r--src/ToolBox/superpmi/superpmi/commandline.h6
-rw-r--r--src/ToolBox/superpmi/superpmi/neardiffer.cpp83
-rw-r--r--src/ToolBox/superpmi/superpmi/neardiffer.h7
-rw-r--r--src/ToolBox/superpmi/superpmi/superpmi.cpp5
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)