diff options
author | George Koehler <kernigh@gmail.com> | 2021-12-16 18:06:49 -0800 |
---|---|---|
committer | Fangrui Song <i@maskray.me> | 2021-12-16 18:06:50 -0800 |
commit | e68f640deecc4cc6318c14468101f4d819f93727 (patch) | |
tree | 3cffc7efb0259cf8ee0ae707138730036afd27c6 | |
parent | 87ca22cba2fad9bbf553a74eced3b7bb69e187be (diff) | |
download | llvm-e68f640deecc4cc6318c14468101f4d819f93727.tar.gz |
[ELF][PPC32] Make R_PPC32_PLTREL retain .got
PLT usage needs the first 12 bytes of the .got section. We need to keep .got and
DT_GOT_PPC even if .got/_GLOBAL_OFFSET_TABLE_ are not referenced (large PIC code
may only reference .got2), which is the case in OpenBSD's ld.so, leading
to a misleading error, "unsupported insecure BSS PLT object".
Fix this by adding R_PPC32_PLTREL to the list of hasGotOffRel.
Reviewed By: MaskRay
Differential Revision: https://reviews.llvm.org/D114982
(cherry picked from commit 885fb9a257faa14ec33ad972df81801483c85da2)
-rw-r--r-- | lld/ELF/Relocations.cpp | 4 | ||||
-rw-r--r-- | lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s | 6 | ||||
-rw-r--r-- | lld/test/ELF/ppc32-reloc-pltrel.s | 35 |
3 files changed, 40 insertions, 5 deletions
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index fefd6f21f590..71249188afe3 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1409,8 +1409,8 @@ static void scanReloc(InputSectionBase &sec, OffsetGetter &getOffset, RelTy *&i, // The 4 types that relative GOTPLT are all x86 and x86-64 specific. if (oneof<R_GOTPLTONLY_PC, R_GOTPLTREL, R_GOTPLT, R_TLSGD_GOTPLT>(expr)) { in.gotPlt->hasGotPltOffRel = true; - } else if (oneof<R_GOTONLY_PC, R_GOTREL, R_PPC64_TOCBASE, R_PPC64_RELAX_TOC>( - expr)) { + } else if (oneof<R_GOTONLY_PC, R_GOTREL, R_PPC32_PLTREL, R_PPC64_TOCBASE, + R_PPC64_RELAX_TOC>( expr)) { in.got->hasGotOffRel = true; } diff --git a/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s b/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s index a88927fdfd75..a4b7c8bf97b8 100644 --- a/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s +++ b/lld/test/ELF/ppc32-ifunc-nonpreemptible-pic.s @@ -7,12 +7,12 @@ # RUN: llvm-objdump -d --no-show-raw-insn %t | FileCheck %s # RELOC: .rela.dyn { -# RELOC-NEXT: 0x30248 R_PPC_RELATIVE - 0x101A8 -# RELOC-NEXT: 0x3024C R_PPC_IRELATIVE - 0x10188 +# RELOC-NEXT: 0x30254 R_PPC_RELATIVE - 0x101A8 +# RELOC-NEXT: 0x30258 R_PPC_IRELATIVE - 0x10188 # RELOC-NEXT: } # SYM: 000101a8 0 FUNC GLOBAL DEFAULT {{.*}} func -# HEX: 0x00030248 00000000 +# HEX: 0x00030254 00000000 .section .got2,"aw" .long func diff --git a/lld/test/ELF/ppc32-reloc-pltrel.s b/lld/test/ELF/ppc32-reloc-pltrel.s new file mode 100644 index 000000000000..17418482871c --- /dev/null +++ b/lld/test/ELF/ppc32-reloc-pltrel.s @@ -0,0 +1,35 @@ +# REQUIRES: ppc + +## Ensure R_PPC_PLTREL retains .got even in the absence of +## .got/_GLOBAL_OFFSET_TABLE_ references. + +# RUN: llvm-mc -filetype=obj -triple=powerpc %s -o %t.o +# RUN: ld.lld -shared %t.o -o %t.so +# RUN: llvm-readobj -Sdr %t.so | FileCheck %s + +.section .got2,"aw",@progbits +.set .LTOC, .+0x8000 + +.text +.L0: +addis 30,30,.LTOC-.L0@ha +addi 30,30,.LTOC-.L0@l +bl baz+0x8000@plt + +## DT_PPC_GOT must point to .got, which must have the 12-byte header. +## The only relocation is an R_PPC_JMP_SLOT. + +# CHECK: Sections [ +# CHECK: Name: .got ( +# CHECK: Address: +# CHECK-SAME: {{ }}[[#%x,GOT:]] +# CHECK: Size: +# CHECK-SAME: {{ 12$}} +# CHECK: DynamicSection [ +# CHECK-NEXT: Tag Type Name/Value +# CHECK: 0x70000000 PPC_GOT [[#GOT]] +# CHECK: Relocations [ +# CHECK-NEXT: Section ([[#]]) .rela.plt { +# CHECK-NEXT: 0x[[#%x,]] R_PPC_JMP_SLOT baz 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] |