Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -924,10 +924,19 @@ static void processRelocAux(InputSectionBase &Sec, RelExpr Expr, RelType Type, uint64_t Offset, Symbol &Sym, const RelTy &Rel, 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}); return; } + bool CanWrite = (Sec.Flags & SHF_WRITE) || !Config->ZText; if (CanWrite) { // FIXME Improve the way we handle absolute relocation types that will @@ -967,13 +976,6 @@ } } - // 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))) { error( "can't create dynamic relocation " + toString(Type) + " against " + Index: lld/trunk/test/ELF/weak-undef-rw.s =================================================================== --- lld/trunk/test/ELF/weak-undef-rw.s +++ lld/trunk/test/ELF/weak-undef-rw.s @@ -1,9 +1,13 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # 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 _start: