From 18805ea951be02fcab6e7b11c3c7d929bcf1441a Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Fri, 6 Nov 2020 14:26:04 -0500 Subject: [PATCH] Fix unwind info relocation with large code model on AArch64 Makes sure that the unwind info uses 64bits pcrel relocation if a large code model is specified and handle the corresponding relocation in the ExecutionEngine. This can happen with certain kernel configuration (the same as the one in https://reviews.llvm.org/D27609, found at least on the ArchLinux stock kernel and the one used on https://www.packet.net/) using the builtin JIT memory manager. Co-authored-by: Yichao Yu Differential Revision: https://reviews.llvm.org/D27629 --- llvm/lib/MC/MCObjectFileInfo.cpp | 2 ++ llvm/test/MC/AArch64/ELF_ARM64_large-relocations.s | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 llvm/test/MC/AArch64/ELF_ARM64_large-relocations.s diff --git a/llvm/lib/MC/MCObjectFileInfo.cpp b/llvm/lib/MC/MCObjectFileInfo.cpp index 1349494..9505420 100644 --- a/llvm/lib/MC/MCObjectFileInfo.cpp +++ b/llvm/lib/MC/MCObjectFileInfo.cpp @@ -317,6 +317,8 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) { break; case Triple::ppc64: case Triple::ppc64le: + case Triple::aarch64: + case Triple::aarch64_be: case Triple::x86_64: FDECFIEncoding = dwarf::DW_EH_PE_pcrel | (Large ? dwarf::DW_EH_PE_sdata8 : dwarf::DW_EH_PE_sdata4); diff --git a/llvm/test/MC/AArch64/ELF_ARM64_large-relocations.s b/llvm/test/MC/AArch64/ELF_ARM64_large-relocations.s new file mode 100644 index 0000000..66f28da --- /dev/null +++ b/llvm/test/MC/AArch64/ELF_ARM64_large-relocations.s @@ -0,0 +1,20 @@ +# RUN: llvm-mc -triple=arm64-none-linux-gnu -large-code-model -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 +# RUN-BE: llvm-mc -triple=aarch64_be-none-linux-gnu -large-code-model -filetype=obj -o %T/be-large-reloc.o %s +# RUN-BE: 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(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) -- 2.7.4