diff --git a/src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp index 1dcbbf1bca20e4..b27003b6930fb1 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/compileresult.cpp @@ -821,15 +821,15 @@ void CompileResult::applyRelocs(RelocContext* rc, unsigned char* block1, ULONG b case CorInfoReloc::ARM32_THUMB_BRANCH24: { - INT32 delta = (INT32)(tmp.target - fixupLocation); if ((section_begin <= address) && (address < section_end)) // A reloc for our section? { - if (!FitsInThumb2BlRel24(delta)) - { - DWORDLONG target = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1; - delta = (INT32)(target - fixupLocation); - } - PutThumb2BlRel24((UINT16*)address, delta); + // Like the arm64 ARM64_BRANCH26 and x64 RELATIVE32 handling, hardcode the + // bottom bits of the target into the instruction so the encoding does not + // depend on where SuperPMI allocated the code buffer. Otherwise a BL whose + // target is out of the +-16MB range for one of the two compared blocks would + // get a buffer-dependent placeholder, producing spurious asm diffs. + DWORDLONG target = tmp.target + (int32_t)tmp.addlDelta; + PutThumb2BlRel24((UINT16*)address, (INT32)(target & 0x00FFFFFE)); } wasRelocHandled = true; } diff --git a/src/coreclr/tools/superpmi/superpmi/jitinstance.h b/src/coreclr/tools/superpmi/superpmi/jitinstance.h index b264894d368499..cbc6e5f5043ad5 100644 --- a/src/coreclr/tools/superpmi/superpmi/jitinstance.h +++ b/src/coreclr/tools/superpmi/superpmi/jitinstance.h @@ -52,6 +52,10 @@ class JitInstance ULONGLONG times[2]; ICorJitCompiler* pJitInstance; + // The loaded JIT module handle. Used to detect when the baseline and diff + // JITs resolve to the same loaded module (which shares global state). + HMODULE getModule() const { return hLib; } + // Allocate and initialize the jit provided static JitInstance* InitJit(char* nameOfJit, bool breakOnAssert, diff --git a/src/coreclr/tools/superpmi/superpmi/superpmi.cpp b/src/coreclr/tools/superpmi/superpmi/superpmi.cpp index c509589330c9c9..b906f243703612 100644 --- a/src/coreclr/tools/superpmi/superpmi/superpmi.cpp +++ b/src/coreclr/tools/superpmi/superpmi/superpmi.cpp @@ -447,6 +447,18 @@ int __cdecl main(int argc, char* argv[]) // InitJit already printed a failure message return (int)SpmiResult::JitFailedToInit; } + + if (jit2->getModule() == jit->getModule()) + { + // The baseline and diff JITs resolved to the same loaded module. Because the JIT keeps + // global state (e.g. g_jitHost, JitConfig), sharing a single module between the two + // JitInstances corrupts that state and produces spurious diffs and intermittent crashes. + // Require the two JITs to be distinct files (copy one to a different path if needed). + LogError("The baseline JIT ('%s') and diff JIT ('%s') resolve to the same loaded module. " + "They must be distinct files; copy one JIT to a different path.", + o.nameOfJit, o.nameOfJit2); + return (int)SpmiResult::JitFailedToInit; + } } }