[PATCH] D35724: [ELF] - Fix missing relocation when linking executable with --unresolved-symbols=ignore-all

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 1 09:26:32 PDT 2017


LGTM.

Thanks!

George Rimar via Phabricator <reviews at reviews.llvm.org> writes:

> grimar updated this revision to Diff 109075.
> grimar added a comment.
>
> - Rebased, addressed comments.
>
>
> https://reviews.llvm.org/D35724
>
> Files:
>   ELF/Symbols.cpp
>   test/ELF/executable-undefined-ignoreall.s
>   test/ELF/executable-undefined-protected-ignoreall.s
>   test/ELF/no-inhibit-exec.s
>
>
> 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
> Index: ELF/Symbols.cpp
> ===================================================================
> --- ELF/Symbols.cpp
> +++ ELF/Symbols.cpp
> @@ -141,18 +141,23 @@
>    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;
>  
>    // Only default visibility symbols can be preempted.
>    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
> Index: ELF/Symbols.cpp
> ===================================================================
> --- ELF/Symbols.cpp
> +++ ELF/Symbols.cpp
> @@ -141,18 +141,23 @@
>    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;
>  
>    // Only default visibility symbols can be preempted.
>    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();
>  }
>  


More information about the llvm-commits mailing list