svn commit: r326831 - head/contrib/llvm/tools/lld/ELF

Dimitry Andric dim at FreeBSD.org
Wed Dec 13 19:03:50 UTC 2017


Author: dim
Date: Wed Dec 13 19:03:48 2017
New Revision: 326831
URL: https://svnweb.freebsd.org/changeset/base/326831

Log:
  Pull in r315334 from upstream lld trunk (by Rafael Espindola):
  
    Don't create a dummy __tls_get_addr.
  
    We just don't need one with the current setup.
  
    We only error on undefined references that are used by some
    relocation.
  
    If we managed to relax all uses of __tls_get_addr, no relocation uses
    it and we don't produce an error.
  
    This is less code and fixes the case were we fail to relax. Before we
    would produce a broken output, but now we produce an error.
  
  Pull in r320390 from upstream lld trunk (by Rafael Espindola):
  
    Create reserved symbols early so they can be versioned.
  
    This fixes pr35570.
  
    We were creating these symbols after parsing version scripts, so they
    could not be versioned.
  
    We cannot move the version script parsing later because we need it for
    lto.
  
    One option is to move both addReservedSymbols and
    createSyntheticSections earlier. The disadvantage is that some
    sections created by createSyntheticSections replace other input
    sections. For example, gdb index replaces .debug_gnu_pubnames, so it
    wants to run after gc sections so that it can set S->Live to false.
  
    What this patch does instead is to move just the ElfHeader creation
    early.
  
  Pull in r320412 from upstream lld trunk (by Rafael Espindola):
  
    Handle symbols pointing to output sections.
  
    Now that gc sections runs after linker defined symbols are added it
    can see symbols that point to an OutputSection.
  
    Should fix a bot failure.
  
  Pull in r320431 from upstream lld trunk (by Peter Collingbourne):
  
    ELF: Do not follow relocation edges to output sections during GC.
  
    This fixes an assertion error introduced by r320390.
  
    Differential Revision: https://reviews.llvm.org/D41095
  
  Together these fix handling of reserved symbols, in particular _end,
  which is needed to make brk(2) and sbrk(2) work correctly.  This
  unbreaks the emacs ports on amd64, and also appears to unbreak most of
  world on i386.
  
  MFC after:	2 weeks
  Differential Revision: https://reviews.freebsd.org/D13466

Modified:
  head/contrib/llvm/tools/lld/ELF/Driver.cpp
  head/contrib/llvm/tools/lld/ELF/MarkLive.cpp
  head/contrib/llvm/tools/lld/ELF/Writer.cpp
  head/contrib/llvm/tools/lld/ELF/Writer.h

Modified: head/contrib/llvm/tools/lld/ELF/Driver.cpp
==============================================================================
--- head/contrib/llvm/tools/lld/ELF/Driver.cpp	Wed Dec 13 18:38:02 2017	(r326830)
+++ head/contrib/llvm/tools/lld/ELF/Driver.cpp	Wed Dec 13 19:03:48 2017	(r326831)
@@ -1010,6 +1010,15 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
   if (Args.hasArg(OPT_exclude_libs))
     excludeLibs(Args, Files);
 
+  // Create ElfHeader early. We need a dummy section in
+  // addReservedSymbols to mark the created symbols as not absolute.
+  Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
+  Out::ElfHeader->Size = sizeof(typename ELFT::Ehdr);
+
+  // We need to create some reserved symbols such as _end. Create them.
+  if (!Config->Relocatable)
+    addReservedSymbols<ELFT>();
+
   // Apply version scripts.
   Symtab.scanVersionScript();
 

Modified: head/contrib/llvm/tools/lld/ELF/MarkLive.cpp
==============================================================================
--- head/contrib/llvm/tools/lld/ELF/MarkLive.cpp	Wed Dec 13 18:38:02 2017	(r326830)
+++ head/contrib/llvm/tools/lld/ELF/MarkLive.cpp	Wed Dec 13 19:03:48 2017	(r326831)
@@ -73,12 +73,13 @@ static void resolveReloc(InputSectionBase &Sec, RelT &
                          std::function<void(ResolvedReloc)> Fn) {
   SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
   if (auto *D = dyn_cast<DefinedRegular>(&B)) {
-    if (!D->Section)
+    auto *RelSec = dyn_cast_or_null<InputSectionBase>(D->Section);
+    if (!RelSec)
       return;
     typename ELFT::uint Offset = D->Value;
     if (D->isSection())
       Offset += getAddend<ELFT>(Sec, Rel);
-    Fn({cast<InputSectionBase>(D->Section), Offset});
+    Fn({RelSec, Offset});
   } else if (auto *U = dyn_cast<Undefined>(&B)) {
     for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
       Fn({Sec, 0});
@@ -220,7 +221,7 @@ template <class ELFT> void elf::markLive() {
 
   auto MarkSymbol = [&](const SymbolBody *Sym) {
     if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
-      if (auto *IS = cast_or_null<InputSectionBase>(D->Section))
+      if (auto *IS = dyn_cast_or_null<InputSectionBase>(D->Section))
         Enqueue({IS, D->Value});
   };
 

Modified: head/contrib/llvm/tools/lld/ELF/Writer.cpp
==============================================================================
--- head/contrib/llvm/tools/lld/ELF/Writer.cpp	Wed Dec 13 18:38:02 2017	(r326830)
+++ head/contrib/llvm/tools/lld/ELF/Writer.cpp	Wed Dec 13 19:03:48 2017	(r326831)
@@ -50,7 +50,6 @@ template <class ELFT> class Writer { (private)
   void createSyntheticSections();
   void copyLocalSymbols();
   void addSectionSymbols();
-  void addReservedSymbols();
   void createSections();
   void forEachRelSec(std::function<void(InputSectionBase &)> Fn);
   void sortSections();
@@ -168,10 +167,6 @@ template <class ELFT> void Writer<ELFT>::run() {
   if (!Config->Relocatable)
     combineEhFrameSections<ELFT>();
 
-  // We need to create some reserved symbols such as _end. Create them.
-  if (!Config->Relocatable)
-    addReservedSymbols();
-
   // Create output sections.
   if (Script->Opt.HasSections) {
     // If linker script contains SECTIONS commands, let it create sections.
@@ -286,8 +281,6 @@ template <class ELFT> void Writer<ELFT>::createSynthet
       Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
   InX::ShStrTab = make<StringTableSection>(".shstrtab", false);
 
-  Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
-  Out::ElfHeader->Size = sizeof(Elf_Ehdr);
   Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
   Out::ProgramHeaders->updateAlignment(Config->Wordsize);
 
@@ -796,7 +789,7 @@ template <class ELFT> void Writer<ELFT>::addRelIpltSym
 
 // The linker is expected to define some symbols depending on
 // the linking result. This function defines such symbols.
-template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
+template <class ELFT> void elf::addReservedSymbols() {
   if (Config->EMachine == EM_MIPS) {
     // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
     // so that it points to an absolute address which by default is relative
@@ -820,21 +813,9 @@ template <class ELFT> void Writer<ELFT>::addReservedSy
           Symtab<ELFT>::X->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_LOCAL);
   }
 
-  // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
-  // be at some offset from the base of the .got section, usually 0 or the end
-  // of the .got
-  InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
-                                          : cast<InputSection>(InX::Got);
   ElfSym::GlobalOffsetTable = addOptionalRegular<ELFT>(
-      "_GLOBAL_OFFSET_TABLE_", GotSection, Target->GotBaseSymOff);
+      "_GLOBAL_OFFSET_TABLE_", Out::ElfHeader, Target->GotBaseSymOff);
 
-  // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For
-  // static linking the linker is required to optimize away any references to
-  // __tls_get_addr, so it's not defined anywhere. Create a hidden definition
-  // to avoid the undefined symbol error.
-  if (!InX::DynSymTab)
-    Symtab<ELFT>::X->addIgnored("__tls_get_addr");
-
   // __ehdr_start is the location of ELF file headers. Note that we define
   // this symbol unconditionally even when using a linker script, which
   // differs from the behavior implemented by GNU linker which only define
@@ -1721,6 +1702,15 @@ static uint16_t getELFType() {
 // to each section. This function fixes some predefined
 // symbol values that depend on section address and size.
 template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() {
+  if (ElfSym::GlobalOffsetTable) {
+    // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
+    // be at some offset from the base of the .got section, usually 0 or the end
+    // of the .got
+    InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
+                                            : cast<InputSection>(InX::Got);
+    ElfSym::GlobalOffsetTable->Section = GotSection;
+  }
+
   // _etext is the first location after the last read-only loadable segment.
   // _edata is the first location after the last read-write loadable segment.
   // _end is the first location after the uninitialized data region.
@@ -1911,3 +1901,8 @@ template void elf::writeResult<ELF32LE>();
 template void elf::writeResult<ELF32BE>();
 template void elf::writeResult<ELF64LE>();
 template void elf::writeResult<ELF64BE>();
+
+template void elf::addReservedSymbols<ELF32LE>();
+template void elf::addReservedSymbols<ELF32BE>();
+template void elf::addReservedSymbols<ELF64LE>();
+template void elf::addReservedSymbols<ELF64BE>();

Modified: head/contrib/llvm/tools/lld/ELF/Writer.h
==============================================================================
--- head/contrib/llvm/tools/lld/ELF/Writer.h	Wed Dec 13 18:38:02 2017	(r326830)
+++ head/contrib/llvm/tools/lld/ELF/Writer.h	Wed Dec 13 19:03:48 2017	(r326831)
@@ -47,6 +47,7 @@ struct PhdrEntry {
   bool HasLMA = false;
 };
 
+template <class ELFT> void addReservedSymbols();
 llvm::StringRef getOutputSectionName(llvm::StringRef Name);
 
 template <class ELFT> uint32_t getMipsEFlags();


More information about the svn-src-head mailing list