Index: lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp =================================================================== --- lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -360,6 +360,16 @@ static_cast(Result & 0xffffffffU); break; } + case ELF::R_AARCH64_PREL64: { + uint64_t *TargetPtr = + reinterpret_cast(Section.getAddressWithOffset(Offset)); + uint64_t Result = Value + Addend - FinalAddress; + if (isBE) + support::ubig64_t::ref{TargetPtr} = Result; + else + support::ulittle64_t::ref{TargetPtr} = Result; + break; + } case ELF::R_AARCH64_CALL26: // fallthrough case ELF::R_AARCH64_JUMP26: { // Operation: S+A-P. Set Call or B immediate value to bits fff_fffc of the Index: lib/MC/MCObjectFileInfo.cpp =================================================================== --- lib/MC/MCObjectFileInfo.cpp +++ lib/MC/MCObjectFileInfo.cpp @@ -279,6 +279,8 @@ case Triple::mips64el: FDECFIEncoding = dwarf::DW_EH_PE_sdata8; break; + case Triple::aarch64: + case Triple::aarch64_be: case Triple::x86_64: FDECFIEncoding = dwarf::DW_EH_PE_pcrel | ((CMModel == CodeModel::Large) ? dwarf::DW_EH_PE_sdata8 Index: test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-large-relocations.s =================================================================== --- /dev/null +++ test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_BE-large-relocations.s @@ -0,0 +1,18 @@ +# RUN: llvm-mc -triple=aarch64_be-none-linux-gnu -code-model=large -filetype=obj -o %T/be-large-reloc.o %s +# RUN: llvm-rtdyld -triple=aarch64_be-none-linux-gnu -verify -map-section be-large-reloc.o,.eh_frame=0x10000 -map-section be-large-reloc.o,.text=0xffff000000000000 -check=%s %T/be-large-reloc.o + + .text + .globl g + .p2align 2 + .type g,@function +g: + .cfi_startproc + mov x0, xzr + ret + .Lfunc_end0: + .size g, .Lfunc_end0-g + .cfi_endproc + +# Skip the CIE and load the 8 bytes PC begin pointer. +# Assuming the CIE and the FDE length are both 4 bytes. +# rtdyld-check: *{8}(section_addr(be-large-reloc.o, .eh_frame) + (*{4}(section_addr(be-large-reloc.o, .eh_frame))) + 0xc) = g - (section_addr(be-large-reloc.o, .eh_frame) + (*{4}(section_addr(be-large-reloc.o, .eh_frame))) + 0xc) Index: test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s =================================================================== --- /dev/null +++ test/ExecutionEngine/RuntimeDyld/AArch64/ELF_ARM64_large-relocations.s @@ -0,0 +1,18 @@ +# RUN: llvm-mc -triple=arm64-none-linux-gnu -code-model=large -filetype=obj -o %T/large-reloc.o %s +# RUN: llvm-rtdyld -triple=arm64-none-linux-gnu -verify -map-section large-reloc.o,.eh_frame=0x10000 -map-section large-reloc.o,.text=0xffff000000000000 -check=%s %T/large-reloc.o + + .text + .globl g + .p2align 2 + .type g,@function +g: + .cfi_startproc + mov x0, xzr + ret + .Lfunc_end0: + .size g, .Lfunc_end0-g + .cfi_endproc + +# Skip the CIE and load the 8 bytes PC begin pointer. +# Assuming the CIE and the FDE length are both 4 bytes. +# rtdyld-check: *{8}(section_addr(large-reloc.o, .eh_frame) + (*{4}(section_addr(large-reloc.o, .eh_frame))) + 0xc) = g - (section_addr(large-reloc.o, .eh_frame) + (*{4}(section_addr(large-reloc.o, .eh_frame))) + 0xc)