Index: ELF/Symbols.cpp =================================================================== --- ELF/Symbols.cpp +++ 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() && !symbol()->isWeak(); + // -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: test/ELF/no-inhibit-exec.s =================================================================== --- test/ELF/no-inhibit-exec.s +++ 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: ] # next code will not link without noinhibit-exec flag # because of undefined symbol _bar