From 31e764bc7f3840e3eb29b297c152f87371c8f122 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 23 Oct 2023 18:59:04 +0200 Subject: [PATCH] JIT: Fix encoding cross-jumps at JIT time (#93851) In 7db4f33 I made the assumption that cross-jumps only appear while prejitting (and thus while recording relocations). However, the fake splitting stress mode runs during JIT and thus will hit the assert. Make the logic handle JIT time splitting as well. Fix #93848 --- src/coreclr/jit/emitxarch.cpp | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/emitxarch.cpp b/src/coreclr/jit/emitxarch.cpp index 7e962c2e0c7cb..f99fb576aac7f 100644 --- a/src/coreclr/jit/emitxarch.cpp +++ b/src/coreclr/jit/emitxarch.cpp @@ -15844,25 +15844,38 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i) // For forward jumps, record the address of the distance value id->idjTemp.idjAddr = (dstOffs > srcOffs) ? dst : nullptr; - // Cross jumps may not be encodable in a 32-bit displacement as the - // hot/cold code buffers may be allocated arbitrarily far away from - // each other. We simply encode a 0 under the assumption that the - // relocations will take care of it. bool crossJump = emitJumpCrossHotColdBoundary(srcOffs, dstOffs); - assert(!crossJump || emitComp->opts.compReloc); - dst += emitOutputLong(dst, crossJump ? 0 : distVal); + int32_t encodedDisplacement; + if (emitComp->opts.compReloc && (!relAddr || crossJump)) + { + // Cross jumps may not be encodable in a 32-bit displacement as the + // hot/cold code buffers may be allocated arbitrarily far away from + // each other. Similarly, absolute addresses when cross compiling + // for 32-bit may also not be representable. We simply encode a 0 + // under the assumption that the relocations will take care of it. + encodedDisplacement = 0; + } + else + { + // For all other cases the displacement should be encodable in 32 + // bits. + assert((distVal >= INT32_MIN) && (distVal <= INT32_MAX)); + encodedDisplacement = static_cast(distVal); + } + + dst += emitOutputLong(dst, encodedDisplacement); if (emitComp->opts.compReloc) { if (!relAddr) { - emitRecordRelocation((void*)(dst - sizeof(INT32)), (void*)distVal, IMAGE_REL_BASED_HIGHLOW); + emitRecordRelocation((void*)(dst - sizeof(int32_t)), (void*)distVal, IMAGE_REL_BASED_HIGHLOW); } else if (crossJump) { assert(id->idjKeepLong); - emitRecordRelocation((void*)(dst - sizeof(INT32)), dst + distVal, IMAGE_REL_BASED_REL32); + emitRecordRelocation((void*)(dst - sizeof(int32_t)), dst + distVal, IMAGE_REL_BASED_REL32); } } }