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(); + // -Bsymbolic means that definitions are not preempted. if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc())) return !isDefined(); @@ -358,7 +363,7 @@ if (computeBinding() == STB_LOCAL) return false; if (body()->isUndefined()) - return Config->Shared; + return Config->Shared || !body()->symbol()->isWeak(); return ExportDynamic || body()->isShared(); } 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