diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h --- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h @@ -49,7 +49,10 @@ /// TODO: Arm_Call is here only as a placeholder for now. Arm_Call = FirstArmRelocation, - LastArmRelocation = Arm_Call, + /// Write immediate value for (unconditional) PC-relative branch without link. + Arm_Jump24, + + LastArmRelocation = Arm_Jump24, /// /// Relocations of class Thumb16 and Thumb32 (covers Thumb instruction subset) @@ -146,12 +149,16 @@ /// template struct FixupInfo {}; -template <> struct FixupInfo { +template <> struct FixupInfo { static constexpr uint32_t Opcode = 0x0a000000; - static constexpr uint32_t OpcodeMask = 0x0e000000; + static constexpr uint32_t OpcodeMask = 0x0f000000; static constexpr uint32_t ImmMask = 0x00ffffff; static constexpr uint32_t Unconditional = 0xe0000000; static constexpr uint32_t CondMask = 0xe0000000; //excluding BLX bit +}; + +template <> struct FixupInfo : public FixupInfo { + static constexpr uint32_t OpcodeMask = 0x0e000000; static constexpr uint32_t BitH = 0x01000000; static constexpr uint32_t BitBlx = 0x10000000; }; diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp @@ -40,6 +40,8 @@ return aarch32::Data_Delta32; case ELF::R_ARM_CALL: return aarch32::Arm_Call; + case ELF::R_ARM_JUMP24: + return aarch32::Arm_Jump24; case ELF::R_ARM_THM_CALL: return aarch32::Thumb_Call; case ELF::R_ARM_THM_JUMP24: @@ -64,6 +66,8 @@ return ELF::R_ARM_ABS32; case aarch32::Arm_Call: return ELF::R_ARM_CALL; + case aarch32::Arm_Jump24: + return ELF::R_ARM_JUMP24; case aarch32::Thumb_Call: return ELF::R_ARM_THM_CALL; case aarch32::Thumb_Jump24: diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp --- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp @@ -288,6 +288,11 @@ return makeUnexpectedOpcodeError(G, R, Kind); return decodeImmBA1BlA1BlxA2(R.Wd); + case Arm_Jump24: + if (!checkOpcode(R)) + return makeUnexpectedOpcodeError(G, R, Kind); + return decodeImmBA1BlA1BlxA2(R.Wd); + default: return make_error( "In graph " + G.getName() + ", section " + B.getSection().getName() + @@ -399,10 +404,25 @@ TargetAddress |= 0x01; switch (Kind) { + case Arm_Jump24: { + if (!checkOpcode(R)) + return makeUnexpectedOpcodeError(G, R, Kind); + if (TargetSymbol.hasTargetFlags(ThumbSymbol)) + return make_error("Branch relocation needs interworking " + "stub when bridging to ARM: " + + StringRef(G.getEdgeKindName(Kind))); + + int64_t Value = TargetAddress - FixupAddress + Addend; + + if (!isInt<26>(Value)) + return makeTargetOutOfRangeError(G, B, E); + writeImmediate(R, encodeImmBA1BlA1BlxA2(Value)); + + return Error::success(); + } case Arm_Call: { if (!checkOpcode(R)) return makeUnexpectedOpcodeError(G, R, Kind); - if ((R.Wd & FixupInfo::CondMask) != FixupInfo::Unconditional) return make_error("Relocation expects an unconditional " @@ -582,6 +602,7 @@ switch (K) { KIND_NAME_CASE(Data_Delta32) KIND_NAME_CASE(Arm_Call) + KIND_NAME_CASE(Arm_Jump24) KIND_NAME_CASE(Thumb_Call) KIND_NAME_CASE(Thumb_Jump24) KIND_NAME_CASE(Thumb_MovwAbsNC) diff --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_arm_reloc.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_arm_reloc.s --- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_arm_reloc.s +++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_arm_reloc.s @@ -2,8 +2,7 @@ // RUN: llvm-jitlink -noexec -slab-address 0x76ff0000 -slab-allocate 10Kb -slab-page-size 4096 \ // RUN: -abs target=0x76bbe880 -show-entry-es -check %s %t.o -# Check R_ARM_CALL relocation handling - +# Check R_ARM_CALL and R_ARM_JUMP24 relocation handling .globl target .type target, %function @@ -29,3 +28,9 @@ blx target .size callx, .-callx +# R_ARM_JUMP24 + .global jump24 +# jitlink-check: next_pc(jump24)+ decode_operand(jump24, 0) + 4 = target + jump24: + b target + .size jump24, .-jump24