Skip to content

[ELF] --pack-dyn-relocs=android+relr: place IRELATIVE in .rela.plt #86751

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions lld/ELF/Relocations.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1659,10 +1659,17 @@ 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 by
// IRELATIVE relocations in the packed relocation section would read
// unrelocated globals with RELR relocations when
// --pack-relative-relocs=android+relr is enabled. 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;

Expand Down
49 changes: 49 additions & 0 deletions lld/test/ELF/pack-dyn-relocs-ifunc.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 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 by
## IRELATIVE relocations in the packed relocation section would read unrelocated
## globals when --pack-relative-relocs=android+relr is enabled. 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 -pie --pack-dyn-relocs=android+relr -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: .relr.dyn {
# CHECK-NEXT: 0x30000 R_AARCH64_RELATIVE -
# CHECK-NEXT: }
# CHECK: .rela.plt {
# CHECK-NEXT: 0x30020 R_AARCH64_JUMP_SLOT bar 0x0
# CHECK-NEXT: 0x30028 R_AARCH64_IRELATIVE - 0x10000
# CHECK-NEXT: }

# ASM: <.iplt>:
# ASM-NEXT: adrp x16, 0x30000
# ASM-NEXT: ldr x17, [x16, #0x28]
# ASM-NEXT: add x16, x16, #0x28
# ASM-NEXT: br x17

#--- a.s
.text
.type foo, %gnu_indirect_function
.globl foo
foo:
ret

.globl _start
_start:
bl foo
bl bar

.data
.balign 8
.quad .data

#--- b.s
.globl bar
bar:
ret