diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp --- a/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_aarch64.cpp @@ -45,7 +45,9 @@ class ELFLinkGraphBuilder_aarch64 : public ELFLinkGraphBuilder { private: enum ELFAArch64RelocationKind : Edge::Kind { - ELFBranch26 = Edge::FirstRelocation, + ELFCall26 = Edge::FirstRelocation, + ELFAdrPage21, + ELFAddAbs12, }; static Expected @@ -53,7 +55,11 @@ using namespace aarch64; switch (Type) { case ELF::R_AARCH64_CALL26: - return ELFBranch26; + return ELFCall26; + case ELF::R_AARCH64_ADR_PREL_PG_HI21: + return ELFAdrPage21; + case ELF::R_AARCH64_ADD_ABS_LO12_NC: + return ELFAddAbs12; } return make_error("Unsupported aarch64 relocation:" + @@ -105,10 +111,18 @@ Edge::Kind Kind = Edge::Invalid; switch (*RelocKind) { - case ELFBranch26: { + case ELFCall26: { Kind = aarch64::Branch26; break; } + case ELFAdrPage21: { + Kind = aarch64::Page21; + break; + } + case ELFAddAbs12: { + Kind = aarch64::PageOffset12; + break; + } }; Edge GE(Kind, Offset, *GraphSymbol, Addend); @@ -125,8 +139,12 @@ /// Return the string name of the given ELF aarch64 edge kind. const char *getELFAArch64RelocationKindName(Edge::Kind R) { switch (R) { - case ELFBranch26: - return "ELFBranch26"; + case ELFCall26: + return "ELFCall26"; + case ELFAdrPage21: + return "ELFAdrPage21"; + case ELFAddAbs12: + return "ELFAddAbs12"; default: return getGenericEdgeKindName(static_cast(R)); } diff --git a/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s new file mode 100644 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_aarch64_relocations.s @@ -0,0 +1,57 @@ +# RUN: rm -rf %t && mkdir -p %t +# RUN: llvm-mc -triple=aarch64-unknown-linux-gnu -relax-relocations=false -position-independent -filetype=obj -o %t/elf_reloc.o %s +# RUN: llvm-jitlink -noexec -check %s %t/elf_reloc.o + + .text + + .globl main + .p2align 2 + .type main,@function +main: + ret + + .size main, .-main + +# Check R_AARCH64_CALL26 relocation of a local function call +# +# jitlink-check: decode_operand(local_func_call26, 0)[25:0] = (local_func - local_func_call26)[27:2] + .globl local_func + .p2align 2 + .type local_func,@function +local_func: + ret + .size local_func, .-local_func + + .globl local_func_call26 + .p2align 2 +local_func_call26: + bl local_func + .size local_func_call26, .-local_func_call26 + + +# Check R_AARCH64_ADR_PREL_PG_HI21 / R_AARCH64_ADD_ABS_LO12_NC relocation of a local symbol +# +# For the ADR_PREL_PG_HI21/ADRP instruction we have the 21-bit delta to the 4k page +# containing the global. +# +# jitlink-check: decode_operand(test_adr_prel, 1) = (named_data - test_adr_prel)[32:12] +# jitlink-check: decode_operand(test_add_abs_lo12, 2) = (named_data + 0)[11:0] + .globl test_adr_prel + .p2align 2 +test_adr_prel: + adrp x0, named_data + .size test_adr_prel, .-test_adr_prel + + .globl test_add_abs_lo12 + .p2align 2 +test_add_abs_lo12: + add x0, x0, :lo12:named_data + .size test_add_abs_lo12, .-test_add_abs_lo12 + + .globl named_data + .p2align 4 + .type named_data,@object +named_data: + .quad 0x2222222222222222 + .quad 0x3333333333333333 + .size named_data, .-named_data