Index: lld/trunk/ELF/Symbols.cpp =================================================================== --- lld/trunk/ELF/Symbols.cpp +++ lld/trunk/ELF/Symbols.cpp @@ -141,10 +141,6 @@ if (isShared()) return !NeedsCopy && !NeedsPltAddr; - // That's all that can be preempted in a non-DSO. - if (!Config->Shared) - return false; - // Only symbols that appear in dynsym can be preempted. if (!symbol()->includeInDynsym()) return false; @@ -153,6 +149,15 @@ if (symbol()->Visibility != STV_DEFAULT) return false; + // Undefined symbols in non-DSOs are usually just an error, so it + // doesn't matter whether we return true or false here. However, if + // -unresolved-symbols=ignore-all is specified, undefined symbols in + // executables are automatically exported so that the runtime linker + // can try to resolve them. In that case, they is preemptible. So, we + // return true for an undefined symbol in case the option is specified. + if (!Config->Shared) + return isUndefined(); + // -Bsymbolic means that definitions are not preempted. if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc())) return !isDefined(); @@ -357,8 +362,11 @@ bool Symbol::includeInDynsym() const { if (computeBinding() == STB_LOCAL) return false; - return ExportDynamic || body()->isShared() || - (body()->isUndefined() && Config->Shared); + if (ExportDynamic || body()->isShared()) + return true; + if (!body()->isUndefined()) + return false; + return Config->Shared || !body()->symbol()->isWeak(); } // Print out a log message for --trace-symbol. Index: lld/trunk/test/ELF/executable-undefined-ignoreall.s =================================================================== --- lld/trunk/test/ELF/executable-undefined-ignoreall.s +++ lld/trunk/test/ELF/executable-undefined-ignoreall.s @@ -0,0 +1,13 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld %t -o %tout --unresolved-symbols=ignore-all -pie +# RUN: llvm-readobj -r %tout | FileCheck %s + +# CHECK: Relocations [ +# CHECK-NEXT: Section ({{.*}}) .rela.plt { +# CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT foo 0x0 +# CHECK-NEXT: } +# CHECK-NEXT: ] + +_start: +callq foo@PLT Index: lld/trunk/test/ELF/executable-undefined-protected-ignoreall.s =================================================================== --- lld/trunk/test/ELF/executable-undefined-protected-ignoreall.s +++ lld/trunk/test/ELF/executable-undefined-protected-ignoreall.s @@ -0,0 +1,8 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: not ld.lld %t -o %tout --unresolved-symbols=ignore-all -pie 2>&1 | FileCheck %s +# CHECK: error: undefined symbol: foo + +.protected foo +_start: +callq foo@PLT Index: lld/trunk/test/ELF/no-inhibit-exec.s =================================================================== --- lld/trunk/test/ELF/no-inhibit-exec.s +++ lld/trunk/test/ELF/no-inhibit-exec.s @@ -2,11 +2,15 @@ # RUN: not ld.lld %t -o %t2 # RUN: ld.lld %t --noinhibit-exec -o %t2 # RUN: llvm-objdump -d %t2 | FileCheck %s +# RUN: llvm-readobj -r %t2 | FileCheck %s --check-prefix=RELOC # REQUIRES: x86 # CHECK: Disassembly of section .text: # CHECK-NEXT: _start -# CHECK-NEXT: 201000: {{.*}} callq -2101253 +# CHECK-NEXT: 201000: {{.*}} callq 0 + +# RELOC: Relocations [ +# RELOC: ] # next code will not link without noinhibit-exec flag # because of undefined symbol _bar