diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h index 0968a093279bf..938d25dc15bf2 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h @@ -135,6 +135,8 @@ enum class StubsFlavor { struct ArmConfig { bool J1J2BranchEncoding = false; StubsFlavor Stubs = StubsFlavor::Unsupported; + // In the long term, we might want a linker switch like --target1-rel + bool Target1Rel = false; }; /// Obtain the sub-arch configuration for a given Arm CPU model. diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp index 2553cd70a5769..ed7d58da2dc11 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp @@ -31,7 +31,8 @@ namespace llvm { namespace jitlink { /// Translate from ELF relocation type to JITLink-internal edge kind. -Expected getJITLinkEdgeKind(uint32_t ELFType) { +Expected +getJITLinkEdgeKind(uint32_t ELFType, const aarch32::ArmConfig &ArmCfg) { switch (ELFType) { case ELF::R_ARM_ABS32: return aarch32::Data_Pointer32; @@ -47,6 +48,9 @@ Expected getJITLinkEdgeKind(uint32_t ELFType) { return aarch32::Arm_MovwAbsNC; case ELF::R_ARM_MOVT_ABS: return aarch32::Arm_MovtAbs; + case ELF::R_ARM_TARGET1: + return (ArmCfg.Target1Rel) ? aarch32::Data_Delta32 + : aarch32::Data_Pointer32; case ELF::R_ARM_THM_CALL: return aarch32::Thumb_Call; case ELF::R_ARM_THM_JUMP24: @@ -171,7 +175,7 @@ class ELFLinkGraphBuilder_aarch32 inconvertibleErrorCode()); uint32_t Type = Rel.getType(false); - Expected Kind = getJITLinkEdgeKind(Type); + Expected Kind = getJITLinkEdgeKind(Type, ArmCfg); if (!Kind) return Kind.takeError(); diff --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_data.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_data.s index f91a4733c40ee..de25a82aff16b 100644 --- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_data.s +++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_relocations_data.s @@ -29,6 +29,13 @@ rel32: .word target - . .size rel32, .-rel32 +# CHECK-TYPE: {{[0-9a-f]+}} R_ARM_TARGET1 target +# jitlink-check: *{4}(target1_abs32) = target + .global target1_abs32 +target1_abs32: + .word target(target1) + .size target1_abs32, .-target1_abs32 + # CHECK-TYPE: {{[0-9a-f]+}} R_ARM_GOT_PREL target # # The GOT entry contains the absolute address of the external: diff --git a/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp b/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp index 26c773b8dc3a7..a08884e1c7f7f 100644 --- a/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp +++ b/llvm/unittests/ExecutionEngine/JITLink/AArch32Tests.cpp @@ -39,7 +39,8 @@ struct MutableWord { namespace llvm { namespace jitlink { -Expected getJITLinkEdgeKind(uint32_t ELFType); +Expected +getJITLinkEdgeKind(uint32_t ELFType, const aarch32::ArmConfig &Cfg); Expected getELFRelocationType(Edge::Kind Kind); } // namespace jitlink @@ -47,7 +48,8 @@ Expected getELFRelocationType(Edge::Kind Kind); TEST(AArch32_ELF, EdgeKinds) { // Fails: Invalid ELF type -> JITLink kind - Expected ErrKind = getJITLinkEdgeKind(ELF::R_ARM_NONE); + aarch32::ArmConfig Cfg; + Expected ErrKind = getJITLinkEdgeKind(ELF::R_ARM_NONE, Cfg); EXPECT_TRUE(errorToBool(ErrKind.takeError())); // Fails: Invalid JITLink kind -> ELF type @@ -59,7 +61,7 @@ TEST(AArch32_ELF, EdgeKinds) { EXPECT_FALSE(errorToBool(ELFType.takeError())) << "Failed to translate JITLink kind -> ELF type"; - Expected JITLinkKind = getJITLinkEdgeKind(*ELFType); + Expected JITLinkKind = getJITLinkEdgeKind(*ELFType, Cfg); EXPECT_FALSE(errorToBool(JITLinkKind.takeError())) << "Failed to translate ELF type -> JITLink kind";