[lld] r313372 - Keep some relocations with undefined weak symbols.

Rafael Avila de Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 15 14:58:53 PDT 2017


BTW, I have tried to change this to always create a dynamic symbol table
first and remove it in removeUnusedSyntheticSections if empty.

A change is that we would have a dynamic symbol table on otherwise
static programs if they had an undefined weak symbol. As far as I can
tell, that is harmless.

An annoying case is what to do with _DYNAMIC. The current patch has two
passes over the symbols. First checking if we need anything in the
dynamic symbol table. After that pass removeUnusedSyntheticSections can
remove the dynamic sections (.dynsym, .dynamic, etc) and we can decide
if _DYNAMIC should be added to the staic symbol table.

A wip patch is attached. Does anyone think this is a good idea?

And yet another option is to always have a .dynsym table. The extra cost
on static binaries would be really small, so this is tempting.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: t.diff
Type: text/x-patch
Size: 9031 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170915/8e68ba34/attachment.bin>
-------------- next part --------------

Cheers,
Rafael

Rafael Espindola via llvm-commits <llvm-commits at lists.llvm.org> writes:

> Author: rafael
> Date: Fri Sep 15 11:05:02 2017
> New Revision: 313372
>
> URL: http://llvm.org/viewvc/llvm-project?rev=313372&view=rev
> Log:
> Keep some relocations with undefined weak symbols.
>
> This fixes pr34301.
>
> As the bug points out, we want to keep some relocations with undefined
> weak symbols. This means that we cannot always claim that these
> symbols are not preemptible as we do now.
>
> Unfortunately, we cannot also just always claim that they are
> preemptible. Doing so would, for example, cause us to try to create a
> plt entry when we don't even have a dynamic symbol table.
>
> What almost works is to say that weak undefined symbols are
> preemptible if and only if we have a dynamic symbol table. Almost
> because we don't want to fail the build trying to create a copy
> relocation to a weak undefined.
>
> Added:
>     lld/trunk/test/ELF/weak-undef-val.s
> Modified:
>     lld/trunk/ELF/Config.h
>     lld/trunk/ELF/Driver.cpp
>     lld/trunk/ELF/Relocations.cpp
>     lld/trunk/ELF/Symbols.cpp
>     lld/trunk/ELF/Writer.cpp
>     lld/trunk/test/ELF/no-inhibit-exec.s
>     lld/trunk/test/ELF/pie-weak.s
>     lld/trunk/test/ELF/relocation-relative-weak.s
>     lld/trunk/test/ELF/weak-undef-export.s
>     lld/trunk/test/ELF/weak-undef.s
>
> Modified: lld/trunk/ELF/Config.h
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=313372&r1=313371&r2=313372&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Config.h (original)
> +++ lld/trunk/ELF/Config.h Fri Sep 15 11:05:02 2017
> @@ -127,6 +127,7 @@ struct Configuration {
>    bool GdbIndex;
>    bool GnuHash;
>    bool HasDynamicList = false;
> +  bool HasDynSymTab;
>    bool ICF;
>    bool MipsN32Abi = false;
>    bool NoGnuUnique;
>
> Modified: lld/trunk/ELF/Driver.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=313372&r1=313371&r2=313372&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Driver.cpp (original)
> +++ lld/trunk/ELF/Driver.cpp Fri Sep 15 11:05:02 2017
> @@ -1009,6 +1009,15 @@ template <class ELFT> void LinkerDriver:
>    for (InputFile *F : Files)
>      Symtab->addFile<ELFT>(F);
>  
> +  // Now that we have every file, we can decide if we will need a
> +  // dynamic symbol table.
> +  // We need one if we were asked to export dynamic symbols or if we are
> +  // producing a shared library.
> +  // We also need one if any shared libraries are used and for pie executables
> +  // (probably because the dynamic linker needs it).
> +  Config->HasDynSymTab = !SharedFile<ELFT>::Instances.empty() || Config->Pic ||
> +                         Config->ExportDynamic;
> +
>    // Some symbols (such as __ehdr_start) are defined lazily only when there
>    // are undefined symbols for them, so we add these to trigger that logic.
>    for (StringRef Sym : Script->Opt.ReferencedSymbols)
>
> Modified: lld/trunk/ELF/Relocations.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=313372&r1=313371&r2=313372&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Relocations.cpp (original)
> +++ lld/trunk/ELF/Relocations.cpp Fri Sep 15 11:05:02 2017
> @@ -568,8 +568,17 @@ static RelExpr adjustExpr(SymbolBody &Bo
>    if (IsWrite || isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, S, RelOff))
>      return Expr;
>  
> -  // This relocation would require the dynamic linker to write a value to read
> -  // only memory. We can hack around it if we are producing an executable and
> +  // If we got here we know that this relocation would require the dynamic
> +  // linker to write a value to read only memory.
> +
> +  // If the relocation is to a weak undef, give up on it and produce a
> +  // non preemptible 0.
> +  if (Body.isUndefWeak()) {
> +    Body.IsPreemptible = false;
> +    return Expr;
> +  }
> +
> +  // We can hack around it if we are producing an executable and
>    // the refered symbol can be preemepted to refer to the executable.
>    if (Config->Shared || (Config->Pic && !isRelExpr(Expr))) {
>      error("can't create dynamic relocation " + toString(Type) + " against " +
>
> Modified: lld/trunk/ELF/Symbols.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=313372&r1=313371&r2=313372&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Symbols.cpp (original)
> +++ lld/trunk/ELF/Symbols.cpp Fri Sep 15 11:05:02 2017
> @@ -344,10 +344,10 @@ uint8_t Symbol::computeBinding() const {
>  }
>  
>  bool Symbol::includeInDynsym() const {
> +  if (!Config->HasDynSymTab)
> +    return false;
>    if (computeBinding() == STB_LOCAL)
>      return false;
> -  if (body()->isUndefWeak())
> -    return Config->Shared;
>    if (!body()->isInCurrentDSO())
>      return true;
>    return ExportDynamic;
>
> Modified: lld/trunk/ELF/Writer.cpp
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=313372&r1=313371&r2=313372&view=diff
> ==============================================================================
> --- lld/trunk/ELF/Writer.cpp (original)
> +++ lld/trunk/ELF/Writer.cpp Fri Sep 15 11:05:02 2017
> @@ -299,10 +299,8 @@ template <class ELFT> void Writer<ELFT>:
>    Add(InX::BssRelRo);
>  
>    // Add MIPS-specific sections.
> -  bool HasDynSymTab = !SharedFile<ELFT>::Instances.empty() || Config->Pic ||
> -                      Config->ExportDynamic;
>    if (Config->EMachine == EM_MIPS) {
> -    if (!Config->Shared && HasDynSymTab) {
> +    if (!Config->Shared && Config->HasDynSymTab) {
>        InX::MipsRldMap = make<MipsRldMapSection>();
>        Add(InX::MipsRldMap);
>      }
> @@ -314,7 +312,7 @@ template <class ELFT> void Writer<ELFT>:
>        Add(Sec);
>    }
>  
> -  if (HasDynSymTab) {
> +  if (Config->HasDynSymTab) {
>      InX::DynSymTab = make<SymbolTableSection<ELFT>>(*InX::DynStrTab);
>      Add(InX::DynSymTab);
>  
>
> Modified: lld/trunk/test/ELF/no-inhibit-exec.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/no-inhibit-exec.s?rev=313372&r1=313371&r2=313372&view=diff
> ==============================================================================
> --- lld/trunk/test/ELF/no-inhibit-exec.s (original)
> +++ lld/trunk/test/ELF/no-inhibit-exec.s Fri Sep 15 11:05:02 2017
> @@ -7,7 +7,7 @@
>  
>  # CHECK: Disassembly of section .text:
>  # CHECK-NEXT: _start
> -# CHECK-NEXT: 201000: {{.*}} callq 0
> +# CHECK-NEXT: 201000: {{.*}} callq -2101253
>  
>  # RELOC:      Relocations [
>  # RELOC-NEXT: ]
>
> Modified: lld/trunk/test/ELF/pie-weak.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/pie-weak.s?rev=313372&r1=313371&r2=313372&view=diff
> ==============================================================================
> --- lld/trunk/test/ELF/pie-weak.s (original)
> +++ lld/trunk/test/ELF/pie-weak.s Fri Sep 15 11:05:02 2017
> @@ -5,6 +5,9 @@
>  # RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
>  
>  # RELOCS:      Relocations [
> +# RELOCS-NEXT:   Section ({{.*}}) .rela.dyn {
> +# RELOCS-NEXT:     R_X86_64_GLOB_DAT foo 0x0
> +# RELOCS-NEXT:   }
>  # RELOCS-NEXT: ]
>  
>  .weak foo
> @@ -12,6 +15,6 @@
>  .globl _start
>  _start:
>  # DISASM: _start:
> -# DISASM-NEXT: 1000: 48 8b 05 69 10 00 00 movq 4201(%rip), %rax
> +# DISASM-NEXT: 1000: 48 8b 05 99 10 00 00 movq 4249(%rip), %rax
>  #                                              ^ .got - (.text + 7)
>  mov foo at gotpcrel(%rip), %rax
>
> Modified: lld/trunk/test/ELF/relocation-relative-weak.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/relocation-relative-weak.s?rev=313372&r1=313371&r2=313372&view=diff
> ==============================================================================
> --- lld/trunk/test/ELF/relocation-relative-weak.s (original)
> +++ lld/trunk/test/ELF/relocation-relative-weak.s Fri Sep 15 11:05:02 2017
> @@ -4,6 +4,7 @@
>  # RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
>  
>  # CHECK:      Dynamic Relocations {
> +# CHECK-NEXT:   0x2018 R_X86_64_JUMP_SLOT w 0x0
>  # CHECK-NEXT: }
>  
>  .globl _start
>
> Modified: lld/trunk/test/ELF/weak-undef-export.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/weak-undef-export.s?rev=313372&r1=313371&r2=313372&view=diff
> ==============================================================================
> --- lld/trunk/test/ELF/weak-undef-export.s (original)
> +++ lld/trunk/test/ELF/weak-undef-export.s Fri Sep 15 11:05:02 2017
> @@ -16,6 +16,15 @@
>  # CHECK-NEXT:     Other: 0
>  # CHECK-NEXT:     Section: Undefined (0x0)
>  # CHECK-NEXT:   }
> +# CHECK-NEXT:   Symbol {
> +# CHECK-NEXT:     Name: foo@ (1)
> +# CHECK-NEXT:     Value: 0x0
> +# CHECK-NEXT:     Size: 0
> +# CHECK-NEXT:     Binding: Weak (0x2)
> +# CHECK-NEXT:     Type: None (0x0)
> +# CHECK-NEXT:     Other: 0
> +# CHECK-NEXT:     Section: Undefined (0x0)
> +# CHECK-NEXT:  }
>  # CHECK-NEXT: ]
>  
>          .weak foo
>
> Added: lld/trunk/test/ELF/weak-undef-val.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/weak-undef-val.s?rev=313372&view=auto
> ==============================================================================
> --- lld/trunk/test/ELF/weak-undef-val.s (added)
> +++ lld/trunk/test/ELF/weak-undef-val.s Fri Sep 15 11:05:02 2017
> @@ -0,0 +1,26 @@
> +# 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 -s -section-data %t | FileCheck %s
> +
> +# CHECK:      Name: .text
> +# CHECK-NEXT: Type: SHT_PROGBITS
> +# CHECK-NEXT: Flags [
> +# CHECK-NEXT:   SHF_ALLOC
> +# CHECK-NEXT:   SHF_EXECINSTR
> +# CHECK-NEXT: ]
> +# CHECK-NEXT: Address: 0x201000
> +# CHECK-NEXT: Offset:
> +# CHECK-NEXT: Size:
> +# CHECK-NEXT: Link:
> +# CHECK-NEXT: Info:
> +# CHECK-NEXT: AddressAlignment:
> +# CHECK-NEXT: EntrySize:
> +# CHECK-NEXT: SectionData (
> +# CHECK-NEXT:   0000: 00F0DFFF                             |
> +# CHECK-NEXT: )
> +
> +        .global _start
> +_start:
> +        .weak foobar
> +        .long foobar - .
>
> Modified: lld/trunk/test/ELF/weak-undef.s
> URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/weak-undef.s?rev=313372&r1=313371&r2=313372&view=diff
> ==============================================================================
> --- lld/trunk/test/ELF/weak-undef.s (original)
> +++ lld/trunk/test/ELF/weak-undef.s Fri Sep 15 11:05:02 2017
> @@ -13,6 +13,15 @@
>  # CHECK-NEXT:     Other: 0
>  # CHECK-NEXT:     Section: Undefined (0x0)
>  # CHECK-NEXT:   }
> +# CHECK-NEXT:   Symbol {
> +# CHECK-NEXT:     Name: foo@
> +# CHECK-NEXT:     Value: 0x0
> +# CHECK-NEXT:     Size: 0
> +# CHECK-NEXT:     Binding: Weak
> +# CHECK-NEXT:     Type: None
> +# CHECK-NEXT:     Other: 0
> +# CHECK-NEXT:     Section: Undefined
> +# CHECK-NEXT:   }
>  # CHECK-NEXT: ]
>  
>  .weak foo
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list