diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -126,6 +126,7 @@ case R_AARCH64_CONDBR19: case R_AARCH64_JUMP26: case R_AARCH64_TSTBR14: + case R_AARCH64_PLT32: return R_PLT_PC; case R_AARCH64_PREL16: case R_AARCH64_PREL32: @@ -325,6 +326,10 @@ checkIntUInt(loc, val, 32, rel); write32le(loc, val); break; + case R_AARCH64_PLT32: + checkInt(loc, val, 32, rel); + write32le(loc, val); + break; case R_AARCH64_ABS64: case R_AARCH64_PREL64: write64le(loc, val); diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -556,6 +556,7 @@ case R_AARCH64_PREL64: case R_AARCH64_ADR_PREL_LO21: case R_AARCH64_LD_PREL_LO19: + case R_AARCH64_PLT32: return p + a; } llvm_unreachable("AArch64 pc-relative relocation expected\n"); diff --git a/lld/test/ELF/aarch64-plt32.test b/lld/test/ELF/aarch64-plt32.test new file mode 100644 --- /dev/null +++ b/lld/test/ELF/aarch64-plt32.test @@ -0,0 +1,60 @@ +# REQUIRES: aarch64 +# RUN: yaml2obj %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs255.s -o %t255.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs256.s -o %t256.o +# RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs257.s -o %t257.o + +# Check for overflow with a R_AACH64_PLT32 relocation. + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_FREEBSD + Type: ET_REL + Machine: EM_AARCH64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000004 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: '0000000000000000' + - Name: .rela.data + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .data + Relocations: + - Symbol: foo + Type: R_AARCH64_PLT32 + Addend: 2149589079 + - Offset: 0x0000000000000004 + Symbol: foo + Type: R_AARCH64_PLT32 + Addend: -2145378212 +Symbols: + - Name: _start + Section: .text + Binding: STB_GLOBAL + - Name: foo + Binding: STB_GLOBAL + +# RUN: ld.lld -z max-page-size=4096 %t.o %t256.o -o %t2 +# RUN: llvm-objdump -s --section=.data %t2 | FileCheck %s + +# CHECK: Contents of section .data: +# 202158: S = 0x100, A = 0x80202057, P = 0x202158 +# S + A - P = 0xffffff7f +# 20215c: S = 0x100, A = -0x7fdfdfa4, P = 0x20215c +# S + A - P = 0x80000000 +# CHECK-NEXT: 202158 ffffff7f 00000080 + +# RUN: not ld.lld -z max-page-size=4096 %t.o %t255.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW1 +# OVERFLOW1: relocation R_AARCH64_PLT32 out of range: -2147483649 is not in [-2147483648, 2147483647]; references foo + +# RUN: not ld.lld -z max-page-size=4096 %t.o %t257.o -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW2 +# OVERFLOW2: relocation R_AARCH64_PLT32 out of range: 2147483648 is not in [-2147483648, 2147483647]; references foo diff --git a/lld/test/ELF/aarch64-undefined-weak-plt32.test b/lld/test/ELF/aarch64-undefined-weak-plt32.test new file mode 100644 --- /dev/null +++ b/lld/test/ELF/aarch64-undefined-weak-plt32.test @@ -0,0 +1,42 @@ +# REQUIRES: aarch64 +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld --image-base=0x10000000 %t.o -o %t +# RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_AARCH64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000004 + Content: '0000000000000000' + - Name: .rela.text + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .text + Relocations: + - Symbol: target + Type: R_AARCH64_PREL32 + - Offset: 0x0000000000000004 + Symbol: target + Type: R_AARCH64_PLT32 +Symbols: + - Name: '$d.0' + Section: .text + - Name: _start + Section: .text + Binding: STB_GLOBAL + - Name: target + Binding: STB_WEAK + +# CHECK: Disassembly of section .text: +# CHECK-EMPTY: +# CHECK-NEXT: 0000000010010120 <_start>: +# CHECK-NEXT: 10010120: 00 00 00 00 .word 0x00000000 +# CHECK-NEXT: 10010124: 00 00 00 00 .word 0x00000000 diff --git a/lld/test/ELF/relocation-plt32-aarch64.test b/lld/test/ELF/relocation-plt32-aarch64.test new file mode 100644 --- /dev/null +++ b/lld/test/ELF/relocation-plt32-aarch64.test @@ -0,0 +1,44 @@ +# REQUIRES: aarch64 +# RUN: yaml2obj %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t.out +# RUN: llvm-objdump -s %t.out | FileCheck %s + +# Check that a PLT entry is generated for R_AARCH64_PLT32 and the caulculation is correct. + +# CHECK: Contents of section .plt: +# CHECK-NEXT: 10290 +# CHECK: Contents of section .data: +# CHECK: 30370 40fffdff +# The calculation is +# 0x10290 (foo@PLT) +# - 0x30370 (.data) +# --------- +# -0x200c0 -> 0xfffdff40 -> 0x40fffdff (little endian) + +!ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_REL + Machine: EM_AARCH64 +Sections: + - Name: .text + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_EXECINSTR ] + AddressAlign: 0x0000000000000004 + - Name: .data + Type: SHT_PROGBITS + Flags: [ SHF_WRITE, SHF_ALLOC ] + AddressAlign: 0x0000000000000001 + Content: '00000000' + - Name: .rela.data + Type: SHT_RELA + Link: .symtab + AddressAlign: 0x0000000000000008 + Info: .data + Relocations: + - Symbol: foo + Type: R_AARCH64_PLT32 +Symbols: + - Name: foo + Binding: STB_GLOBAL