[lld] [ELF] --pack-dyn-relocs=android: place IRELATIVE in .rela.dyn (PR #86751)

via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 26 17:02:31 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-lld

Author: Fangrui Song (MaskRay)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/86751.diff


2 Files Affected:

- (modified) lld/ELF/Relocations.cpp (+8-2) 
- (added) lld/test/ELF/pack-dyn-relocs-ifunc.s (+43) 


``````````diff
diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp
index 33c50133bec495..2ffb40c5fa4398 100644
--- a/lld/ELF/Relocations.cpp
+++ b/lld/ELF/Relocations.cpp
@@ -1659,10 +1659,16 @@ static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
   // original section/value pairs. For non-GOT non-PLT relocation case below, we
   // may alter section/value, so create a copy of the symbol to make
   // section/value fixed.
+  //
+  // Prior to Android V, there was a bug that caused RELR relocations to be
+  // applied after packed relocations. This meant that resolvers referenced
+  // IRELATIVE relocations in the packed relocation section could not read
+  // globals with RELR relocations. Work around this by placing IRELATIVE in
+  // .rela.plt.
   auto *directSym = makeDefined(cast<Defined>(sym));
   directSym->allocateAux();
-  addPltEntry(*in.iplt, *in.igotPlt, *mainPart->relaDyn, target->iRelativeRel,
-              *directSym);
+  auto &dyn = config->androidPackDynRelocs ? *in.relaPlt : *mainPart->relaDyn;
+  addPltEntry(*in.iplt, *in.igotPlt, dyn, target->iRelativeRel, *directSym);
   sym.allocateAux();
   symAux.back().pltIdx = symAux[directSym->auxIdx].pltIdx;
 
diff --git a/lld/test/ELF/pack-dyn-relocs-ifunc.s b/lld/test/ELF/pack-dyn-relocs-ifunc.s
new file mode 100644
index 00000000000000..ada771aa08ace3
--- /dev/null
+++ b/lld/test/ELF/pack-dyn-relocs-ifunc.s
@@ -0,0 +1,43 @@
+# REQUIRES: aarch64
+## Prior to Android V, there was a bug that caused RELR relocations to be
+## applied after packed relocations. This meant that resolvers referenced
+## IRELATIVE relocations in the packed relocation section could not read
+## globals with RELR relocations. Work around this by placing IRELATIVE in
+## .rela.plt
+
+# RUN: rm -rf %t && split-file %s %t && cd %t
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-android a.s -o a.o
+# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-android b.s -o b.o
+# RUN: ld.lld -shared b.o -o b.so
+# RUN: ld.lld --pack-dyn-relocs=android -z separate-loadable-segments a.o b.so -o a
+# RUN: llvm-readobj -r a | FileCheck %s
+# RUN: llvm-objdump -d a | FileCheck %s --check-prefix=ASM
+
+# CHECK:      .rela.plt {
+# CHECK-NEXT:   0x230020 R_AARCH64_JUMP_SLOT bar 0x0
+# CHECK-NEXT:   0x230028 R_AARCH64_IRELATIVE - {{.*}}
+# CHECK-NEXT: }
+
+# ASM:      <.iplt>:
+# ASM-NEXT: adrp    x16, 0x230000
+# ASM-NEXT: ldr     x17, [x16, #0x28]
+
+#--- a.s
+.text
+.type foo, %gnu_indirect_function
+.globl foo
+foo:
+  ret
+
+.globl _start
+_start:
+  bl foo
+  bl bar
+
+.data
+.quad .data
+
+#--- b.s
+.globl bar
+bar:
+  ret

``````````

</details>


https://github.com/llvm/llvm-project/pull/86751


More information about the llvm-commits mailing list