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

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Fri Sep 15 11:05:02 PDT 2017


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




More information about the llvm-commits mailing list