Skip to content

Commit c335acc

Browse files
authored
[ELF] --pack-dyn-relocs=android+relr: place IRELATIVE in .rela.plt (#86751)
Current Bionic processes relocations in this order: * DT_ANDROID_REL[A] * DT_RELR * DT_REL[A] * DT_JMPREL If an IRELATIVE relocation is in DT_ANDROID_REL[A], it would read unrelocated (incorrect) global variables associated with RELR when --pack-dyn-relocs=android+relr is enabled. Work around this by placing IRELATIVE in .rel[a].plt (DT_JMPREL). Link: https://r.android.com/3014185
1 parent 1c96580 commit c335acc

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

lld/ELF/Relocations.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,10 +1659,17 @@ static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
16591659
// original section/value pairs. For non-GOT non-PLT relocation case below, we
16601660
// may alter section/value, so create a copy of the symbol to make
16611661
// section/value fixed.
1662+
//
1663+
// Prior to Android V, there was a bug that caused RELR relocations to be
1664+
// applied after packed relocations. This meant that resolvers referenced by
1665+
// IRELATIVE relocations in the packed relocation section would read
1666+
// unrelocated globals with RELR relocations when
1667+
// --pack-relative-relocs=android+relr is enabled. Work around this by placing
1668+
// IRELATIVE in .rela.plt.
16621669
auto *directSym = makeDefined(cast<Defined>(sym));
16631670
directSym->allocateAux();
1664-
addPltEntry(*in.iplt, *in.igotPlt, *mainPart->relaDyn, target->iRelativeRel,
1665-
*directSym);
1671+
auto &dyn = config->androidPackDynRelocs ? *in.relaPlt : *mainPart->relaDyn;
1672+
addPltEntry(*in.iplt, *in.igotPlt, dyn, target->iRelativeRel, *directSym);
16661673
sym.allocateAux();
16671674
symAux.back().pltIdx = symAux[directSym->auxIdx].pltIdx;
16681675

lld/test/ELF/pack-dyn-relocs-ifunc.s

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# REQUIRES: aarch64
2+
## Prior to Android V, there was a bug that caused RELR relocations to be
3+
## applied after packed relocations. This meant that resolvers referenced by
4+
## IRELATIVE relocations in the packed relocation section would read unrelocated
5+
## globals when --pack-relative-relocs=android+relr is enabled. Work around this
6+
## by placing IRELATIVE in .rela.plt.
7+
8+
# RUN: rm -rf %t && split-file %s %t && cd %t
9+
# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-android a.s -o a.o
10+
# RUN: llvm-mc -filetype=obj -triple=aarch64-linux-android b.s -o b.o
11+
# RUN: ld.lld -shared b.o -o b.so
12+
# RUN: ld.lld -pie --pack-dyn-relocs=android+relr -z separate-loadable-segments a.o b.so -o a
13+
# RUN: llvm-readobj -r a | FileCheck %s
14+
# RUN: llvm-objdump -d a | FileCheck %s --check-prefix=ASM
15+
16+
# CHECK: .relr.dyn {
17+
# CHECK-NEXT: 0x30000 R_AARCH64_RELATIVE -
18+
# CHECK-NEXT: }
19+
# CHECK: .rela.plt {
20+
# CHECK-NEXT: 0x30020 R_AARCH64_JUMP_SLOT bar 0x0
21+
# CHECK-NEXT: 0x30028 R_AARCH64_IRELATIVE - 0x10000
22+
# CHECK-NEXT: }
23+
24+
# ASM: <.iplt>:
25+
# ASM-NEXT: adrp x16, 0x30000
26+
# ASM-NEXT: ldr x17, [x16, #0x28]
27+
# ASM-NEXT: add x16, x16, #0x28
28+
# ASM-NEXT: br x17
29+
30+
#--- a.s
31+
.text
32+
.type foo, %gnu_indirect_function
33+
.globl foo
34+
foo:
35+
ret
36+
37+
.globl _start
38+
_start:
39+
bl foo
40+
bl bar
41+
42+
.data
43+
.balign 8
44+
.quad .data
45+
46+
#--- b.s
47+
.globl bar
48+
bar:
49+
ret

0 commit comments

Comments
 (0)