forked from OSchip/llvm-project
[ELF] Don't emit dynamic relocations with weak undef in writable sections
In processRelocAux(), our handling of 1) link-time constant and 2) weak undef is the same, so put them together to simplify the logic. This moves the weak undef code around. The result is that: in a writable section (or -z notext), we will no longer emit dynamic relocations for weak undefined symbols. The new behavior seems to match GNU linkers, and improves consistency with the case of a readonly section. The condition `!Config->Shared` was there probably because it is common for a -shared link not to specify full dependencies. Keep it now but we may revisit the decision in the future. gABI says: > The behavior of weak symbols in areas not specified by this document is > implementation defined. Weak symbols are intended primarily for use in > system software. Applications using weak symbols are unreliable since > changes in the runtime environment might cause the execution to fail. Reviewed By: ruiu Differential Revision: https://reviews.llvm.org/D63003 llvm-svn: 363399
This commit is contained in:
parent
a59bc6e589
commit
e05ca38101
|
@ -924,10 +924,19 @@ template <class ELFT, class RelTy>
|
||||||
static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
|
static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
|
||||||
uint64_t Offset, Symbol &Sym, const RelTy &Rel,
|
uint64_t Offset, Symbol &Sym, const RelTy &Rel,
|
||||||
int64_t Addend) {
|
int64_t Addend) {
|
||||||
if (isStaticLinkTimeConstant(Expr, Type, Sym, Sec, Offset)) {
|
// If the relocation is known to be a link-time constant, we know no dynamic
|
||||||
|
// relocation will be created, pass the control to relocateAlloc() or
|
||||||
|
// relocateNonAlloc() to resolve it.
|
||||||
|
//
|
||||||
|
// The behavior of an undefined weak reference is implementation defined. If
|
||||||
|
// the relocation is to a weak undef, and we are producing an executable, let
|
||||||
|
// relocate{,Non}Alloc() resolve it.
|
||||||
|
if (isStaticLinkTimeConstant(Expr, Type, Sym, Sec, Offset) ||
|
||||||
|
(!Config->Shared && Sym.isUndefWeak())) {
|
||||||
Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
|
Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanWrite = (Sec.Flags & SHF_WRITE) || !Config->ZText;
|
bool CanWrite = (Sec.Flags & SHF_WRITE) || !Config->ZText;
|
||||||
if (CanWrite) {
|
if (CanWrite) {
|
||||||
// FIXME Improve the way we handle absolute relocation types that will
|
// FIXME Improve the way we handle absolute relocation types that will
|
||||||
|
@ -967,13 +976,6 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the relocation is to a weak undef, and we are producing
|
|
||||||
// executable, give up on it and produce a non preemptible 0.
|
|
||||||
if (!Config->Shared && Sym.isUndefWeak()) {
|
|
||||||
Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Sym});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CanWrite && (Config->Pic && !isRelExpr(Expr))) {
|
if (!CanWrite && (Config->Pic && !isRelExpr(Expr))) {
|
||||||
error(
|
error(
|
||||||
"can't create dynamic relocation " + toString(Type) + " against " +
|
"can't create dynamic relocation " + toString(Type) + " against " +
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
# REQUIRES: x86
|
# REQUIRES: x86
|
||||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
|
||||||
# RUN: ld.lld %t.o -o %t --export-dynamic
|
# RUN: ld.lld %t.o -o %t --export-dynamic
|
||||||
# RUN: llvm-readobj -r %t | FileCheck %s
|
# RUN: llvm-readelf -r %t | FileCheck %s
|
||||||
|
|
||||||
# CHECK: R_X86_64_64 foobar 0x0
|
## gABI leaves the behavior of weak undefined references implementation defined.
|
||||||
|
## We choose to resolve it statically and not create a dynamic relocation for
|
||||||
|
## implementation simplicity. This also matches ld.bfd and gold.
|
||||||
|
|
||||||
|
# CHECK: no relocations
|
||||||
|
|
||||||
.global _start
|
.global _start
|
||||||
_start:
|
_start:
|
||||||
|
|
Loading…
Reference in New Issue