diff --git a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h index 3f36b53d6684a..97999a61dfe73 100644 --- a/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h +++ b/llvm/include/llvm/ExecutionEngine/JITLink/aarch32.h @@ -89,7 +89,15 @@ enum EdgeKind_aarch32 : Edge::Kind { /// Write immediate value to the top halfword of the destination register Thumb_MovtAbs, - LastThumbRelocation = Thumb_MovtAbs, + /// Write PC-relative immediate value to the lower halfword of the destination + /// register + Thumb_MovwPrelNC, + + /// Write PC-relative immediate value to the top halfword of the destination + /// register + Thumb_MovtPrel, + + LastThumbRelocation = Thumb_MovtPrel, }; /// Flags enum for AArch32-specific symbol properties diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp index 6359ceb4c5174..b6b63691d8408 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch32.cpp @@ -53,6 +53,10 @@ Expected getJITLinkEdgeKind(uint32_t ELFType) { return aarch32::Thumb_MovwAbsNC; case ELF::R_ARM_THM_MOVT_ABS: return aarch32::Thumb_MovtAbs; + case ELF::R_ARM_THM_MOVW_PREL_NC: + return aarch32::Thumb_MovwPrelNC; + case ELF::R_ARM_THM_MOVT_PREL: + return aarch32::Thumb_MovtPrel; } return make_error( @@ -83,6 +87,10 @@ Expected getELFRelocationType(Edge::Kind Kind) { return ELF::R_ARM_THM_MOVW_ABS_NC; case aarch32::Thumb_MovtAbs: return ELF::R_ARM_THM_MOVT_ABS; + case aarch32::Thumb_MovwPrelNC: + return ELF::R_ARM_THM_MOVW_PREL_NC; + case aarch32::Thumb_MovtPrel: + return ELF::R_ARM_THM_MOVT_PREL; } return make_error(formatv("Invalid aarch32 edge {0:d}: ", diff --git a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp index 4aed649666544..c3823f985ce18 100644 --- a/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/aarch32.cpp @@ -377,12 +377,14 @@ Expected readAddendThumb(LinkGraph &G, Block &B, const Edge &E, : decodeImmBT4BlT1BlxT2(R.Hi, R.Lo); case Thumb_MovwAbsNC: + case Thumb_MovwPrelNC: if (!checkOpcode(R)) return makeUnexpectedOpcodeError(G, R, Kind); // Initial addend is interpreted as a signed value return SignExtend64<16>(decodeImmMovtT1MovwT3(R.Hi, R.Lo)); case Thumb_MovtAbs: + case Thumb_MovtPrel: if (!checkOpcode(R)) return makeUnexpectedOpcodeError(G, R, Kind); // Initial addend is interpreted as a signed value @@ -610,6 +612,20 @@ Error applyFixupThumb(LinkGraph &G, Block &B, const Edge &E, writeImmediate(R, encodeImmMovtT1MovwT3(Value)); return Error::success(); } + case Thumb_MovwPrelNC: { + if (!checkOpcode(R)) + return makeUnexpectedOpcodeError(G, R, Kind); + uint16_t Value = ((TargetAddress + Addend - FixupAddress) & 0xffff); + writeImmediate(R, encodeImmMovtT1MovwT3(Value)); + return Error::success(); + } + case Thumb_MovtPrel: { + if (!checkOpcode(R)) + return makeUnexpectedOpcodeError(G, R, Kind); + uint16_t Value = (((TargetAddress + Addend - FixupAddress) >> 16) & 0xffff); + writeImmediate(R, encodeImmMovtT1MovwT3(Value)); + return Error::success(); + } default: return make_error( @@ -659,6 +675,8 @@ const char *getEdgeKindName(Edge::Kind K) { KIND_NAME_CASE(Thumb_Jump24) KIND_NAME_CASE(Thumb_MovwAbsNC) KIND_NAME_CASE(Thumb_MovtAbs) + KIND_NAME_CASE(Thumb_MovwPrelNC) + KIND_NAME_CASE(Thumb_MovtPrel) default: return getGenericEdgeKindName(K); } diff --git a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s index c694a65ae1061..c4f4d4a9e10a1 100644 --- a/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s +++ b/llvm/test/ExecutionEngine/JITLink/AArch32/ELF_static_thumb_reloc.s @@ -2,7 +2,8 @@ # RUN: llvm-objdump -r %t.o | FileCheck --check-prefix=CHECK-TYPE %s # RUN: llvm-objdump --disassemble %t.o | FileCheck --check-prefix=CHECK-INSTR %s # RUN: llvm-jitlink -noexec -slab-address 0x76ff0000 -slab-allocate 10Kb \ -# RUN: -slab-page-size 4096 -show-entry-es -check %s %t.o +# RUN: -slab-page-size 4096 -abs external_func=0x76bbe880 \ +# RUN: -check %s %t.o .text @@ -95,6 +96,34 @@ data_symbol: .text +# CHECK-TYPE: {{[0-9a-f]+}} R_ARM_THM_MOVW_PREL_NC external_func +# CHECK-INSTR: 00000014 : +# CHECK-INSTR: 14: f240 0000 movw r0, #0x0 +# jitlink-check: decode_operand(movw_prel, 1) = \ +# jitlink-check: ((external_func - movw_prel)&0x0000ffff) +.globl movw_prel +.type movw_prel,%function +.p2align 1 +.code 16 +.thumb_func +movw_prel: + movw r0, :lower16:external_func - . + .size movw_prel, .-movw_prel + +# CHECK-TYPE: {{[0-9a-f]+}} R_ARM_THM_MOVT_PREL external_func +# CHECK-INSTR: 00000018 : +# CHECK-INSTR: 18: f2c0 0000 movt r0, #0x0 +# jitlink-check: decode_operand(movt_prel, 2) = \ +# jitlink-check: ((external_func - movt_prel)&0xffff0000>>16) +.globl movt_prel +.type movt_prel,%function +.p2align 1 +.code 16 +.thumb_func +movt_prel: + movt r0, :upper16:external_func - . + .size movt_prel, .-movt_prel + # Empty main function for jitlink to be happy .globl main .type main,%function