Skip to content

Commit 7b06bfc

Browse files
committed
[ELF] -pie: produce dynamic relocations for absolute relocations referencing undef weak
See the comment for my understanding of -no-pie and -shared expectation. -no-pie has freedom on choices. We choose dynamic relocations to be consistent with the handling of GOT-generating relocations. Note: GNU ld has arch-varying behaviors and its x86 -pie has a very complex rule: if there is at least one GOT-generating or PLT-generating relocation and -z dynamic-undefined-weak (enabled by default) is in effect, generate a dynamic relocation. We don't emulate its rule. Reviewed By: peter.smith Differential Revision: https://reviews.llvm.org/D105164
1 parent 5709842 commit 7b06bfc

File tree

2 files changed

+26
-8
lines changed

2 files changed

+26
-8
lines changed

lld/ELF/Relocations.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,11 +1147,18 @@ static void processRelocAux(InputSectionBase &sec, RelExpr expr, RelType type,
11471147
// relocation will be created, pass the control to relocateAlloc() or
11481148
// relocateNonAlloc() to resolve it.
11491149
//
1150-
// The behavior of an undefined weak reference is implementation defined. If
1151-
// the relocation is to a weak undef, and we are producing an executable, let
1152-
// relocate{,Non}Alloc() resolve it.
1150+
// The behavior of an undefined weak reference is implementation defined. For
1151+
// non-link-time constants, we resolve relocations statically (let
1152+
// relocate{,Non}Alloc() resolve them) for -no-pie and try producing dynamic
1153+
// relocations for -pie and -shared.
1154+
//
1155+
// The general expectation of -no-pie static linking is that there is no
1156+
// dynamic relocation (except IRELATIVE). Emitting dynamic relocations for
1157+
// -shared matches the spirit of its -z undefs default. -pie has freedom on
1158+
// choices, and we choose dynamic relocations to be consistent with the
1159+
// handling of GOT-generating relocations.
11531160
if (isStaticLinkTimeConstant(expr, type, sym, sec, offset) ||
1154-
(!config->shared && sym.isUndefWeak())) {
1161+
(!config->isPic && sym.isUndefWeak())) {
11551162
sec.relocations.push_back({expr, type, offset, addend, &sym});
11561163
return;
11571164
}

lld/test/ELF/weak-undef-rw.s

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
11
# REQUIRES: x86
22
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
33
# RUN: ld.lld %t.o -o %t --export-dynamic
4-
# RUN: llvm-readelf -r %t | FileCheck %s
4+
# RUN: llvm-readelf -r %t | FileCheck %s --check-prefix=NOPIC
5+
# RUN: ld.lld %t.o -o %t.pie -pie
6+
# RUN: llvm-readobj -r %t.pie | FileCheck %s --check-prefix=PIC
7+
# RUN: ld.lld %t.o -o %t.so -shared
8+
# RUN: llvm-readobj -r %t.so | FileCheck %s --check-prefix=PIC
59

610
## gABI leaves the behavior of weak undefined references implementation defined.
7-
## We choose to resolve it statically and not create a dynamic relocation for
8-
## implementation simplicity. This also matches ld.bfd and gold.
11+
## We choose to resolve them statically for -no-pie and produce dynamic relocations
12+
## for -pie and -shared.
13+
##
14+
## Note: Some ports of GNU ld support -z nodynamic-undefined-weak that we don't
15+
## implement.
916

10-
# CHECK: no relocations
17+
# NOPIC: no relocations
18+
19+
# PIC: .rela.dyn {
20+
# PIC-NEXT: R_X86_64_64 foobar 0x0
21+
# PIC-NEXT: }
1122

1223
.global _start
1324
_start:

0 commit comments

Comments
 (0)