diff --git a/src/coreclr/jit/emitarm.cpp b/src/coreclr/jit/emitarm.cpp index 1f5698a0afb01e..cfb5de23666cac 100644 --- a/src/coreclr/jit/emitarm.cpp +++ b/src/coreclr/jit/emitarm.cpp @@ -5334,7 +5334,14 @@ BYTE* emitter::emitOutputLJ(insGroup* ig, BYTE* dst, instrDesc* i) else { assert(ins == INS_movw || ins == INS_movt); - distVal = (ssize_t)emitOffsetToPtr(dstOffs) + 1; // Or in thumb bit + distVal = (ssize_t)emitOffsetToPtr(dstOffs); + + // ILC defines method symbols with the thumb bit already set, so don't add it here. + // For ReadyToRun and non-relocatable code (runtime JIT), we set it ourselves. + if (!m_compiler->IsNativeAot()) + { + distVal += 1; + } } if (dstOffs <= srcOffs) diff --git a/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs b/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs index 1736908a2250c4..cbc3cf3537f7cf 100644 --- a/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs +++ b/src/coreclr/tools/Common/Compiler/ObjectWriter/ObjectWriter.cs @@ -189,20 +189,13 @@ or IMAGE_REL_BASED_THUMB_BRANCH24 or IMAGE_REL_BASED_THUMB_MOV32_PCREL && // Resolve the relocation to already defined symbol and write it into data fixed (byte* pData = data) { - // RyuJIT generates the Thumb bit in the addend and we also get it from - // the symbol value. The AAELF ABI specification defines the R_ARM_THM_JUMP24 - // and R_ARM_THM_MOVW_PREL_NC relocations using the formula ((S + A) | T) – P. - // The thumb bit is thus supposed to be only added once. - // For R_ARM_THM_JUMP24 the thumb bit cannot be encoded, so mask it out. - // - // R2R doesn't use add the thumb bit to the symbol value, so we don't need to do this here. -#if !READYTORUN - long maskThumbBitOut = relocType is IMAGE_REL_BASED_THUMB_BRANCH24 or IMAGE_REL_BASED_THUMB_MOV32_PCREL ? 1 : 0; - long maskThumbBitIn = relocType is IMAGE_REL_BASED_THUMB_MOV32_PCREL ? 1 : 0; -#else - long maskThumbBitOut = 0; - long maskThumbBitIn = 0; -#endif + // Method symbols should be defined with the thumb bit (+1) set per the AAELF ABI + // convention. For BRANCH24, the encoding cannot represent the thumb bit + // (per AAELF formula ((S + A) | T) – P), so strip it from the symbol value. + // NOTE: R2R doesn't currently add the thumb bit to the symbol value, so this is a NOP. + long symbolValue = relocType is IMAGE_REL_BASED_THUMB_BRANCH24 + ? definedSymbol.Value & ~1L + : definedSymbol.Value; long adjustedAddend = addend; adjustedAddend -= relocType switch @@ -213,9 +206,8 @@ or IMAGE_REL_BASED_THUMB_BRANCH24 or IMAGE_REL_BASED_THUMB_MOV32_PCREL && _ => 0 }; - adjustedAddend += definedSymbol.Value & ~maskThumbBitOut; + adjustedAddend += symbolValue; adjustedAddend += Relocation.ReadValue(relocType, (void*)pData); - adjustedAddend |= definedSymbol.Value & maskThumbBitIn; adjustedAddend -= offset; if (relocType is IMAGE_REL_BASED_THUMB_BRANCH24 && !Relocation.FitsInThumb2BlRel24((int)adjustedAddend))