From 35f7bf1e6816e7bb4b4bc5f4a1e7deeb5a1d1f5a Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Wed, 30 Sep 2020 16:57:46 -0700 Subject: [PATCH 01/28] Implement IMAGE_REL_ARM64_BRANCH26 in compileresult.cpp --- .../ToolBox/superpmi/superpmi-shared/compileresult.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index 4d2a13af9a43a2..8867f962006ca2 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -834,6 +834,15 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o #ifdef TARGET_ARM64 case IMAGE_REL_ARM64_BRANCH26: // 26 bit offset << 2 & sign ext, for B and BL + { + DWORDLONG fixupLocation = tmp.location; + DWORDLONG branchInstr = section_begin + fixupLocation - (DWORDLONG)originalAddr; + DWORDLONG endOfTheBlock = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1; + INT64 delta = (INT64)(endOfTheBlock - fixupLocation); + PutArm64Rel28((UINT32*)branchInstr, (INT32)delta); + } + break; + case IMAGE_REL_ARM64_PAGEBASE_REL21: case IMAGE_REL_ARM64_PAGEOFFSET_12A: LogError("Unimplemented reloc type %u", tmp.fRelocType); From 80be600473e9a48d82ea38ead7f9c4c50a13d3b3 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Tue, 23 Feb 2021 19:35:27 -0800 Subject: [PATCH 02/28] Introduce GetSpmiTargetArchitecture/SetSpmiTargetArchitecture helpers and move them to src/coreclr/ToolBox/superpmi/superpmi-shared --- .../superpmi/superpmi-shared/spmiutil.cpp | 22 ++++++++++++++++ .../superpmi/superpmi-shared/spmiutil.h | 11 ++++++++ .../ToolBox/superpmi/superpmi/jitinstance.cpp | 4 +-- .../ToolBox/superpmi/superpmi/superpmi.cpp | 25 ++++--------------- .../ToolBox/superpmi/superpmi/superpmi.h | 11 -------- 5 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp index 4cf2d77b298cfa..eaad65d26ba3b1 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp @@ -227,3 +227,25 @@ WCHAR* GetResultFileName(const WCHAR* folderPath, const WCHAR* fileName, const W return fullPath; } + +#ifdef TARGET_AMD64 +static SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_AMD64; +#elif defined(TARGET_X86) +static SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_X86; +#elif defined(TARGET_ARM) +static SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_ARM; +#elif defined(TARGET_ARM64) +static SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_ARM64; +#else +#error Unsupported architecture +#endif + +SPMI_TARGET_ARCHITECTURE GetSpmiTargetArchitecture() +{ + return SpmiTargetArchitecture; +} + +void SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE spmiTargetArchitecture) +{ + SpmiTargetArchitecture = spmiTargetArchitecture; +} diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h index df956696a409fc..882f9c77697dfa 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h @@ -45,4 +45,15 @@ inline DWORDLONG CastPointer(T* p) return (DWORDLONG)(uintptr_t)p; } +enum SPMI_TARGET_ARCHITECTURE +{ + SPMI_TARGET_ARCHITECTURE_X86, + SPMI_TARGET_ARCHITECTURE_AMD64, + SPMI_TARGET_ARCHITECTURE_ARM64, + SPMI_TARGET_ARCHITECTURE_ARM +}; + +SPMI_TARGET_ARCHITECTURE GetSpmiTargetArchitecture(); +void SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE spmiTargetArchitecture); + #endif // !_SPMIUtil diff --git a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp index dd04e5f211ac0e..abd4240a48b437 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp @@ -322,12 +322,12 @@ JitInstance::Result JitInstance::CompileMethod(MethodContext* MethodToCompile, i { // For altjit, treat SKIPPED as OK #ifdef TARGET_AMD64 - if (SpmiTargetArchitecture == SPMI_TARGET_ARCHITECTURE_ARM64) + if (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM64) { jitResult = CORJIT_OK; } #elif defined(TARGET_X86) - if (SpmiTargetArchitecture == SPMI_TARGET_ARCHITECTURE_ARM) + if (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM) { jitResult = CORJIT_OK; } diff --git a/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp index a2d9b2d210aa63..2b741a45f1eea3 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.cpp @@ -17,6 +17,7 @@ #include "methodcontextreader.h" #include "mclist.h" #include "methodstatsemitter.h" +#include "spmiutil.h" extern int doParallelSuperPMI(CommandLine::Options& o); @@ -29,43 +30,27 @@ const char* const g_AsmDiffsSummaryFormatString = "Loaded %d Jitted %d FailedC //#define SuperPMI_ChewMemory 0x7FFFFFFF //Amount of address space to consume on startup -SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture; - void SetSuperPmiTargetArchitecture(const char* targetArchitecture) { - // Set the default - -#ifdef TARGET_AMD64 - SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_AMD64; -#elif defined(TARGET_X86) - SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_X86; -#elif defined(TARGET_ARM) - SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_ARM; -#elif defined(TARGET_ARM64) - SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_ARM64; -#else -#error Unsupported architecture -#endif - // Allow overriding the default. if (targetArchitecture != nullptr) { if ((0 == _stricmp(targetArchitecture, "x64")) || (0 == _stricmp(targetArchitecture, "amd64"))) { - SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_AMD64; + SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE_AMD64); } else if (0 == _stricmp(targetArchitecture, "x86")) { - SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_X86; + SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE_X86); } else if ((0 == _stricmp(targetArchitecture, "arm")) || (0 == _stricmp(targetArchitecture, "arm32"))) { - SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_ARM; + SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE_ARM); } else if (0 == _stricmp(targetArchitecture, "arm64")) { - SpmiTargetArchitecture = SPMI_TARGET_ARCHITECTURE_ARM64; + SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE_ARM64); } else { diff --git a/src/coreclr/ToolBox/superpmi/superpmi/superpmi.h b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.h index 0f63a3b7136478..c56a74e16af82c 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/superpmi.h +++ b/src/coreclr/ToolBox/superpmi/superpmi/superpmi.h @@ -6,17 +6,6 @@ #include "errorhandling.h" -enum SPMI_TARGET_ARCHITECTURE -{ - SPMI_TARGET_ARCHITECTURE_X86, - SPMI_TARGET_ARCHITECTURE_AMD64, - SPMI_TARGET_ARCHITECTURE_ARM64, - SPMI_TARGET_ARCHITECTURE_ARM -}; - -extern SPMI_TARGET_ARCHITECTURE SpmiTargetArchitecture; -extern void SetSuperPmiTargetArchitecture(const char* targetArchitecture); - extern const char* const g_SuperPMIUsageFirstLine; extern const char* const g_AllFormatStringFixedPrefix; From bbd037fd18c35439f0e619a0e20506448f28b1b5 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Tue, 23 Feb 2021 19:46:52 -0800 Subject: [PATCH 03/28] Do platform specific relocations (IMAGE_REL_BASED_HIGHLOW) first in CompileResult::applyRelocs in src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp --- .../superpmi-shared/compileresult.cpp | 24 ++++++++++++++----- 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index 8867f962006ca2..f73962f7c8a184 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -742,10 +742,16 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o printf("\n"); } - switch (tmp.fRelocType) + const SPMI_TARGET_ARCHITECTURE targetArch = GetSpmiTargetArchitecture(); + + const DWORD relocType = tmp.fRelocType; + bool relocWasHandled = false; + + // Do platform specific relocations first. + + if (targetArch == SPMI_TARGET_ARCHITECTURE_X86) { -#if defined(TARGET_X86) - case IMAGE_REL_BASED_HIGHLOW: + if (relocType == IMAGE_REL_BASED_HIGHLOW) { DWORDLONG fixupLocation = tmp.location; @@ -753,13 +759,19 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o if ((section_begin <= address) && (address < section_end)) // A reloc for our section? { LogDebug(" fixupLoc-%016llX (@%p) : %08X => %08X", fixupLocation, address, *(DWORD*)address, - (DWORD)tmp.target); + (DWORD)tmp.target); *(DWORD*)address = (DWORD)tmp.target; } + + relocWasHandled = true; } - break; -#endif // TARGET_X86 + } + + if (relocWasHandled) + continue; + switch (tmp.fRelocType) + { #if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_ARM) case IMAGE_REL_BASED_REL32: { From f5ec6d293c7baf41605b19ecd99c06ed3b63a6a4 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Tue, 23 Feb 2021 19:51:56 -0800 Subject: [PATCH 04/28] Do Arm64 specific relocations first (IMAGE_REL_ARM64_*) in src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp --- .../superpmi-shared/compileresult.cpp | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index f73962f7c8a184..d694fbc823c3d6 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -767,6 +767,32 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o } } + if (targetArch == SPMI_TARGET_ARCHITECTURE_ARM64) + { + switch (relocType) + { + case IMAGE_REL_ARM64_BRANCH26: // 26 bit offset << 2 & sign ext, for B and BL + { + DWORDLONG fixupLocation = tmp.location; + DWORDLONG branchInstr = section_begin + fixupLocation - (DWORDLONG)originalAddr; + DWORDLONG endOfTheBlock = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1; + INT64 delta = (INT64)(endOfTheBlock - fixupLocation); + PutArm64Rel28((UINT32*)branchInstr, (INT32)delta); + relocWasHandled = true; + } + break; + + case IMAGE_REL_ARM64_PAGEBASE_REL21: + case IMAGE_REL_ARM64_PAGEOFFSET_12A: + LogError("Unimplemented reloc type %u", tmp.fRelocType); + relocWasHandled = true; + break; + + default: + break; + } + } + if (relocWasHandled) continue; @@ -844,23 +870,6 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o break; #endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) -#ifdef TARGET_ARM64 - case IMAGE_REL_ARM64_BRANCH26: // 26 bit offset << 2 & sign ext, for B and BL - { - DWORDLONG fixupLocation = tmp.location; - DWORDLONG branchInstr = section_begin + fixupLocation - (DWORDLONG)originalAddr; - DWORDLONG endOfTheBlock = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1; - INT64 delta = (INT64)(endOfTheBlock - fixupLocation); - PutArm64Rel28((UINT32*)branchInstr, (INT32)delta); - } - break; - - case IMAGE_REL_ARM64_PAGEBASE_REL21: - case IMAGE_REL_ARM64_PAGEOFFSET_12A: - LogError("Unimplemented reloc type %u", tmp.fRelocType); - break; -#endif // TARGET_ARM64 - default: LogError("Unknown reloc type %u", tmp.fRelocType); break; From 226acee209682079185d1ee449e1c9e62df1a520 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Tue, 23 Feb 2021 19:53:37 -0800 Subject: [PATCH 05/28] Rename 'relocWasHandled' -> 'wasRelocHandled' in src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp --- .../superpmi/superpmi-shared/compileresult.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index d694fbc823c3d6..e7acb50fc1d459 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -745,7 +745,7 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o const SPMI_TARGET_ARCHITECTURE targetArch = GetSpmiTargetArchitecture(); const DWORD relocType = tmp.fRelocType; - bool relocWasHandled = false; + bool wasRelocHandled = false; // Do platform specific relocations first. @@ -763,7 +763,7 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o *(DWORD*)address = (DWORD)tmp.target; } - relocWasHandled = true; + wasRelocHandled = true; } } @@ -778,14 +778,14 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o DWORDLONG endOfTheBlock = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1; INT64 delta = (INT64)(endOfTheBlock - fixupLocation); PutArm64Rel28((UINT32*)branchInstr, (INT32)delta); - relocWasHandled = true; + wasRelocHandled = true; } break; case IMAGE_REL_ARM64_PAGEBASE_REL21: case IMAGE_REL_ARM64_PAGEOFFSET_12A: LogError("Unimplemented reloc type %u", tmp.fRelocType); - relocWasHandled = true; + wasRelocHandled = true; break; default: @@ -793,7 +793,8 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o } } - if (relocWasHandled) + + if (wasRelocHandled) continue; switch (tmp.fRelocType) From a4cce851f09cfa235d47aadf9c80152d68e90348 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Tue, 23 Feb 2021 19:56:33 -0800 Subject: [PATCH 06/28] Do 64-bit target specific relocations first (IMAGE_REL_BASED_DIR64) in src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp --- .../superpmi-shared/compileresult.cpp | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index e7acb50fc1d459..d76396537ae6c2 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -793,6 +793,26 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o } } + const bool is64BitTarget = (targetArch == SPMI_TARGET_ARCHITECTURE_AMD64) || (targetArch == SPMI_TARGET_ARCHITECTURE_ARM64); + + if (is64BitTarget) + { + if (relocType == IMAGE_REL_BASED_DIR64) + { + DWORDLONG fixupLocation = tmp.location + tmp.slotNum; + + // Write 64-bits into location + size_t address = section_begin + (size_t)fixupLocation - (size_t)originalAddr; + if ((section_begin <= address) && (address < section_end)) // A reloc for our section? + { + LogDebug(" fixupLoc-%016llX (@%p) %016llX => %016llX", fixupLocation, address, + *(DWORDLONG*)address, tmp.target); + *(DWORDLONG*)address = tmp.target; + } + + wasRelocHandled = true; + } + } if (wasRelocHandled) continue; @@ -854,23 +874,6 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o break; #endif // defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_ARM) -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) - case IMAGE_REL_BASED_DIR64: - { - DWORDLONG fixupLocation = tmp.location + tmp.slotNum; - - // Write 64-bits into location - size_t address = section_begin + (size_t)fixupLocation - (size_t)originalAddr; - if ((section_begin <= address) && (address < section_end)) // A reloc for our section? - { - LogDebug(" fixupLoc-%016llX (@%p) %016llX => %016llX", fixupLocation, address, - *(DWORDLONG*)address, tmp.target); - *(DWORDLONG*)address = tmp.target; - } - } - break; -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) - default: LogError("Unknown reloc type %u", tmp.fRelocType); break; From bd38deb1b5f8a79286007d72ed7eb85136162095 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Tue, 23 Feb 2021 20:01:15 -0800 Subject: [PATCH 07/28] Remove remaning 'if defined(TARGET_*)' in src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp --- .../superpmi-shared/compileresult.cpp | 64 ++++++++++--------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index d76396537ae6c2..538afeaa806d6b 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -819,7 +819,6 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o switch (tmp.fRelocType) { -#if defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_ARM) case IMAGE_REL_BASED_REL32: { DWORDLONG target = tmp.target + tmp.addlDelta; @@ -827,52 +826,57 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o DWORDLONG baseAddr = fixupLocation + sizeof(INT32); INT64 delta = (INT64)((BYTE*)target - baseAddr); -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) - if (delta != (INT64)(int)delta) + if (is64BitTarget) { - // This isn't going to fit in a signed 32-bit address. Use something that will fit, - // since we assume that original compilation fit fine. This is only an issue for - // 32-bit offsets on 64-bit targets. - target = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1; - INT64 newdelta = (INT64)((BYTE*)target - baseAddr); - - LogDebug(" REL32 overflow. Mapping target to %016llX. Mapping delta: %016llX => %016llX", target, - delta, newdelta); - - delta = newdelta; + if (delta != (INT64)(int)delta) + { + // This isn't going to fit in a signed 32-bit address. Use something that will fit, + // since we assume that original compilation fit fine. This is only an issue for + // 32-bit offsets on 64-bit targets. + target = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1; + INT64 newdelta = (INT64)((BYTE*)target - baseAddr); + + LogDebug(" REL32 overflow. Mapping target to %016llX. Mapping delta: %016llX => %016llX", target, + delta, newdelta); + + delta = newdelta; + } } -#endif // defined(TARGET_AMD64) || defined(TARGET_ARM64) if (delta != (INT64)(int)delta) { -#if defined(TARGET_AMD64) || defined(TARGET_ARM64) - LogError("REL32 relocation overflows field! delta=0x%016llX", delta); -#else - LogError("REL32 relocation overflows field! delta=0x%08X", delta); -#endif + if (is64BitTarget) + { + LogError("REL32 relocation overflows field! delta=0x%016llX", delta); + } + else + { + LogError("REL32 relocation overflows field! delta=0x%08X", delta); + } } // Write 32-bits into location size_t address = section_begin + (size_t)fixupLocation - (size_t)originalAddr; if ((section_begin <= address) && (address < section_end)) // A reloc for our section? { -#if defined(TARGET_AMD64) - // During an actual compile, recordRelocation() will be called before the compile - // is actually finished, and it will write the relative offset into the fixupLocation. - // Then, emitEndCodeGen() will patch forward jumps by subtracting any adjustment due - // to overestimation of instruction sizes. Because we're applying the relocs after the - // compile has finished, we need to reverse that: i.e. add in the (negative) adjustment - // that's now in the fixupLocation. - INT32 adjustment = *(INT32*)address; - delta += adjustment; -#endif + if (targetArch == SPMI_TARGET_ARCHITECTURE_AMD64) + { + // During an actual compile, recordRelocation() will be called before the compile + // is actually finished, and it will write the relative offset into the fixupLocation. + // Then, emitEndCodeGen() will patch forward jumps by subtracting any adjustment due + // to overestimation of instruction sizes. Because we're applying the relocs after the + // compile has finished, we need to reverse that: i.e. add in the (negative) adjustment + // that's now in the fixupLocation. + INT32 adjustment = *(INT32*)address; + delta += adjustment; + } + LogDebug(" fixupLoc-%016llX (@%p) : %08X => %08X", fixupLocation, address, *(DWORD*)address, delta); *(DWORD*)address = (DWORD)delta; } } break; -#endif // defined(TARGET_X86) || defined(TARGET_AMD64) || defined(TARGET_ARM64) || defined(TARGET_ARM) default: LogError("Unknown reloc type %u", tmp.fRelocType); From 1e31f4443bdb454ccae8b949d0f38f24a28aefd8 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Tue, 23 Feb 2021 10:40:39 -0800 Subject: [PATCH 08/28] Call repCompileMethod() on Arm64 to adjust hotCodeSize in src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp --- .../ToolBox/superpmi/superpmi/neardiffer.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp b/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp index 4b8757cc5ae9e6..0f5c6e0d83b0da 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp @@ -13,6 +13,7 @@ #include "logging.h" #include "neardiffer.h" +#include "spmiutil.h" #ifdef USE_COREDISTOOLS @@ -1103,6 +1104,23 @@ bool NearDiffer::compare(MethodContext* mc, CompileResult* cr1, CompileResult* c &coldCodeBlock_2, &roDataBlock_2, &orig_hotCodeBlock_2, &orig_coldCodeBlock_2, &orig_roDataBlock_2); + if (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM64) + { + BYTE* nativeEntry_1; + ULONG nativeSizeOfCode_1; + CorJitResult jitResult_1; + + BYTE* nativeEntry_2; + ULONG nativeSizeOfCode_2; + CorJitResult jitResult_2; + + cr1->repCompileMethod(&nativeEntry_1, &nativeSizeOfCode_1, &jitResult_1); + cr2->repCompileMethod(&nativeEntry_2, &nativeSizeOfCode_2, &jitResult_2); + + hotCodeSize_1 = nativeSizeOfCode_1; + hotCodeSize_2 = nativeSizeOfCode_2; + } + LogDebug("HCS1 %d CCS1 %d RDS1 %d xcpnt1 %d flag1 %08X, HCB %p CCB %p RDB %p ohcb %p occb %p odb %p", hotCodeSize_1, coldCodeSize_1, roDataSize_1, xcptnsCount_1, flag_1, hotCodeBlock_1, coldCodeBlock_1, roDataBlock_1, orig_hotCodeBlock_1, orig_coldCodeBlock_1, orig_roDataBlock_1); From 72c97ba8b697cd870208020400aada21ab15bee5 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Tue, 23 Feb 2021 20:44:50 -0800 Subject: [PATCH 09/28] Add PutArm64Rel28 helper in src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h --- src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp | 8 ++++++++ src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp index eaad65d26ba3b1..611e8151c9afac 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp @@ -249,3 +249,11 @@ void SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE spmiTargetArchitecture) { SpmiTargetArchitecture = spmiTargetArchitecture; } + +void PutArm64Rel28(UINT32* pCode, INT32 imm28) +{ + UINT32 branchInstr = *pCode; + branchInstr &= 0xFC000000; + branchInstr |= ((imm28 >> 2) & 0x03FFFFFF); + *pCode = branchInstr; +} diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h index 882f9c77697dfa..7e039261bf8822 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h @@ -56,4 +56,6 @@ enum SPMI_TARGET_ARCHITECTURE SPMI_TARGET_ARCHITECTURE GetSpmiTargetArchitecture(); void SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE spmiTargetArchitecture); +void PutArm64Rel28(UINT32* pCode, INT32 imm28); + #endif // !_SPMIUtil From 48aff18cf98faa6ad013e4d0827277d07086721d Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Wed, 24 Feb 2021 16:16:25 -0800 Subject: [PATCH 10/28] Add PutArm64Rel21 and PutArm64Rel12 helpers in src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h --- .../superpmi/superpmi-shared/spmiutil.cpp | 18 ++++++++++++++++++ .../superpmi/superpmi-shared/spmiutil.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp index 611e8151c9afac..501f0f22533d78 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp @@ -257,3 +257,21 @@ void PutArm64Rel28(UINT32* pCode, INT32 imm28) branchInstr |= ((imm28 >> 2) & 0x03FFFFFF); *pCode = branchInstr; } + +void PutArm64Rel21(UINT32* pCode, INT32 imm21) +{ + UINT32 adrpInstr = *pCode; + adrpInstr &= 0x9F00001F; + INT32 immlo = imm21 & 0x03; + INT32 immhi = (imm21 & 0x1FFFFC) >> 2; + adrpInstr |= ((immlo << 29) | (immhi << 5)); + *pCode = adrpInstr; +} + +void PutArm64Rel12(UINT32* pCode, INT32 imm12) +{ + UINT32 addInstr = *pCode; + addInstr &= 0xFFC003FF; + addInstr |= (imm12 << 10); + *pCode = addInstr; +} diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h index 7e039261bf8822..668d2cdf4d5c10 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h @@ -57,5 +57,7 @@ SPMI_TARGET_ARCHITECTURE GetSpmiTargetArchitecture(); void SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE spmiTargetArchitecture); void PutArm64Rel28(UINT32* pCode, INT32 imm28); +void PutArm64Rel21(UINT32* pCode, INT32 imm21); +void PutArm64Rel12(UINT32* pCode, INT32 imm12); #endif // !_SPMIUtil From ae3fa9d510446d426009d225bc2d9e784ac53130 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Wed, 24 Feb 2021 16:17:44 -0800 Subject: [PATCH 11/28] Re-implement IMAGE_REL_ARM64_BRANCH26 and implement IMAGE_REL_ARM64_PAGEBASE_REL21 and IMAGE_REL_ARM64_PAGEOFFSET_12A in compileresult.cpp --- .../superpmi-shared/compileresult.cpp | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index 538afeaa806d6b..ee282b04b16806 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -762,31 +762,59 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o (DWORD)tmp.target); *(DWORD*)address = (DWORD)tmp.target; } - wasRelocHandled = true; } } if (targetArch == SPMI_TARGET_ARCHITECTURE_ARM64) { + DWORDLONG fixupLocation = tmp.location; + DWORDLONG address = section_begin + (size_t)fixupLocation - (size_t)originalAddr; + switch (relocType) { case IMAGE_REL_ARM64_BRANCH26: // 26 bit offset << 2 & sign ext, for B and BL { - DWORDLONG fixupLocation = tmp.location; - DWORDLONG branchInstr = section_begin + fixupLocation - (DWORDLONG)originalAddr; - DWORDLONG endOfTheBlock = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1; - INT64 delta = (INT64)(endOfTheBlock - fixupLocation); - PutArm64Rel28((UINT32*)branchInstr, (INT32)delta); + if ((section_begin <= address) && (address < section_end)) // A reloc for our section? + { + INT64 delta = (INT64)(tmp.target - fixupLocation); + if (!FitsInRel28(delta)) + { + // Assume here that we would need a jump stub for this relocation and pretend + // that the jump stub is located right at the end of the method. + DWORDLONG target = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1; + delta = (INT64)(target - fixupLocation); + } + PutArm64Rel28((UINT32*)address, (INT32)delta); + } wasRelocHandled = true; } break; - case IMAGE_REL_ARM64_PAGEBASE_REL21: - case IMAGE_REL_ARM64_PAGEOFFSET_12A: - LogError("Unimplemented reloc type %u", tmp.fRelocType); + case IMAGE_REL_ARM64_PAGEBASE_REL21: // ADRP 21 bit PC-relative page address + { + if ((section_begin <= address) && (address < section_end)) // A reloc for our section? + { + INT64 targetPage = (INT64)tmp.target & 0xFFFFFFFFFFFFF000LL; + INT64 fixupLocationPage = (INT64)fixupLocation & 0xFFFFFFFFFFFFF000LL; + INT64 pageDelta = (INT64)(targetPage - targetPage); + INT32 imm21 = (INT32)(pageDelta >> 12) & 0x1FFFFF; + PutArm64Rel21((UINT32*)address, imm21); + } wasRelocHandled = true; - break; + } + break; + + case IMAGE_REL_ARM64_PAGEOFFSET_12A: // ADD 12 bit page offset + { + if ((section_begin <= address) && (address < section_end)) // A reloc for our section? + { + INT32 imm12 = (INT32)(SIZE_T)tmp.target & 0xFFFLL; + PutArm64Rel12((UINT32*)address, imm12); + } + wasRelocHandled = true; + } + break; default: break; From a0b8cb4a8a7f7d15008461f9a8a5682d7c750d8d Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Wed, 24 Feb 2021 20:43:14 -0800 Subject: [PATCH 12/28] Add PutThumb2Mov32 and PutThumb2BlRel24 helpers in src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h --- .../superpmi/superpmi-shared/spmiutil.cpp | 38 +++++++++++++++++++ .../superpmi/superpmi-shared/spmiutil.h | 3 ++ 2 files changed, 41 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp index 501f0f22533d78..c0ed92f9de1281 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp @@ -275,3 +275,41 @@ void PutArm64Rel12(UINT32* pCode, INT32 imm12) addInstr |= (imm12 << 10); *pCode = addInstr; } + +void PutThumb2Imm16(UINT16* p, UINT16 imm16) +{ + USHORT Opcode0 = p[0]; + USHORT Opcode1 = p[1]; + Opcode0 &= ~((0xf000 >> 12) | (0x0800 >> 1)); + Opcode1 &= ~((0x0700 << 4) | (0x00ff << 0)); + Opcode0 |= (imm16 & 0xf000) >> 12; + Opcode0 |= (imm16 & 0x0800) >> 1; + Opcode1 |= (imm16 & 0x0700) << 4; + Opcode1 |= (imm16 & 0x00ff) << 0; + p[0] = Opcode0; + p[1] = Opcode1; +} + +void PutThumb2Mov32(UINT16* p, UINT32 imm32) +{ + PutThumb2Imm16(p, (UINT16)imm32); + PutThumb2Imm16(p + 2, (UINT16)(imm32 >> 16)); +} + +void PutThumb2BlRel24(UINT16* p, INT32 imm24) +{ + USHORT Opcode0 = p[0]; + USHORT Opcode1 = p[1]; + Opcode0 &= 0xF800; + Opcode1 &= 0xD000; + + UINT32 S = (imm24 & 0x1000000) >> 24; + UINT32 J1 = ((imm24 & 0x0800000) >> 23) ^ S ^ 1; + UINT32 J2 = ((imm24 & 0x0400000) >> 22) ^ S ^ 1; + + Opcode0 |= ((imm24 & 0x03FF000) >> 12) | (S << 10); + Opcode1 |= ((imm24 & 0x0000FFE) >> 1) | (J1 << 13) | (J2 << 11); + + p[0] = Opcode0; + p[1] = Opcode1; +} diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h index 668d2cdf4d5c10..28b19d4464a097 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h @@ -60,4 +60,7 @@ void PutArm64Rel28(UINT32* pCode, INT32 imm28); void PutArm64Rel21(UINT32* pCode, INT32 imm21); void PutArm64Rel12(UINT32* pCode, INT32 imm12); +void PutThumb2Mov32(UINT16* p, UINT32 imm32); +void PutThumb2BlRel24(UINT16* p, INT32 imm24); + #endif // !_SPMIUtil From 0a763b40c26d7b9c2d942c57244a9dc17bf1f62b Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Wed, 24 Feb 2021 20:44:45 -0800 Subject: [PATCH 13/28] Enable IMAGE_REL_BASED_HIGHLOW on Arm in compileresult.cpp --- src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index ee282b04b16806..b608b6cb7e0d31 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -749,7 +749,7 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o // Do platform specific relocations first. - if (targetArch == SPMI_TARGET_ARCHITECTURE_X86) + if ((targetArch == SPMI_TARGET_ARCHITECTURE_X86) || (targetArch == SPMI_TARGET_ARCHITECTURE_ARM)) { if (relocType == IMAGE_REL_BASED_HIGHLOW) { From 30023dd8cb63343b5a5636f0ece24bbe1d616e35 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Wed, 24 Feb 2021 20:45:21 -0800 Subject: [PATCH 14/28] Implement IMAGE_REL_BASED_THUMB_MOV32 IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL IMAGE_REL_BASED_THUMB_BRANCH24 on Arm in compileresult.cpp --- .../superpmi-shared/compileresult.cpp | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index b608b6cb7e0d31..6cd5d7a1354c45 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -766,6 +766,46 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o } } + if (targetArch == SPMI_TARGET_ARCHITECTURE_ARM) + { + DWORDLONG fixupLocation = tmp.location; + DWORDLONG address = section_begin + (size_t)fixupLocation - (size_t)originalAddr; + + switch (relocType) + { + case IMAGE_REL_BASED_THUMB_MOV32: + case IMAGE_REL_BASED_REL_THUMB_MOV32_PCREL: + { + INT32 delta = (INT32)(tmp.target - fixupLocation); + if ((section_begin <= address) && (address < section_end)) // A reloc for our section? + { + PutThumb2Mov32((UINT16*)address, (UINT32)delta); + } + wasRelocHandled = true; + } + break; + + case IMAGE_REL_BASED_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); + } + wasRelocHandled = true; + } + break; + + default: + break; + } + } + if (targetArch == SPMI_TARGET_ARCHITECTURE_ARM64) { DWORDLONG fixupLocation = tmp.location; From 6fe2d4656ec5b22db1bcf400e1ca790349178113 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 17:59:45 -0800 Subject: [PATCH 15/28] Add comment about functions copied from utilcode in spmiutil.cpp --- src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp index c0ed92f9de1281..0d52ae35ed1ab1 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.cpp @@ -250,6 +250,11 @@ void SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE spmiTargetArchitecture) SpmiTargetArchitecture = spmiTargetArchitecture; } +// The following functions are used for arm64/arm32 relocation processing. +// They are copies of the code in src\coreclr\utilcode\util.cpp. +// We decided to copy them instead of linking with utilcode library +// to avoid introducing additional runtime dependencies. + void PutArm64Rel28(UINT32* pCode, INT32 imm28) { UINT32 branchInstr = *pCode; From df78f9c44879e5d11008b4105d90f64def731920 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 18:26:38 -0800 Subject: [PATCH 16/28] Generalize checks for altjits in jitinstance.cpp --- .../ToolBox/superpmi/superpmi/jitinstance.cpp | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp index abd4240a48b437..c1264b6c6cf492 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/jitinstance.cpp @@ -320,18 +320,40 @@ JitInstance::Result JitInstance::CompileMethod(MethodContext* MethodToCompile, i } if (jitResult == CORJIT_SKIPPED) { - // For altjit, treat SKIPPED as OK -#ifdef TARGET_AMD64 - if (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM64) + SPMI_TARGET_ARCHITECTURE targetArch = GetSpmiTargetArchitecture(); + bool matchesTargetArch = false; + + switch (pParam->pThis->mc->repGetExpectedTargetArchitecture()) { - jitResult = CORJIT_OK; + case IMAGE_FILE_MACHINE_AMD64: + matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_AMD64); + break; + + case IMAGE_FILE_MACHINE_I386: + matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_X86); + break; + + case IMAGE_FILE_MACHINE_ARMNT: + matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_ARM); + break; + + case IMAGE_FILE_MACHINE_ARM64: + matchesTargetArch = (targetArch == SPMI_TARGET_ARCHITECTURE_ARM64); + break; + + default: + LogError("Unknown target architecture"); + break; } -#elif defined(TARGET_X86) - if (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM) + + // If the target architecture doesn't match the expected target architecture + // then we have an altjit, so treat SKIPPED as OK to avoid counting the compilation as failed. + + if (!matchesTargetArch) { jitResult = CORJIT_OK; } -#endif + } if (jitResult == CORJIT_OK) { From b9c6214f8cf74774fea8171f28b7a0fb7bbd4a6f Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 19:39:56 -0800 Subject: [PATCH 17/28] Add comment and add logic for figuring out roDataBlock/roDataSize on Arm64 in neardiffer.cpp --- src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp b/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp index 0f5c6e0d83b0da..90659e902edf4b 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp @@ -1104,6 +1104,8 @@ bool NearDiffer::compare(MethodContext* mc, CompileResult* cr1, CompileResult* c &coldCodeBlock_2, &roDataBlock_2, &orig_hotCodeBlock_2, &orig_coldCodeBlock_2, &orig_roDataBlock_2); + // On Arm64 the constant pool is appended at the end of the method code section, hence hotCodeSize_{1,2} + // is a sum of their sizes. The following is to adjust theor sizes and the roDataBlock_{1,2} pointers. if (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM64) { BYTE* nativeEntry_1; @@ -1117,6 +1119,15 @@ bool NearDiffer::compare(MethodContext* mc, CompileResult* cr1, CompileResult* c cr1->repCompileMethod(&nativeEntry_1, &nativeSizeOfCode_1, &jitResult_1); cr2->repCompileMethod(&nativeEntry_2, &nativeSizeOfCode_2, &jitResult_2); + roDataSize_1 = hotCodeSize_1 - nativeSizeOfCode_1; + roDataSize_2 = hotCodeSize_2 - nativeSizeOfCode_2; + + roDataBlock_1 = hotCodeBlock_1 + nativeSizeOfCode_1; + roDataBlock_2 = hotCodeBlock_2 + nativeSizeOfCode_2; + + orig_roDataBlock_1 = (void*)((size_t)orig_hotCodeBlock_1 + nativeSizeOfCode_1); + orig_roDataBlock_2 = (void*)((size_t)orig_hotCodeBlock_2 + nativeSizeOfCode_2); + hotCodeSize_1 = nativeSizeOfCode_1; hotCodeSize_2 = nativeSizeOfCode_2; } From b88159d9f2c4b47d31ca81f0e9a8d31850221c0a Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 19:42:18 -0800 Subject: [PATCH 18/28] Remove redundant cast in compileresult.cpp --- src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index 6cd5d7a1354c45..d08dfa9ba6a109 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -902,7 +902,7 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o // since we assume that original compilation fit fine. This is only an issue for // 32-bit offsets on 64-bit targets. target = (DWORDLONG)originalAddr + (DWORDLONG)blocksize1; - INT64 newdelta = (INT64)((BYTE*)target - baseAddr); + INT64 newdelta = (INT64)(target - baseAddr); LogDebug(" REL32 overflow. Mapping target to %016llX. Mapping delta: %016llX => %016llX", target, delta, newdelta); From 13d16eae0c9230a4e3cda7fe7e1c9548fdf7b5bc Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 19:44:52 -0800 Subject: [PATCH 19/28] Use one error message for both 32-bit and 64-bit targets in compileresult.cpp --- .../ToolBox/superpmi/superpmi-shared/compileresult.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index d08dfa9ba6a109..6f11cb051dae4f 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -913,14 +913,7 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o if (delta != (INT64)(int)delta) { - if (is64BitTarget) - { - LogError("REL32 relocation overflows field! delta=0x%016llX", delta); - } - else - { - LogError("REL32 relocation overflows field! delta=0x%08X", delta); - } + LogError("REL32 relocation overflows field! delta=0x%016llX", delta); } // Write 32-bits into location From 227d6f6dddceed990c728d822386a3669cbb274c Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 19:46:12 -0800 Subject: [PATCH 20/28] Add comment before all platform relocations in src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp --- src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index 6f11cb051dae4f..419fe0769cb019 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -885,6 +885,8 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o if (wasRelocHandled) continue; + // Now do all-platform relocations. + switch (tmp.fRelocType) { case IMAGE_REL_BASED_REL32: From ac3ce2ef4cb80b69a504ec8d4e952fd9043efce6 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 19:48:54 -0800 Subject: [PATCH 21/28] Remove another redundant cast in compileresult.cpp --- src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index 419fe0769cb019..e4d85d438e4303 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -894,7 +894,7 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o DWORDLONG target = tmp.target + tmp.addlDelta; DWORDLONG fixupLocation = tmp.location + tmp.slotNum; DWORDLONG baseAddr = fixupLocation + sizeof(INT32); - INT64 delta = (INT64)((BYTE*)target - baseAddr); + INT64 delta = (INT64)(target - baseAddr); if (is64BitTarget) { From 365b24ac51b513796de2047021bcb41cc946f4bb Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 19:56:00 -0800 Subject: [PATCH 22/28] Remove unused CallUtils::HasRetBuffArg in callutils.cpp callutils.h --- .../superpmi/superpmi-shared/callutils.cpp | 19 ------------------- .../superpmi/superpmi-shared/callutils.h | 1 - 2 files changed, 20 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp index d83763ce822cce..75bbf2a55c76ec 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.cpp @@ -215,25 +215,6 @@ CallType CallUtils::GetDirectCallSiteInfo(MethodContext* mc, // SuperPMI's method context replaying instead of directly making calls into the JIT/EE interface. //------------------------------------------------------------------------------------------------- -// Stolen from Compiler::impMethodInfo_hasRetBuffArg (in the importer) -bool CallUtils::HasRetBuffArg(MethodContext* mc, CORINFO_SIG_INFO args) -{ - if (args.retType != CORINFO_TYPE_VALUECLASS && args.retType != CORINFO_TYPE_REFANY) - { - return false; - } - -#if defined(TARGET_AMD64) - // We don't need a return buffer if: - // i) TYP_STRUCT argument that can fit into a single register and - // ii) Power of two sized TYP_STRUCT on AMD64. - unsigned size = mc->repGetClassSize(args.retTypeClass); - return (size > sizeof(void*)) || ((size & (size - 1)) != 0); -#else - return true; -#endif -} - // Originally from src/jit/ee_il_dll.cpp const char* CallUtils::GetMethodName(MethodContext* mc, CORINFO_METHOD_HANDLE method, const char** classNamePtr) { diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.h index 7e37f3bd2655c7..b0b04cb59bb4d7 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/callutils.h @@ -28,7 +28,6 @@ class CallUtils void* callTarget, /*out*/ CORINFO_SIG_INFO* outSigInfo, /*out*/ char** outCallTargetSymbol); - static bool HasRetBuffArg(MethodContext* mc, CORINFO_SIG_INFO args); static CorInfoHelpFunc GetHelperNum(CORINFO_METHOD_HANDLE method); static bool IsNativeMethod(CORINFO_METHOD_HANDLE method); static CORINFO_METHOD_HANDLE GetMethodHandleForNative(CORINFO_METHOD_HANDLE method); From f805314ab83c4b740bfe533b69bc89d4dd1f8ce5 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 20:09:04 -0800 Subject: [PATCH 23/28] Add IsSpmiTarget64Bit() and SpmiTargetPointerSize() helpers in spmiutil.h --- .../ToolBox/superpmi/superpmi-shared/spmiutil.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h index 28b19d4464a097..89bdcf19536190 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/spmiutil.h @@ -56,6 +56,16 @@ enum SPMI_TARGET_ARCHITECTURE SPMI_TARGET_ARCHITECTURE GetSpmiTargetArchitecture(); void SetSpmiTargetArchitecture(SPMI_TARGET_ARCHITECTURE spmiTargetArchitecture); +inline bool IsSpmiTarget64Bit() +{ + return (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_AMD64) || (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM64); +} + +inline size_t SpmiTargetPointerSize() +{ + return IsSpmiTarget64Bit() ? sizeof(INT64) : sizeof(INT32); +} + void PutArm64Rel28(UINT32* pCode, INT32 imm28); void PutArm64Rel21(UINT32* pCode, INT32 imm21); void PutArm64Rel12(UINT32* pCode, INT32 imm12); From b4e70daf7a78cf5136857366d59902deee1a6c6c Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 20:10:36 -0800 Subject: [PATCH 24/28] Update TypeUtils in typeutils.cpp --- .../superpmi/superpmi-shared/typeutils.cpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/typeutils.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/typeutils.cpp index a0e3b62b35a19a..4e55a221af2671 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/typeutils.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/typeutils.cpp @@ -8,6 +8,7 @@ #include "standardpch.h" #include "typeutils.h" #include "errorhandling.h" +#include "spmiutil.h" // Returns a string representation of the given CorInfoType. The naming scheme is based on JITtype2varType // in src/jit/ee_il_dll.hpp. @@ -68,12 +69,8 @@ const char* TypeUtils::GetCorInfoTypeName(CorInfoType type) case CORINFO_TYPE_NATIVEINT: case CORINFO_TYPE_NATIVEUINT: -// Emulates the JIT's concept of TYP_I_IMPL -#if defined(TARGET_AMD64) // TODO: should be TARGET_64BIT - return "long"; -#else - return "int"; -#endif + // Emulates the JIT's concept of TYP_I_IMPL + return IsSpmiTarget64Bit() ? "long" : "int"; case CORINFO_TYPE_PTR: // The JIT just treats this as a TYP_I_IMPL because this isn't a GC root, @@ -106,13 +103,16 @@ bool TypeUtils::IsValueClass(CorInfoType type) // by reference (i.e. it cannot be stuffed as-is into a register or stack slot). bool TypeUtils::ValueClassRequiresByref(MethodContext* mc, CORINFO_CLASS_HANDLE clsHnd) { -#if defined(TARGET_AMD64) - size_t size = mc->repGetClassSize(clsHnd); - return ((size > sizeof(void*)) || ((size & (size - 1)) != 0)); -#else - LogException(EXCEPTIONCODE_TYPEUTILS, "unsupported architecture", ""); - return false; -#endif + if (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_AMD64) + { + size_t size = mc->repGetClassSize(clsHnd); + return ((size > SpmiTargetPointerSize()) || ((size & (size - 1)) != 0)); + } + else + { + LogException(EXCEPTIONCODE_TYPEUTILS, "unsupported architecture", ""); + return false; + } } // Returns the size of the given CorInfoType. If there is no applicable size (e.g. CORINFO_TYPE_VOID, @@ -148,7 +148,7 @@ size_t TypeUtils::SizeOfCorInfoType(CorInfoType type) case CORINFO_TYPE_PTR: case CORINFO_TYPE_BYREF: case CORINFO_TYPE_CLASS: - return sizeof(void*); + return SpmiTargetPointerSize(); // This should be obtained via repGetClassSize case CORINFO_TYPE_VALUECLASS: From 74681c6da9cdef7b7a35705cd787ff150ac8e397 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 20:12:03 -0800 Subject: [PATCH 25/28] Use IsSpmiTarget64Bit() in compileresult.cpp --- .../ToolBox/superpmi/superpmi-shared/compileresult.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp index e4d85d438e4303..94ac3a50a36923 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/compileresult.cpp @@ -861,9 +861,7 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o } } - const bool is64BitTarget = (targetArch == SPMI_TARGET_ARCHITECTURE_AMD64) || (targetArch == SPMI_TARGET_ARCHITECTURE_ARM64); - - if (is64BitTarget) + if (IsSpmiTarget64Bit()) { if (relocType == IMAGE_REL_BASED_DIR64) { @@ -896,7 +894,7 @@ void CompileResult::applyRelocs(unsigned char* block1, ULONG blocksize1, void* o DWORDLONG baseAddr = fixupLocation + sizeof(INT32); INT64 delta = (INT64)(target - baseAddr); - if (is64BitTarget) + if (IsSpmiTarget64Bit()) { if (delta != (INT64)(int)delta) { From 3ad3238dee337e810e2832e850597b1ecbb576e4 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Thu, 25 Feb 2021 20:16:47 -0800 Subject: [PATCH 26/28] Replace sizeof(void*) -> SpmiTargetPointerSize() in methodcontext.cpp --- src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 05d3bb9def052a..469eba7a005b9f 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -632,7 +632,7 @@ unsigned int toCorInfoSize(CorInfoType cit) case CORINFO_TYPE_PTR: case CORINFO_TYPE_BYREF: case CORINFO_TYPE_CLASS: - return sizeof(void*); + return SpmiTargetPointerSize(); case CORINFO_TYPE_STRING: case CORINFO_TYPE_VALUECLASS: From d280c5b6c1f72b21804ec9115c2bf952d4a1ded9 Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Fri, 26 Feb 2021 10:56:06 -0800 Subject: [PATCH 27/28] Fix warning in methodcontext.cpp --- src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp index 469eba7a005b9f..1aac4350ba3cb6 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi-shared/methodcontext.cpp @@ -632,7 +632,7 @@ unsigned int toCorInfoSize(CorInfoType cit) case CORINFO_TYPE_PTR: case CORINFO_TYPE_BYREF: case CORINFO_TYPE_CLASS: - return SpmiTargetPointerSize(); + return (int)SpmiTargetPointerSize(); case CORINFO_TYPE_STRING: case CORINFO_TYPE_VALUECLASS: From 5f9e9fd16397223d62458f62ffaf6721000061ae Mon Sep 17 00:00:00 2001 From: Egor Chesakov Date: Fri, 26 Feb 2021 11:00:27 -0800 Subject: [PATCH 28/28] Nit: "theor" -> "their" in neardiffer.cpp --- src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp b/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp index 90659e902edf4b..cc11b287419d81 100644 --- a/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp +++ b/src/coreclr/ToolBox/superpmi/superpmi/neardiffer.cpp @@ -1105,7 +1105,7 @@ bool NearDiffer::compare(MethodContext* mc, CompileResult* cr1, CompileResult* c &orig_roDataBlock_2); // On Arm64 the constant pool is appended at the end of the method code section, hence hotCodeSize_{1,2} - // is a sum of their sizes. The following is to adjust theor sizes and the roDataBlock_{1,2} pointers. + // is a sum of their sizes. The following is to adjust their sizes and the roDataBlock_{1,2} pointers. if (GetSpmiTargetArchitecture() == SPMI_TARGET_ARCHITECTURE_ARM64) { BYTE* nativeEntry_1;