svn commit: r327130 - in vendor/lld/dist: . COFF ELF ELF/Arch test/COFF test/ELF test/ELF/Inputs test/ELF/linkerscript test/wasm test/wasm/Inputs wasm

Dimitry Andric dim at FreeBSD.org
Sun Dec 24 01:00:54 UTC 2017


Author: dim
Date: Sun Dec 24 01:00:50 2017
New Revision: 327130
URL: https://svnweb.freebsd.org/changeset/base/327130

Log:
  Vendor import of lld trunk r321414:
  https://llvm.org/svn/llvm-project/lld/trunk@321414

Added:
  vendor/lld/dist/test/ELF/Inputs/znotext-plt-relocations.s   (contents, props changed)
  vendor/lld/dist/test/ELF/arm-exidx-dedup-and-sentinel.s   (contents, props changed)
  vendor/lld/dist/test/ELF/i386-tls-initial-exec-local.s   (contents, props changed)
  vendor/lld/dist/test/ELF/znotext-plt-relocations.s   (contents, props changed)
  vendor/lld/dist/test/wasm/Inputs/global-ctor-dtor.ll
  vendor/lld/dist/test/wasm/init-fini.ll
Modified:
  vendor/lld/dist/COFF/DLL.cpp
  vendor/lld/dist/ELF/AArch64ErrataFix.cpp
  vendor/lld/dist/ELF/Arch/ARM.cpp
  vendor/lld/dist/ELF/Driver.cpp
  vendor/lld/dist/ELF/InputFiles.cpp
  vendor/lld/dist/ELF/InputFiles.h
  vendor/lld/dist/ELF/InputSection.cpp
  vendor/lld/dist/ELF/InputSection.h
  vendor/lld/dist/ELF/MarkLive.cpp
  vendor/lld/dist/ELF/Relocations.cpp
  vendor/lld/dist/ELF/ScriptParser.cpp
  vendor/lld/dist/ELF/SymbolTable.cpp
  vendor/lld/dist/ELF/SymbolTable.h
  vendor/lld/dist/ELF/Symbols.cpp
  vendor/lld/dist/ELF/Symbols.h
  vendor/lld/dist/ELF/SyntheticSections.cpp
  vendor/lld/dist/ELF/SyntheticSections.h
  vendor/lld/dist/ELF/Target.cpp
  vendor/lld/dist/ELF/Target.h
  vendor/lld/dist/ELF/Thunks.cpp
  vendor/lld/dist/ELF/Writer.cpp
  vendor/lld/dist/ELF/Writer.h
  vendor/lld/dist/README.md
  vendor/lld/dist/test/COFF/export-armnt.yaml
  vendor/lld/dist/test/COFF/lto.ll
  vendor/lld/dist/test/ELF/i386-got-value.s
  vendor/lld/dist/test/ELF/linkerscript/arm-exidx-sentinel-and-assignment.s
  vendor/lld/dist/test/ELF/linkerscript/operators.s
  vendor/lld/dist/test/wasm/Inputs/weak-alias.ll
  vendor/lld/dist/test/wasm/Inputs/weak-symbol1.ll
  vendor/lld/dist/test/wasm/Inputs/weak-symbol2.ll
  vendor/lld/dist/test/wasm/archive.ll
  vendor/lld/dist/test/wasm/call-indirect.ll
  vendor/lld/dist/test/wasm/conflict.test
  vendor/lld/dist/test/wasm/data-layout.ll
  vendor/lld/dist/test/wasm/entry.ll
  vendor/lld/dist/test/wasm/function-imports-first.ll
  vendor/lld/dist/test/wasm/function-imports.ll
  vendor/lld/dist/test/wasm/function-index.test
  vendor/lld/dist/test/wasm/import-memory.test
  vendor/lld/dist/test/wasm/invalid-stack-size.test
  vendor/lld/dist/test/wasm/local-symbols.ll
  vendor/lld/dist/test/wasm/many-functions.ll
  vendor/lld/dist/test/wasm/relocatable.ll
  vendor/lld/dist/test/wasm/signature-mismatch.ll
  vendor/lld/dist/test/wasm/stack-pointer.ll
  vendor/lld/dist/test/wasm/strip-debug.test
  vendor/lld/dist/test/wasm/symbol-type-mismatch.ll
  vendor/lld/dist/test/wasm/undefined-entry.test
  vendor/lld/dist/test/wasm/undefined.ll
  vendor/lld/dist/test/wasm/version.ll
  vendor/lld/dist/test/wasm/weak-alias-overide.ll
  vendor/lld/dist/test/wasm/weak-alias.ll
  vendor/lld/dist/test/wasm/weak-external.ll
  vendor/lld/dist/test/wasm/weak-symbols.ll
  vendor/lld/dist/wasm/InputFiles.cpp
  vendor/lld/dist/wasm/InputSegment.h
  vendor/lld/dist/wasm/OutputSections.cpp
  vendor/lld/dist/wasm/OutputSections.h
  vendor/lld/dist/wasm/OutputSegment.h
  vendor/lld/dist/wasm/SymbolTable.cpp
  vendor/lld/dist/wasm/SymbolTable.h
  vendor/lld/dist/wasm/Writer.cpp

Modified: vendor/lld/dist/COFF/DLL.cpp
==============================================================================
--- vendor/lld/dist/COFF/DLL.cpp	Sun Dec 24 01:00:48 2017	(r327129)
+++ vendor/lld/dist/COFF/DLL.cpp	Sun Dec 24 01:00:50 2017	(r327130)
@@ -362,12 +362,12 @@ class AddressTableChunk : public Chunk { (public)
   size_t getSize() const override { return Size * 4; }
 
   void writeTo(uint8_t *Buf) const override {
-    uint32_t Bit = 0;
-    // Pointer to thumb code must have the LSB set, so adjust it.
-    if (Config->Machine == ARMNT)
-      Bit = 1;
-    for (Export &E : Config->Exports) {
+    for (const Export &E : Config->Exports) {
       uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
+      uint32_t Bit = 0;
+      // Pointer to thumb code must have the LSB set, so adjust it.
+      if (Config->Machine == ARMNT && !E.Data)
+        Bit = 1;
       if (E.ForwardChunk) {
         write32le(P, E.ForwardChunk->getRVA() | Bit);
       } else {

Modified: vendor/lld/dist/ELF/AArch64ErrataFix.cpp
==============================================================================
--- vendor/lld/dist/ELF/AArch64ErrataFix.cpp	Sun Dec 24 01:00:48 2017	(r327129)
+++ vendor/lld/dist/ELF/AArch64ErrataFix.cpp	Sun Dec 24 01:00:50 2017	(r327130)
@@ -400,8 +400,8 @@ lld::elf::Patch843419Section::Patch843419Section(Input
   this->Parent = P->getParent();
   PatchSym = addSyntheticLocal(
       Saver.save("__CortexA53843419_" + utohexstr(getLDSTAddr())), STT_FUNC, 0,
-      getSize(), this);
-  addSyntheticLocal(Saver.save("$x"), STT_NOTYPE, 0, 0, this);
+      getSize(), *this);
+  addSyntheticLocal(Saver.save("$x"), STT_NOTYPE, 0, 0, *this);
 }
 
 uint64_t lld::elf::Patch843419Section::getLDSTAddr() const {

Modified: vendor/lld/dist/ELF/Arch/ARM.cpp
==============================================================================
--- vendor/lld/dist/ELF/Arch/ARM.cpp	Sun Dec 24 01:00:48 2017	(r327129)
+++ vendor/lld/dist/ELF/Arch/ARM.cpp	Sun Dec 24 01:00:50 2017	(r327130)
@@ -37,8 +37,8 @@ class ARM final : public TargetInfo { (public)
   void writePltHeader(uint8_t *Buf) const override;
   void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
                 int32_t Index, unsigned RelOff) const override;
-  void addPltSymbols(InputSectionBase *IS, uint64_t Off) const override;
-  void addPltHeaderSymbols(InputSectionBase *ISD) const override;
+  void addPltSymbols(InputSection &IS, uint64_t Off) const override;
+  void addPltHeaderSymbols(InputSection &ISD) const override;
   bool needsThunk(RelExpr Expr, RelType Type, const InputFile *File,
                   uint64_t BranchAddr, const Symbol &S) const override;
   bool inBranchRange(RelType Type, uint64_t Src, uint64_t Dst) const override;
@@ -184,7 +184,7 @@ void ARM::writeIgotPlt(uint8_t *Buf, const Symbol &S) 
   write32le(Buf, S.getVA());
 }
 
-// Long form PLT Heade that does not have any restrictions on the displacement
+// Long form PLT Header that does not have any restrictions on the displacement
 // of the .plt from the .plt.got.
 static void writePltHeaderLong(uint8_t *Buf) {
   const uint8_t PltData[] = {
@@ -232,8 +232,7 @@ void ARM::writePltHeader(uint8_t *Buf) const {
   write32le(Buf + 28, TrapInstr);
 }
 
-void ARM::addPltHeaderSymbols(InputSectionBase *ISD) const {
-  auto *IS = cast<InputSection>(ISD);
+void ARM::addPltHeaderSymbols(InputSection &IS) const {
   addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
   addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
 }
@@ -282,8 +281,7 @@ void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryA
   write32le(Buf + 12, TrapInstr); // Pad to 16-byte boundary
 }
 
-void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const {
-  auto *IS = cast<InputSection>(ISD);
+void ARM::addPltSymbols(InputSection &IS, uint64_t Off) const {
   addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);
   addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
 }

Modified: vendor/lld/dist/ELF/Driver.cpp
==============================================================================
--- vendor/lld/dist/ELF/Driver.cpp	Sun Dec 24 01:00:48 2017	(r327129)
+++ vendor/lld/dist/ELF/Driver.cpp	Sun Dec 24 01:00:50 2017	(r327130)
@@ -1056,7 +1056,7 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
 
   // We need to create some reserved symbols such as _end. Create them.
   if (!Config->Relocatable)
-    addReservedSymbols<ELFT>();
+    addReservedSymbols();
 
   // Apply version scripts.
   Symtab->scanVersionScript();
@@ -1111,7 +1111,7 @@ template <class ELFT> void LinkerDriver::link(opt::Inp
   // before decompressAndMergeSections because the .comment section is a
   // mergeable section.
   if (!Config->Relocatable)
-    InputSections.push_back(createCommentSection<ELFT>());
+    InputSections.push_back(createCommentSection());
 
   // Do size optimizations: garbage collection, merging of SHF_MERGE sections
   // and identical code folding.

Modified: vendor/lld/dist/ELF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputFiles.cpp	Sun Dec 24 01:00:48 2017	(r327129)
+++ vendor/lld/dist/ELF/InputFiles.cpp	Sun Dec 24 01:00:50 2017	(r327130)
@@ -32,6 +32,7 @@
 using namespace llvm;
 using namespace llvm::ELF;
 using namespace llvm::object;
+using namespace llvm::sys;
 using namespace llvm::sys::fs;
 
 using namespace lld;
@@ -69,6 +70,50 @@ Optional<MemoryBufferRef> elf::readFile(StringRef Path
   return MBRef;
 }
 
+// Concatenates arguments to construct a string representing an error location.
+static std::string createFileLineMsg(StringRef Path, unsigned Line) {
+  std::string Filename = path::filename(Path);
+  std::string Lineno = ":" + std::to_string(Line);
+  if (Filename == Path)
+    return Filename + Lineno;
+  return Filename + Lineno + " (" + Path.str() + Lineno + ")";
+}
+
+template <class ELFT>
+static std::string getSrcMsgAux(ObjFile<ELFT> &File, const Symbol &Sym,
+                                InputSectionBase &Sec, uint64_t Offset) {
+  // In DWARF, functions and variables are stored to different places.
+  // First, lookup a function for a given offset.
+  if (Optional<DILineInfo> Info = File.getDILineInfo(&Sec, Offset))
+    return createFileLineMsg(Info->FileName, Info->Line);
+
+  // If it failed, lookup again as a variable.
+  if (Optional<std::pair<std::string, unsigned>> FileLine =
+          File.getVariableLoc(Sym.getName()))
+    return createFileLineMsg(FileLine->first, FileLine->second);
+
+  // File.SourceFile contains STT_FILE symbol, and that is a last resort.
+  return File.SourceFile;
+}
+
+std::string InputFile::getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
+                                 uint64_t Offset) {
+  if (kind() != ObjKind)
+    return "";
+  switch (Config->EKind) {
+  default:
+    llvm_unreachable("Invalid kind");
+  case ELF32LEKind:
+    return getSrcMsgAux(cast<ObjFile<ELF32LE>>(*this), Sym, Sec, Offset);
+  case ELF32BEKind:
+    return getSrcMsgAux(cast<ObjFile<ELF32BE>>(*this), Sym, Sec, Offset);
+  case ELF64LEKind:
+    return getSrcMsgAux(cast<ObjFile<ELF64LE>>(*this), Sym, Sec, Offset);
+  case ELF64BEKind:
+    return getSrcMsgAux(cast<ObjFile<ELF64BE>>(*this), Sym, Sec, Offset);
+  }
+}
+
 template <class ELFT> void ObjFile<ELFT>::initializeDwarf() {
   DWARFContext Dwarf(make_unique<LLDDwarfObj<ELFT>>(this));
   const DWARFObject &Obj = Dwarf.getDWARFObj();
@@ -384,8 +429,8 @@ void ObjFile<ELFT>::initializeSections(
     // have a SHF_LINK_ORDER dependency, this is identified by the sh_link.
     if (Sec.sh_flags & SHF_LINK_ORDER) {
       if (Sec.sh_link >= this->Sections.size())
-        fatal(toString(this) + ": invalid sh_link index: " +
-              Twine(Sec.sh_link));
+        fatal(toString(this) +
+              ": invalid sh_link index: " + Twine(Sec.sh_link));
       this->Sections[Sec.sh_link]->DependentSections.push_back(
           cast<InputSection>(this->Sections[I]));
     }
@@ -454,11 +499,9 @@ InputSectionBase *ObjFile<ELFT>::getRelocTarget(const 
 
 // Create a regular InputSection class that has the same contents
 // as a given section.
-InputSectionBase *toRegularSection(MergeInputSection *Sec) {
-  auto *Ret = make<InputSection>(Sec->Flags, Sec->Type, Sec->Alignment,
-                                 Sec->Data, Sec->Name);
-  Ret->File = Sec->File;
-  return Ret;
+static InputSection *toRegularSection(MergeInputSection *Sec) {
+  return make<InputSection>(Sec->File, Sec->Flags, Sec->Type, Sec->Alignment,
+                            Sec->Data, Sec->Name);
 }
 
 template <class ELFT>
@@ -471,13 +514,13 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(co
       break;
     ARMAttributeParser Attributes;
     ArrayRef<uint8_t> Contents = check(this->getObj().getSectionContents(&Sec));
-    Attributes.Parse(Contents, /*isLittle*/Config->EKind == ELF32LEKind);
+    Attributes.Parse(Contents, /*isLittle*/ Config->EKind == ELF32LEKind);
     updateSupportedARMFeatures(Attributes);
     // FIXME: Retain the first attribute section we see. The eglibc ARM
     // dynamic loaders require the presence of an attribute section for dlopen
     // to work. In a full implementation we would merge all attribute sections.
     if (InX::ARMAttributes == nullptr) {
-      InX::ARMAttributes = make<InputSection>(this, &Sec, Name);
+      InX::ARMAttributes = make<InputSection>(*this, Sec, Name);
       return InX::ARMAttributes;
     }
     return &InputSection::Discarded;
@@ -496,7 +539,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(co
     // If -r is given, we do not interpret or apply relocation
     // but just copy relocation sections to output.
     if (Config->Relocatable)
-      return make<InputSection>(this, &Sec, Name);
+      return make<InputSection>(*this, Sec, Name);
 
     if (Target->FirstRelocation)
       fatal(toString(this) +
@@ -534,7 +577,7 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(co
     // However, if -emit-relocs is given, we need to leave them in the output.
     // (Some post link analysis tools need this information.)
     if (Config->EmitRelocs) {
-      InputSection *RelocSec = make<InputSection>(this, &Sec, Name);
+      InputSection *RelocSec = make<InputSection>(*this, Sec, Name);
       // We will not emit relocation section if target was discarded.
       Target->DependentSections.push_back(RelocSec);
       return RelocSec;
@@ -581,11 +624,11 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(co
   // .eh_frame_hdr section for runtime. So we handle them with a special
   // class. For relocatable outputs, they are just passed through.
   if (Name == ".eh_frame" && !Config->Relocatable)
-    return make<EhInputSection>(this, &Sec, Name);
+    return make<EhInputSection>(*this, Sec, Name);
 
   if (shouldMerge(Sec))
-    return make<MergeInputSection>(this, &Sec, Name);
-  return make<InputSection>(this, &Sec, Name);
+    return make<MergeInputSection>(*this, Sec, Name);
+  return make<InputSection>(*this, Sec, Name);
 }
 
 template <class ELFT>
@@ -636,7 +679,7 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSym
     if (Value == 0 || Value >= UINT32_MAX)
       fatal(toString(this) + ": common symbol '" + Name +
             "' has invalid alignment: " + Twine(Value));
-    return Symtab->addCommon(Name, Size, Value, Binding, StOther, Type, this);
+    return Symtab->addCommon(Name, Size, Value, Binding, StOther, Type, *this);
   }
 
   switch (Binding) {
@@ -648,8 +691,8 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSym
     if (Sec == &InputSection::Discarded)
       return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type,
                                         /*CanOmitFromDynSym=*/false, this);
-    return Symtab->addRegular<ELFT>(Name, StOther, Type, Value, Size, Binding,
-                                    Sec, this);
+    return Symtab->addRegular(Name, StOther, Type, Value, Size, Binding, Sec,
+                              this);
   }
 }
 
@@ -660,7 +703,7 @@ ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&Fi
 template <class ELFT> void ArchiveFile::parse() {
   Symbols.reserve(File->getNumberOfSymbols());
   for (const Archive::Symbol &Sym : File->symbols())
-    Symbols.push_back(Symtab->addLazyArchive<ELFT>(Sym.getName(), this, Sym));
+    Symbols.push_back(Symtab->addLazyArchive<ELFT>(Sym.getName(), *this, Sym));
 }
 
 // Returns a buffer pointing to a member file containing a given symbol.
@@ -841,14 +884,14 @@ template <class ELFT> void SharedFile<ELFT>::parseRest
       error(toString(this) + ": alignment too large: " + Name);
 
     if (!Hidden)
-      Symtab->addShared(Name, this, Sym, Alignment, VersymIndex);
+      Symtab->addShared(Name, *this, Sym, Alignment, VersymIndex);
 
     // Also add the symbol with the versioned name to handle undefined symbols
     // with explicit versions.
     if (Ver) {
       StringRef VerName = this->StringTable.data() + Ver->getAux()->vda_name;
       Name = Saver.save(Name + "@" + VerName);
-      Symtab->addShared(Name, this, Sym, Alignment, VersymIndex);
+      Symtab->addShared(Name, *this, Sym, Alignment, VersymIndex);
     }
   }
 }
@@ -925,7 +968,7 @@ static uint8_t mapVisibility(GlobalValue::VisibilityTy
 template <class ELFT>
 static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
                                    const lto::InputFile::Symbol &ObjSym,
-                                   BitcodeFile *F) {
+                                   BitcodeFile &F) {
   StringRef NameRef = Saver.save(ObjSym.getName());
   uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
 
@@ -936,11 +979,11 @@ static Symbol *createBitcodeSymbol(const std::vector<b
   int C = ObjSym.getComdatIndex();
   if (C != -1 && !KeptComdats[C])
     return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type,
-                                      CanOmitFromDynSym, F);
+                                      CanOmitFromDynSym, &F);
 
   if (ObjSym.isUndefined())
     return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type,
-                                      CanOmitFromDynSym, F);
+                                      CanOmitFromDynSym, &F);
 
   if (ObjSym.isCommon())
     return Symtab->addCommon(NameRef, ObjSym.getCommonSize(),
@@ -958,7 +1001,7 @@ void BitcodeFile::parse(DenseSet<CachedHashStringRef> 
     KeptComdats.push_back(ComdatGroups.insert(CachedHashStringRef(S)).second);
 
   for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
-    Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this));
+    Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, *this));
 }
 
 static ELFKind getELFKind(MemoryBufferRef MB) {
@@ -981,10 +1024,10 @@ static ELFKind getELFKind(MemoryBufferRef MB) {
   return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
 }
 
-template <class ELFT> void BinaryFile::parse() {
+void BinaryFile::parse() {
   ArrayRef<uint8_t> Data = toArrayRef(MB.getBuffer());
-  auto *Section =
-      make<InputSection>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 8, Data, ".data");
+  auto *Section = make<InputSection>(nullptr, SHF_ALLOC | SHF_WRITE,
+                                     SHT_PROGBITS, 8, Data, ".data");
   Sections.push_back(Section);
 
   // For each input file foo that is embedded to a result as a binary
@@ -996,12 +1039,12 @@ template <class ELFT> void BinaryFile::parse() {
     if (!isAlnum(S[I]))
       S[I] = '_';
 
-  Symtab->addRegular<ELFT>(Saver.save(S + "_start"), STV_DEFAULT, STT_OBJECT,
-                           0, 0, STB_GLOBAL, Section, nullptr);
-  Symtab->addRegular<ELFT>(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT,
-                           Data.size(), 0, STB_GLOBAL, Section, nullptr);
-  Symtab->addRegular<ELFT>(Saver.save(S + "_size"), STV_DEFAULT, STT_OBJECT,
-                           Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
+  Symtab->addRegular(Saver.save(S + "_start"), STV_DEFAULT, STT_OBJECT, 0, 0,
+                     STB_GLOBAL, Section, nullptr);
+  Symtab->addRegular(Saver.save(S + "_end"), STV_DEFAULT, STT_OBJECT,
+                     Data.size(), 0, STB_GLOBAL, Section, nullptr);
+  Symtab->addRegular(Saver.save(S + "_size"), STV_DEFAULT, STT_OBJECT,
+                     Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
 }
 
 static bool isBitcode(MemoryBufferRef MB) {
@@ -1145,8 +1188,3 @@ template class elf::SharedFile<ELF32LE>;
 template class elf::SharedFile<ELF32BE>;
 template class elf::SharedFile<ELF64LE>;
 template class elf::SharedFile<ELF64BE>;
-
-template void BinaryFile::parse<ELF32LE>();
-template void BinaryFile::parse<ELF32BE>();
-template void BinaryFile::parse<ELF64LE>();
-template void BinaryFile::parse<ELF64BE>();

Modified: vendor/lld/dist/ELF/InputFiles.h
==============================================================================
--- vendor/lld/dist/ELF/InputFiles.h	Sun Dec 24 01:00:48 2017	(r327129)
+++ vendor/lld/dist/ELF/InputFiles.h	Sun Dec 24 01:00:50 2017	(r327130)
@@ -72,6 +72,11 @@ class InputFile { (public)
 
   Kind kind() const { return FileKind; }
 
+  bool isElf() const {
+    Kind K = kind();
+    return K == ObjKind || K == SharedKind;
+  }
+
   StringRef getName() const { return MB.getBufferIdentifier(); }
   MemoryBufferRef MB;
 
@@ -104,6 +109,9 @@ class InputFile { (public)
   // Cache for toString(). Only toString() should use this member.
   mutable std::string ToStringCache;
 
+  std::string getSrcMsg(const Symbol &Sym, InputSectionBase &Sec,
+                        uint64_t Offset);
+
 protected:
   InputFile(Kind K, MemoryBufferRef M);
   std::vector<InputSectionBase *> Sections;
@@ -121,10 +129,7 @@ template <typename ELFT> class ELFFileBase : public In
   typedef typename ELFT::SymRange Elf_Sym_Range;
 
   ELFFileBase(Kind K, MemoryBufferRef M);
-  static bool classof(const InputFile *F) {
-    Kind K = F->kind();
-    return K == ObjKind || K == SharedKind;
-  }
+  static bool classof(const InputFile *F) { return F->isElf(); }
 
   llvm::object::ELFFile<ELFT> getObj() const {
     return check(llvm::object::ELFFile<ELFT>::create(MB.getBuffer()));
@@ -325,7 +330,7 @@ class BinaryFile : public InputFile {
 public:
   explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
   static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
-  template <class ELFT> void parse();
+  void parse();
 };
 
 InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",

Modified: vendor/lld/dist/ELF/InputSection.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputSection.cpp	Sun Dec 24 01:00:48 2017	(r327129)
+++ vendor/lld/dist/ELF/InputSection.cpp	Sun Dec 24 01:00:50 2017	(r327130)
@@ -24,7 +24,6 @@
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/Endian.h"
-#include "llvm/Support/Path.h"
 #include "llvm/Support/Threading.h"
 #include "llvm/Support/xxhash.h"
 #include <mutex>
@@ -73,11 +72,11 @@ DenseMap<SectionBase *, int> elf::buildSectionOrder() 
 }
 
 template <class ELFT>
-static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> *File,
-                                            const typename ELFT::Shdr *Hdr) {
-  if (!File || Hdr->sh_type == SHT_NOBITS)
-    return makeArrayRef<uint8_t>(nullptr, Hdr->sh_size);
-  return check(File->getObj().getSectionContents(Hdr));
+static ArrayRef<uint8_t> getSectionContents(ObjFile<ELFT> &File,
+                                            const typename ELFT::Shdr &Hdr) {
+  if (Hdr.sh_type == SHT_NOBITS)
+    return makeArrayRef<uint8_t>(nullptr, Hdr.sh_size);
+  return check(File.getObj().getSectionContents(&Hdr));
 }
 
 InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
@@ -88,6 +87,12 @@ InputSectionBase::InputSectionBase(InputFile *File, ui
     : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
                   Link),
       File(File), Data(Data) {
+  // In order to reduce memory allocation, we assume that mergeable
+  // sections are smaller than 4 GiB, which is not an unreasonable
+  // assumption as of 2017.
+  if (SectionKind == SectionBase::Merge && Data.size() > UINT32_MAX)
+    error(toString(this) + ": section too large");
+
   NumRelocations = 0;
   AreRelocsRela = false;
 
@@ -128,18 +133,18 @@ static uint64_t getType(uint64_t Type, StringRef Name)
 }
 
 template <class ELFT>
-InputSectionBase::InputSectionBase(ObjFile<ELFT> *File,
-                                   const typename ELFT::Shdr *Hdr,
+InputSectionBase::InputSectionBase(ObjFile<ELFT> &File,
+                                   const typename ELFT::Shdr &Hdr,
                                    StringRef Name, Kind SectionKind)
-    : InputSectionBase(File, getFlags(Hdr->sh_flags),
-                       getType(Hdr->sh_type, Name), Hdr->sh_entsize,
-                       Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
+    : InputSectionBase(&File, getFlags(Hdr.sh_flags),
+                       getType(Hdr.sh_type, Name), Hdr.sh_entsize, Hdr.sh_link,
+                       Hdr.sh_info, Hdr.sh_addralign,
                        getSectionContents(File, Hdr), Name, SectionKind) {
   // We reject object files having insanely large alignments even though
   // they are allowed by the spec. I think 4GB is a reasonable limitation.
   // We might want to relax this in the future.
-  if (Hdr->sh_addralign > UINT32_MAX)
-    fatal(toString(File) + ": section sh_addralign is too large");
+  if (Hdr.sh_addralign > UINT32_MAX)
+    fatal(toString(&File) + ": section sh_addralign is too large");
 }
 
 size_t InputSectionBase::getSize() const {
@@ -211,8 +216,8 @@ void InputSectionBase::maybeUncompress() {
     fatal(toString(this) +
           ": decompress failed: " + llvm::toString(std::move(E)));
 
-  this->Data = makeArrayRef((uint8_t *)UncompressBuf.get(), Size);
-  this->Flags &= ~(uint64_t)SHF_COMPRESSED;
+  Data = makeArrayRef((uint8_t *)UncompressBuf.get(), Size);
+  Flags &= ~(uint64_t)SHF_COMPRESSED;
 }
 
 InputSection *InputSectionBase::getLinkOrderDep() const {
@@ -257,40 +262,17 @@ std::string InputSectionBase::getLocation(uint64_t Off
   return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str();
 }
 
-// Concatenates arguments to construct a string representing an error location.
-static std::string createFileLineMsg(StringRef Path, unsigned Line) {
-  std::string Filename = path::filename(Path);
-  std::string Lineno = ":" + std::to_string(Line);
-  if (Filename == Path)
-    return Filename + Lineno;
-  return Filename + Lineno + " (" + Path.str() + Lineno + ")";
-}
-
 // This function is intended to be used for constructing an error message.
 // The returned message looks like this:
 //
 //   foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42)
 //
 //  Returns an empty string if there's no way to get line info.
-template <class ELFT>
 std::string InputSectionBase::getSrcMsg(const Symbol &Sym, uint64_t Offset) {
   // Synthetic sections don't have input files.
-  ObjFile<ELFT> *File = getFile<ELFT>();
   if (!File)
     return "";
-
-  // In DWARF, functions and variables are stored to different places.
-  // First, lookup a function for a given offset.
-  if (Optional<DILineInfo> Info = File->getDILineInfo(this, Offset))
-    return createFileLineMsg(Info->FileName, Info->Line);
-
-  // If it failed, lookup again as a variable.
-  if (Optional<std::pair<std::string, unsigned>> FileLine =
-          File->getVariableLoc(Sym.getName()))
-    return createFileLineMsg(FileLine->first, FileLine->second);
-
-  // File->SourceFile contains STT_FILE symbol, and that is a last resort.
-  return File->SourceFile;
+  return File->getSrcMsg(Sym, *this, Offset);
 }
 
 // Returns a filename string along with an optional section name. This
@@ -323,16 +305,17 @@ std::string InputSectionBase::getObjMsg(uint64_t Off) 
       .str();
 }
 
-InputSection InputSection::Discarded(0, 0, 0, ArrayRef<uint8_t>(), "");
+InputSection InputSection::Discarded(nullptr, 0, 0, 0, ArrayRef<uint8_t>(), "");
 
-InputSection::InputSection(uint64_t Flags, uint32_t Type, uint32_t Alignment,
-                           ArrayRef<uint8_t> Data, StringRef Name, Kind K)
-    : InputSectionBase(nullptr, Flags, Type,
+InputSection::InputSection(InputFile *F, uint64_t Flags, uint32_t Type,
+                           uint32_t Alignment, ArrayRef<uint8_t> Data,
+                           StringRef Name, Kind K)
+    : InputSectionBase(F, Flags, Type,
                        /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Alignment, Data,
                        Name, K) {}
 
 template <class ELFT>
-InputSection::InputSection(ObjFile<ELFT> *F, const typename ELFT::Shdr *Header,
+InputSection::InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
                            StringRef Name)
     : InputSectionBase(F, Header, Name, InputSectionBase::Regular) {}
 
@@ -357,15 +340,15 @@ template <class ELFT> void InputSection::copyShtGroup(
 
   // Adjust section numbers because section numbers in an input object
   // files are different in the output.
-  ArrayRef<InputSectionBase *> Sections = this->File->getSections();
+  ArrayRef<InputSectionBase *> Sections = File->getSections();
   for (uint32_t Idx : From.slice(1))
     *To++ = Sections[Idx]->getOutputSection()->SectionIndex;
 }
 
 InputSectionBase *InputSection::getRelocatedSection() {
-  assert(this->Type == SHT_RELA || this->Type == SHT_REL);
-  ArrayRef<InputSectionBase *> Sections = this->File->getSections();
-  return Sections[this->Info];
+  assert(Type == SHT_RELA || Type == SHT_REL);
+  ArrayRef<InputSectionBase *> Sections = File->getSections();
+  return Sections[Info];
 }
 
 // This is used for -r and --emit-relocs. We can't use memcpy to copy
@@ -377,7 +360,7 @@ void InputSection::copyRelocations(uint8_t *Buf, Array
 
   for (const RelTy &Rel : Rels) {
     RelType Type = Rel.getType(Config->IsMips64EL);
-    Symbol &Sym = this->getFile<ELFT>()->getRelocTargetSym(Rel);
+    Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel);
 
     auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf);
     Buf += sizeof(RelTy);
@@ -679,7 +662,7 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, Arra
     if (!RelTy::IsRela)
       Addend += Target->getImplicitAddend(BufLoc, Type);
 
-    Symbol &Sym = this->getFile<ELFT>()->getRelocTargetSym(Rel);
+    Symbol &Sym = getFile<ELFT>()->getRelocTargetSym(Rel);
     RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc);
     if (Expr == R_NONE)
       continue;
@@ -691,7 +674,7 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, Arra
       if (Config->EMachine == EM_386 && Type == R_386_GOTPC)
         continue;
 
-      error(this->getLocation<ELFT>(Offset) + ": has non-ABS relocation " +
+      error(getLocation<ELFT>(Offset) + ": has non-ABS relocation " +
             toString(Type) + " against symbol '" + toString(Sym) + "'");
       return;
     }
@@ -765,7 +748,7 @@ void InputSectionBase::relocateAlloc(uint8_t *Buf, uin
 }
 
 template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
-  if (this->Type == SHT_NOBITS)
+  if (Type == SHT_NOBITS)
     return;
 
   if (auto *S = dyn_cast<SyntheticSection>(this)) {
@@ -775,19 +758,17 @@ template <class ELFT> void InputSection::writeTo(uint8
 
   // If -r or --emit-relocs is given, then an InputSection
   // may be a relocation section.
-  if (this->Type == SHT_RELA) {
-    copyRelocations<ELFT>(Buf + OutSecOff,
-                          this->template getDataAs<typename ELFT::Rela>());
+  if (Type == SHT_RELA) {
+    copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rela>());
     return;
   }
-  if (this->Type == SHT_REL) {
-    copyRelocations<ELFT>(Buf + OutSecOff,
-                          this->template getDataAs<typename ELFT::Rel>());
+  if (Type == SHT_REL) {
+    copyRelocations<ELFT>(Buf + OutSecOff, getDataAs<typename ELFT::Rel>());
     return;
   }
 
   // If -r is given, we may have a SHT_GROUP section.
-  if (this->Type == SHT_GROUP) {
+  if (Type == SHT_GROUP) {
     copyShtGroup<ELFT>(Buf + OutSecOff);
     return;
   }
@@ -796,18 +777,18 @@ template <class ELFT> void InputSection::writeTo(uint8
   // and then apply relocations.
   memcpy(Buf + OutSecOff, Data.data(), Data.size());
   uint8_t *BufEnd = Buf + OutSecOff + Data.size();
-  this->relocate<ELFT>(Buf, BufEnd);
+  relocate<ELFT>(Buf, BufEnd);
 }
 
 void InputSection::replace(InputSection *Other) {
-  this->Alignment = std::max(this->Alignment, Other->Alignment);
-  Other->Repl = this->Repl;
+  Alignment = std::max(Alignment, Other->Alignment);
+  Other->Repl = Repl;
   Other->Live = false;
 }
 
 template <class ELFT>
-EhInputSection::EhInputSection(ObjFile<ELFT> *F,
-                               const typename ELFT::Shdr *Header,
+EhInputSection::EhInputSection(ObjFile<ELFT> &F,
+                               const typename ELFT::Shdr &Header,
                                StringRef Name)
     : InputSectionBase(F, Header, Name, InputSectionBase::EHFrame) {}
 
@@ -838,22 +819,21 @@ static unsigned getReloc(IntTy Begin, IntTy Size, cons
 // This function splits an input section into records and returns them.
 template <class ELFT> void EhInputSection::split() {
   // Early exit if already split.
-  if (!this->Pieces.empty())
+  if (!Pieces.empty())
     return;
 
-  if (this->AreRelocsRela)
-    split<ELFT>(this->relas<ELFT>());
+  if (AreRelocsRela)
+    split<ELFT>(relas<ELFT>());
   else
-    split<ELFT>(this->rels<ELFT>());
+    split<ELFT>(rels<ELFT>());
 }
 
 template <class ELFT, class RelTy>
 void EhInputSection::split(ArrayRef<RelTy> Rels) {
-  ArrayRef<uint8_t> Data = this->Data;
   unsigned RelI = 0;
   for (size_t Off = 0, End = Data.size(); Off != End;) {
     size_t Size = readEhRecordSize(this, Off);
-    this->Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));
+    Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));
     // The empty record is the end marker.
     if (Size == 4)
       break;
@@ -882,7 +862,7 @@ SyntheticSection *MergeInputSection::getParent() const
 // null-terminated strings.
 void MergeInputSection::splitStrings(ArrayRef<uint8_t> Data, size_t EntSize) {
   size_t Off = 0;
-  bool IsAlloc = this->Flags & SHF_ALLOC;
+  bool IsAlloc = Flags & SHF_ALLOC;
   StringRef S = toStringRef(Data);
 
   while (!S.empty()) {
@@ -903,7 +883,7 @@ void MergeInputSection::splitNonStrings(ArrayRef<uint8
                                         size_t EntSize) {
   size_t Size = Data.size();
   assert((Size % EntSize) == 0);
-  bool IsAlloc = this->Flags & SHF_ALLOC;
+  bool IsAlloc = Flags & SHF_ALLOC;
 
   for (size_t I = 0; I != Size; I += EntSize)
     Pieces.emplace_back(I, xxHash64(toStringRef(Data.slice(I, EntSize))),
@@ -911,17 +891,17 @@ void MergeInputSection::splitNonStrings(ArrayRef<uint8
 }
 
 template <class ELFT>
-MergeInputSection::MergeInputSection(ObjFile<ELFT> *F,
-                                     const typename ELFT::Shdr *Header,
+MergeInputSection::MergeInputSection(ObjFile<ELFT> &F,
+                                     const typename ELFT::Shdr &Header,
                                      StringRef Name)
-    : InputSectionBase(F, Header, Name, InputSectionBase::Merge) {
-  // In order to reduce memory allocation, we assume that mergeable
-  // sections are smaller than 4 GiB, which is not an unreasonable
-  // assumption as of 2017.
-  if (Data.size() > UINT32_MAX)
-    error(toString(this) + ": section too large");
-}
+    : InputSectionBase(F, Header, Name, InputSectionBase::Merge) {}
 
+MergeInputSection::MergeInputSection(uint64_t Flags, uint32_t Type,
+                                     uint64_t Entsize, ArrayRef<uint8_t> Data,
+                                     StringRef Name)
+    : InputSectionBase(nullptr, Flags, Type, Entsize, /*Link*/ 0, /*Info*/ 0,
+                       /*Alignment*/ Entsize, Data, Name, SectionBase::Merge) {}
+
 // This function is called after we obtain a complete list of input sections
 // that need to be linked. This is responsible to split section contents
 // into small chunks for further processing.
@@ -931,14 +911,14 @@ MergeInputSection::MergeInputSection(ObjFile<ELFT> *F,
 void MergeInputSection::splitIntoPieces() {
   assert(Pieces.empty());
 
-  if (this->Flags & SHF_STRINGS)
+  if (Flags & SHF_STRINGS)
     splitStrings(Data, Entsize);
   else
     splitNonStrings(Data, Entsize);
 
-  if (Config->GcSections && (this->Flags & SHF_ALLOC))
+  if (Config->GcSections && (Flags & SHF_ALLOC))
     for (uint64_t Off : LiveOffsets)
-      this->getSectionPiece(Off)->Live = true;
+      getSectionPiece(Off)->Live = true;
 }
 
 // Do binary search to get a section piece at a given input offset.
@@ -993,7 +973,7 @@ uint64_t MergeInputSection::getOffset(uint64_t Offset)
 
   // If Offset is not at beginning of a section piece, it is not in the map.
   // In that case we need to search from the original section piece vector.
-  const SectionPiece &Piece = *this->getSectionPiece(Offset);
+  const SectionPiece &Piece = *getSectionPiece(Offset);
   if (!Piece.Live)
     return 0;
 
@@ -1001,13 +981,13 @@ uint64_t MergeInputSection::getOffset(uint64_t Offset)
   return Piece.OutputOff + Addend;
 }
 
-template InputSection::InputSection(ObjFile<ELF32LE> *, const ELF32LE::Shdr *,
+template InputSection::InputSection(ObjFile<ELF32LE> &, const ELF32LE::Shdr &,
                                     StringRef);
-template InputSection::InputSection(ObjFile<ELF32BE> *, const ELF32BE::Shdr *,
+template InputSection::InputSection(ObjFile<ELF32BE> &, const ELF32BE::Shdr &,
                                     StringRef);
-template InputSection::InputSection(ObjFile<ELF64LE> *, const ELF64LE::Shdr *,
+template InputSection::InputSection(ObjFile<ELF64LE> &, const ELF64LE::Shdr &,
                                     StringRef);
-template InputSection::InputSection(ObjFile<ELF64BE> *, const ELF64BE::Shdr *,
+template InputSection::InputSection(ObjFile<ELF64BE> &, const ELF64BE::Shdr &,
                                     StringRef);
 
 template std::string InputSectionBase::getLocation<ELF32LE>(uint64_t);
@@ -1015,37 +995,28 @@ template std::string InputSectionBase::getLocation<ELF
 template std::string InputSectionBase::getLocation<ELF64LE>(uint64_t);
 template std::string InputSectionBase::getLocation<ELF64BE>(uint64_t);
 
-template std::string InputSectionBase::getSrcMsg<ELF32LE>(const Symbol &,
-                                                          uint64_t);
-template std::string InputSectionBase::getSrcMsg<ELF32BE>(const Symbol &,
-                                                          uint64_t);
-template std::string InputSectionBase::getSrcMsg<ELF64LE>(const Symbol &,
-                                                          uint64_t);
-template std::string InputSectionBase::getSrcMsg<ELF64BE>(const Symbol &,
-                                                          uint64_t);
-
 template void InputSection::writeTo<ELF32LE>(uint8_t *);
 template void InputSection::writeTo<ELF32BE>(uint8_t *);
 template void InputSection::writeTo<ELF64LE>(uint8_t *);
 template void InputSection::writeTo<ELF64BE>(uint8_t *);
 
-template MergeInputSection::MergeInputSection(ObjFile<ELF32LE> *,
-                                              const ELF32LE::Shdr *, StringRef);
-template MergeInputSection::MergeInputSection(ObjFile<ELF32BE> *,
-                                              const ELF32BE::Shdr *, StringRef);
-template MergeInputSection::MergeInputSection(ObjFile<ELF64LE> *,
-                                              const ELF64LE::Shdr *, StringRef);
-template MergeInputSection::MergeInputSection(ObjFile<ELF64BE> *,
-                                              const ELF64BE::Shdr *, StringRef);
+template MergeInputSection::MergeInputSection(ObjFile<ELF32LE> &,
+                                              const ELF32LE::Shdr &, StringRef);
+template MergeInputSection::MergeInputSection(ObjFile<ELF32BE> &,
+                                              const ELF32BE::Shdr &, StringRef);
+template MergeInputSection::MergeInputSection(ObjFile<ELF64LE> &,
+                                              const ELF64LE::Shdr &, StringRef);
+template MergeInputSection::MergeInputSection(ObjFile<ELF64BE> &,
+                                              const ELF64BE::Shdr &, StringRef);
 
-template EhInputSection::EhInputSection(ObjFile<ELF32LE> *,
-                                        const ELF32LE::Shdr *, StringRef);
-template EhInputSection::EhInputSection(ObjFile<ELF32BE> *,
-                                        const ELF32BE::Shdr *, StringRef);
-template EhInputSection::EhInputSection(ObjFile<ELF64LE> *,
-                                        const ELF64LE::Shdr *, StringRef);
-template EhInputSection::EhInputSection(ObjFile<ELF64BE> *,
-                                        const ELF64BE::Shdr *, StringRef);
+template EhInputSection::EhInputSection(ObjFile<ELF32LE> &,
+                                        const ELF32LE::Shdr &, StringRef);
+template EhInputSection::EhInputSection(ObjFile<ELF32BE> &,
+                                        const ELF32BE::Shdr &, StringRef);
+template EhInputSection::EhInputSection(ObjFile<ELF64LE> &,
+                                        const ELF64LE::Shdr &, StringRef);
+template EhInputSection::EhInputSection(ObjFile<ELF64BE> &,
+                                        const ELF64BE::Shdr &, StringRef);
 
 template void EhInputSection::split<ELF32LE>();
 template void EhInputSection::split<ELF32BE>();

Modified: vendor/lld/dist/ELF/InputSection.h
==============================================================================
--- vendor/lld/dist/ELF/InputSection.h	Sun Dec 24 01:00:48 2017	(r327129)
+++ vendor/lld/dist/ELF/InputSection.h	Sun Dec 24 01:00:50 2017	(r327130)
@@ -93,7 +93,7 @@ class SectionBase { (protected)
 class InputSectionBase : public SectionBase {
 public:
   template <class ELFT>
-  InputSectionBase(ObjFile<ELFT> *File, const typename ELFT::Shdr *Header,
+  InputSectionBase(ObjFile<ELFT> &File, const typename ELFT::Shdr &Header,
                    StringRef Name, Kind SectionKind);
 
   InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type,
@@ -168,7 +168,6 @@ class InputSectionBase : public SectionBase { (public)
 
   // Returns a source location string. Used to construct an error message.
   template <class ELFT> std::string getLocation(uint64_t Offset);
-  template <class ELFT>
   std::string getSrcMsg(const Symbol &Sym, uint64_t Offset);
   std::string getObjMsg(uint64_t Offset);
 
@@ -216,8 +215,11 @@ static_assert(sizeof(SectionPiece) == 16, "SectionPiec
 class MergeInputSection : public InputSectionBase {
 public:
   template <class ELFT>
-  MergeInputSection(ObjFile<ELFT> *F, const typename ELFT::Shdr *Header,
+  MergeInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
                     StringRef Name);
+  MergeInputSection(uint64_t Flags, uint32_t Type, uint64_t Entsize,
+                    ArrayRef<uint8_t> Data, StringRef Name);
+
   static bool classof(const SectionBase *S) { return S->kind() == Merge; }
   void splitIntoPieces();
 
@@ -279,7 +281,7 @@ struct EhSectionPiece {
 class EhInputSection : public InputSectionBase {
 public:
   template <class ELFT>
-  EhInputSection(ObjFile<ELFT> *F, const typename ELFT::Shdr *Header,
+  EhInputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
                  StringRef Name);
   static bool classof(const SectionBase *S) { return S->kind() == EHFrame; }
   template <class ELFT> void split();
@@ -298,10 +300,10 @@ class EhInputSection : public InputSectionBase { (publ
 // .eh_frame. It also includes the synthetic sections themselves.
 class InputSection : public InputSectionBase {
 public:
-  InputSection(uint64_t Flags, uint32_t Type, uint32_t Alignment,
+  InputSection(InputFile *F, uint64_t Flags, uint32_t Type, uint32_t Alignment,
                ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
   template <class ELFT>
-  InputSection(ObjFile<ELFT> *F, const typename ELFT::Shdr *Header,
+  InputSection(ObjFile<ELFT> &F, const typename ELFT::Shdr &Header,
                StringRef Name);
 
   // Write this section to a mmap'ed file, assuming Buf is pointing to

Modified: vendor/lld/dist/ELF/MarkLive.cpp
==============================================================================
--- vendor/lld/dist/ELF/MarkLive.cpp	Sun Dec 24 01:00:48 2017	(r327129)
+++ vendor/lld/dist/ELF/MarkLive.cpp	Sun Dec 24 01:00:50 2017	(r327130)
@@ -68,7 +68,7 @@ static void resolveReloc(InputSectionBase &Sec, RelT &
   B.Used = true;
   if (auto *SS = dyn_cast<SharedSymbol>(&B))
     if (!SS->isWeak())
-      SS->getFile<ELFT>()->IsNeeded = true;
+      SS->getFile<ELFT>().IsNeeded = true;
 
   if (auto *D = dyn_cast<Defined>(&B)) {
     auto *RelSec = dyn_cast_or_null<InputSectionBase>(D->Section);
@@ -246,7 +246,7 @@ template <class ELFT> static void doGcSections() {
     // that point to .eh_frames. Otherwise, the garbage collector would drop
     // all of them. We also want to preserve personality routines and LSDA
     // referenced by .eh_frame sections, so we scan them for that here.
-    if (auto *EH = dyn_cast_or_null<EhInputSection>(Sec)) {
+    if (auto *EH = dyn_cast<EhInputSection>(Sec)) {
       EH->Live = true;
       scanEhFrameSection<ELFT>(*EH, Enqueue);
     }

Modified: vendor/lld/dist/ELF/Relocations.cpp
==============================================================================
--- vendor/lld/dist/ELF/Relocations.cpp	Sun Dec 24 01:00:48 2017	(r327129)
+++ vendor/lld/dist/ELF/Relocations.cpp	Sun Dec 24 01:00:50 2017	(r327130)
@@ -70,12 +70,11 @@ using namespace lld::elf;
 // >>> defined in /home/alice/src/foo.o
 // >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)
 // >>>               /home/alice/src/bar.o:(.text+0x1)
-template <class ELFT>
 static std::string getLocation(InputSectionBase &S, const Symbol &Sym,
                                uint64_t Off) {
   std::string Msg =
       "\n>>> defined in " + toString(Sym.File) + "\n>>> referenced by ";
-  std::string Src = S.getSrcMsg<ELFT>(Sym, Off);
+  std::string Src = S.getSrcMsg(Sym, Off);
   if (!Src.empty())
     Msg += Src + "\n>>>               ";
   return Msg + S.getObjMsg(Off);
@@ -365,7 +364,6 @@ static bool isRelExpr(RelExpr Expr) {
 //
 // If this function returns false, that means we need to emit a
 // dynamic relocation so that the relocation will be fixed at load-time.
-template <class ELFT>
 static bool isStaticLinkTimeConstant(RelExpr E, RelType Type, const Symbol &Sym,
                                      InputSectionBase &S, uint64_t RelOff) {
   // These expressions always compute a constant
@@ -410,7 +408,7 @@ static bool isStaticLinkTimeConstant(RelExpr E, RelTyp
     return true;
 
   error("relocation " + toString(Type) + " cannot refer to absolute symbol: " +
-        toString(Sym) + getLocation<ELFT>(S, Sym, RelOff));
+        toString(Sym) + getLocation(S, Sym, RelOff));
   return true;
 }
 
@@ -443,8 +441,8 @@ template <class ELFT> static bool isReadOnly(SharedSym
   typedef typename ELFT::Phdr Elf_Phdr;
 
   // Determine if the symbol is read-only by scanning the DSO's program headers.
-  const SharedFile<ELFT> *File = SS->getFile<ELFT>();
-  for (const Elf_Phdr &Phdr : check(File->getObj().program_headers()))
+  const SharedFile<ELFT> &File = SS->getFile<ELFT>();
+  for (const Elf_Phdr &Phdr : check(File.getObj().program_headers()))
     if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
         !(Phdr.p_flags & ELF::PF_W) && SS->Value >= Phdr.p_vaddr &&
         SS->Value < Phdr.p_vaddr + Phdr.p_memsz)
@@ -461,14 +459,14 @@ template <class ELFT>
 static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) {
   typedef typename ELFT::Sym Elf_Sym;
 
-  SharedFile<ELFT> *File = SS->getFile<ELFT>();
+  SharedFile<ELFT> &File = SS->getFile<ELFT>();
 
   std::vector<SharedSymbol *> Ret;
-  for (const Elf_Sym &S : File->getGlobalELFSyms()) {
+  for (const Elf_Sym &S : File.getGlobalELFSyms()) {
     if (S.st_shndx == SHN_UNDEF || S.st_shndx == SHN_ABS ||
         S.st_value != SS->Value)
       continue;
-    StringRef Name = check(S.getName(File->getStringTable()));
+    StringRef Name = check(S.getName(File.getStringTable()));
     Symbol *Sym = Symtab->find(Name);
     if (auto *Alias = dyn_cast_or_null<SharedSymbol>(Sym))
       Ret.push_back(Alias);
@@ -554,22 +552,57 @@ static void errorOrWarn(const Twine &Msg) {
     warn(Msg);
 }
 
+// Returns PLT relocation expression.
+//
+// This handles a non PIC program call to function in a shared library. In
+// an ideal world, we could just report an error saying the relocation can
+// overflow at runtime. In the real world with glibc, crt1.o has a
+// R_X86_64_PC32 pointing to libc.so.
+//
+// The general idea on how to handle such cases is to create a PLT entry and
+// use that as the function value.
+//
+// For the static linking part, we just return a plt expr and everything
+// else will use the the PLT entry as the address.
+//
+// The remaining problem is making sure pointer equality still works. We
+// need the help of the dynamic linker for that. We let it know that we have
+// a direct reference to a so symbol by creating an undefined symbol with a
+// non zero st_value. Seeing that, the dynamic linker resolves the symbol to
+// the value of the symbol we created. This is true even for got entries, so
+// pointer equality is maintained. To avoid an infinite loop, the only entry
+// that points to the real function is a dedicated got entry used by the
+// plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT,
+// R_386_JMP_SLOT, etc).
+static RelExpr getPltExpr(Symbol &Sym, RelExpr Expr, bool &IsConstant) {
+  Sym.NeedsPltAddr = true;
+  Sym.IsPreemptible = false;
+  IsConstant = true;
+  return toPlt(Expr);
+}
+
 template <class ELFT>
 static RelExpr adjustExpr(Symbol &Sym, RelExpr Expr, RelType Type,
-                          InputSectionBase &S, uint64_t RelOff) {
+                          InputSectionBase &S, uint64_t RelOff,
+                          bool &IsConstant) {
   // We can create any dynamic relocation if a section is simply writable.
   if (S.Flags & SHF_WRITE)
     return Expr;
 
   // Or, if we are allowed to create dynamic relocations against
-  // read-only sections (i.e. unless "-z notext" is given),
+  // read-only sections (i.e. when "-z notext" is given),
   // we can create a dynamic relocation as we want, too.
-  if (!Config->ZText)
+  if (!Config->ZText) {
+    // We use PLT for relocations that may overflow in runtime,

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-all mailing list