Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Feb 2019 18:39:57 +0000 (UTC)
From:      Dimitry Andric <dim@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r343802 - in vendor/lld/dist-release_80: COFF ELF MinGW docs test/COFF test/ELF
Message-ID:  <201902051839.x15Idvsc063691@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Tue Feb  5 18:39:57 2019
New Revision: 343802
URL: https://svnweb.freebsd.org/changeset/base/343802

Log:
  Vendor import of lld release_80 branch r353167:
  https://llvm.org/svn/llvm-project/lld/branches/release_80@353167

Added:
  vendor/lld/dist-release_80/test/COFF/arm-thumb-thunks-pdb.s
  vendor/lld/dist-release_80/test/COFF/arm64-thunks.s
  vendor/lld/dist-release_80/test/ELF/no-discard-this_module.s
  vendor/lld/dist-release_80/test/ELF/sht-group-empty.test
Deleted:
  vendor/lld/dist-release_80/test/COFF/arm64-branch-range.test
Modified:
  vendor/lld/dist-release_80/COFF/Chunks.cpp
  vendor/lld/dist-release_80/COFF/Chunks.h
  vendor/lld/dist-release_80/COFF/DLL.cpp
  vendor/lld/dist-release_80/COFF/ICF.cpp
  vendor/lld/dist-release_80/COFF/Writer.cpp
  vendor/lld/dist-release_80/ELF/ICF.cpp
  vendor/lld/dist-release_80/ELF/InputFiles.cpp
  vendor/lld/dist-release_80/ELF/InputFiles.h
  vendor/lld/dist-release_80/ELF/ScriptParser.cpp
  vendor/lld/dist-release_80/ELF/SyntheticSections.cpp
  vendor/lld/dist-release_80/MinGW/Options.td
  vendor/lld/dist-release_80/docs/ReleaseNotes.rst
  vendor/lld/dist-release_80/test/COFF/imports.test
  vendor/lld/dist-release_80/test/ELF/arm-gnu-ifunc.s
  vendor/lld/dist-release_80/test/ELF/comdat-linkonce.s
  vendor/lld/dist-release_80/test/ELF/emulation-aarch64.s
  vendor/lld/dist-release_80/test/ELF/emulation-ppc.s
  vendor/lld/dist-release_80/test/ELF/emulation-x86.s

Modified: vendor/lld/dist-release_80/COFF/Chunks.cpp
==============================================================================
--- vendor/lld/dist-release_80/COFF/Chunks.cpp	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/COFF/Chunks.cpp	Tue Feb  5 18:39:57 2019	(r343802)
@@ -669,16 +669,36 @@ const uint8_t ArmThunk[] = {
     0xe7, 0x44,             // L1: add  pc, ip
 };
 
-size_t RangeExtensionThunk::getSize() const {
+size_t RangeExtensionThunkARM::getSize() const {
   assert(Config->Machine == ARMNT);
   return sizeof(ArmThunk);
 }
 
-void RangeExtensionThunk::writeTo(uint8_t *Buf) const {
+void RangeExtensionThunkARM::writeTo(uint8_t *Buf) const {
   assert(Config->Machine == ARMNT);
   uint64_t Offset = Target->getRVA() - RVA - 12;
   memcpy(Buf + OutputSectionOff, ArmThunk, sizeof(ArmThunk));
   applyMOV32T(Buf + OutputSectionOff, uint32_t(Offset));
+}
+
+// A position independent ARM64 adrp+add thunk, with a maximum range of
+// +/- 4 GB, which is enough for any PE-COFF.
+const uint8_t Arm64Thunk[] = {
+    0x10, 0x00, 0x00, 0x90, // adrp x16, Dest
+    0x10, 0x02, 0x00, 0x91, // add  x16, x16, :lo12:Dest
+    0x00, 0x02, 0x1f, 0xd6, // br   x16
+};
+
+size_t RangeExtensionThunkARM64::getSize() const {
+  assert(Config->Machine == ARM64);
+  return sizeof(Arm64Thunk);
+}
+
+void RangeExtensionThunkARM64::writeTo(uint8_t *Buf) const {
+  assert(Config->Machine == ARM64);
+  memcpy(Buf + OutputSectionOff, Arm64Thunk, sizeof(Arm64Thunk));
+  applyArm64Addr(Buf + OutputSectionOff + 0, Target->getRVA(), RVA, 12);
+  applyArm64Imm(Buf + OutputSectionOff + 4, Target->getRVA() & 0xfff, 0);
 }
 
 void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {

Modified: vendor/lld/dist-release_80/COFF/Chunks.h
==============================================================================
--- vendor/lld/dist-release_80/COFF/Chunks.h	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/COFF/Chunks.h	Tue Feb  5 18:39:57 2019	(r343802)
@@ -355,9 +355,18 @@ class ImportThunkChunkARM64 : public Chunk { (private)
   Defined *ImpSymbol;
 };
 
-class RangeExtensionThunk : public Chunk {
+class RangeExtensionThunkARM : public Chunk {
 public:
-  explicit RangeExtensionThunk(Defined *T) : Target(T) {}
+  explicit RangeExtensionThunkARM(Defined *T) : Target(T) {}
+  size_t getSize() const override;
+  void writeTo(uint8_t *Buf) const override;
+
+  Defined *Target;
+};
+
+class RangeExtensionThunkARM64 : public Chunk {
+public:
+  explicit RangeExtensionThunkARM64(Defined *T) : Target(T) {}
   size_t getSize() const override;
   void writeTo(uint8_t *Buf) const override;
 

Modified: vendor/lld/dist-release_80/COFF/DLL.cpp
==============================================================================
--- vendor/lld/dist-release_80/COFF/DLL.cpp	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/COFF/DLL.cpp	Tue Feb  5 18:39:57 2019	(r343802)
@@ -47,6 +47,7 @@ class HintNameChunk : public Chunk { (public)
   }
 
   void writeTo(uint8_t *Buf) const override {
+    memset(Buf + OutputSectionOff, 0, getSize());
     write16le(Buf + OutputSectionOff, Hint);
     memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size());
   }
@@ -63,7 +64,10 @@ class LookupChunk : public Chunk { (public)
   size_t getSize() const override { return Config->Wordsize; }
 
   void writeTo(uint8_t *Buf) const override {
-    write32le(Buf + OutputSectionOff, HintName->getRVA());
+    if (Config->is64())
+      write64le(Buf + OutputSectionOff, HintName->getRVA());
+    else
+      write32le(Buf + OutputSectionOff, HintName->getRVA());
   }
 
   Chunk *HintName;
@@ -99,6 +103,8 @@ class ImportDirectoryChunk : public Chunk { (public)
   size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
 
   void writeTo(uint8_t *Buf) const override {
+    memset(Buf + OutputSectionOff, 0, getSize());
+
     auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);
     E->ImportLookupTableRVA = LookupTab->getRVA();
     E->NameRVA = DLLName->getRVA();
@@ -118,6 +124,10 @@ class NullChunk : public Chunk { (public)
   bool hasData() const override { return false; }
   size_t getSize() const override { return Size; }
 
+  void writeTo(uint8_t *Buf) const override {
+    memset(Buf + OutputSectionOff, 0, Size);
+  }
+
 private:
   size_t Size;
 };
@@ -160,6 +170,8 @@ class DelayDirectoryChunk : public Chunk { (public)
   }
 
   void writeTo(uint8_t *Buf) const override {
+    memset(Buf + OutputSectionOff, 0, getSize());
+
     auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff);
     E->Attributes = 1;
     E->Name = DLLName->getRVA();
@@ -392,6 +404,8 @@ class ExportDirectoryChunk : public Chunk { (public)
   }
 
   void writeTo(uint8_t *Buf) const override {
+    memset(Buf + OutputSectionOff, 0, getSize());
+
     auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff);
     E->NameRVA = DLLName->getRVA();
     E->OrdinalBase = 0;

Modified: vendor/lld/dist-release_80/COFF/ICF.cpp
==============================================================================
--- vendor/lld/dist-release_80/COFF/ICF.cpp	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/COFF/ICF.cpp	Tue Feb  5 18:39:57 2019	(r343802)
@@ -263,19 +263,21 @@ void ICF::run(ArrayRef<Chunk *> Vec) {
 
   // Initially, we use hash values to partition sections.
   parallelForEach(Chunks, [&](SectionChunk *SC) {
-    SC->Class[1] = xxHash64(SC->getContents());
+    SC->Class[0] = xxHash64(SC->getContents());
   });
 
   // Combine the hashes of the sections referenced by each section into its
   // hash.
-  parallelForEach(Chunks, [&](SectionChunk *SC) {
-    uint32_t Hash = SC->Class[1];
-    for (Symbol *B : SC->symbols())
-      if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
-        Hash ^= Sym->getChunk()->Class[1];
-    // Set MSB to 1 to avoid collisions with non-hash classs.
-    SC->Class[0] = Hash | (1U << 31);
-  });
+  for (unsigned Cnt = 0; Cnt != 2; ++Cnt) {
+    parallelForEach(Chunks, [&](SectionChunk *SC) {
+      uint32_t Hash = SC->Class[Cnt % 2];
+      for (Symbol *B : SC->symbols())
+        if (auto *Sym = dyn_cast_or_null<DefinedRegular>(B))
+          Hash += Sym->getChunk()->Class[Cnt % 2];
+      // Set MSB to 1 to avoid collisions with non-hash classs.
+      SC->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
+    });
+  }
 
   // From now on, sections in Chunks are ordered so that sections in
   // the same group are consecutive in the vector.

Modified: vendor/lld/dist-release_80/COFF/Writer.cpp
==============================================================================
--- vendor/lld/dist-release_80/COFF/Writer.cpp	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/COFF/Writer.cpp	Tue Feb  5 18:39:57 2019	(r343802)
@@ -306,16 +306,31 @@ void OutputSection::writeHeaderTo(uint8_t *Buf) {
 // Check whether the target address S is in range from a relocation
 // of type RelType at address P.
 static bool isInRange(uint16_t RelType, uint64_t S, uint64_t P, int Margin) {
-  assert(Config->Machine == ARMNT);
-  int64_t Diff = AbsoluteDifference(S, P + 4) + Margin;
-  switch (RelType) {
-  case IMAGE_REL_ARM_BRANCH20T:
-    return isInt<21>(Diff);
-  case IMAGE_REL_ARM_BRANCH24T:
-  case IMAGE_REL_ARM_BLX23T:
-    return isInt<25>(Diff);
-  default:
-    return true;
+  if (Config->Machine == ARMNT) {
+    int64_t Diff = AbsoluteDifference(S, P + 4) + Margin;
+    switch (RelType) {
+    case IMAGE_REL_ARM_BRANCH20T:
+      return isInt<21>(Diff);
+    case IMAGE_REL_ARM_BRANCH24T:
+    case IMAGE_REL_ARM_BLX23T:
+      return isInt<25>(Diff);
+    default:
+      return true;
+    }
+  } else if (Config->Machine == ARM64) {
+    int64_t Diff = AbsoluteDifference(S, P) + Margin;
+    switch (RelType) {
+    case IMAGE_REL_ARM64_BRANCH26:
+      return isInt<28>(Diff);
+    case IMAGE_REL_ARM64_BRANCH19:
+      return isInt<21>(Diff);
+    case IMAGE_REL_ARM64_BRANCH14:
+      return isInt<16>(Diff);
+    default:
+      return true;
+    }
+  } else {
+    llvm_unreachable("Unexpected architecture");
   }
 }
 
@@ -327,7 +342,17 @@ getThunk(DenseMap<uint64_t, Defined *> &LastThunks, De
   Defined *&LastThunk = LastThunks[Target->getRVA()];
   if (LastThunk && isInRange(Type, LastThunk->getRVA(), P, Margin))
     return {LastThunk, false};
-  RangeExtensionThunk *C = make<RangeExtensionThunk>(Target);
+  Chunk *C;
+  switch (Config->Machine) {
+  case ARMNT:
+    C = make<RangeExtensionThunkARM>(Target);
+    break;
+  case ARM64:
+    C = make<RangeExtensionThunkARM64>(Target);
+    break;
+  default:
+    llvm_unreachable("Unexpected architecture");
+  }
   Defined *D = make<DefinedSynthetic>("", C);
   LastThunk = D;
   return {D, true};
@@ -344,14 +369,14 @@ getThunk(DenseMap<uint64_t, Defined *> &LastThunks, De
 // After adding thunks, we verify that all relocations are in range (with
 // no extra margin requirements). If this failed, we restart (throwing away
 // the previously created thunks) and retry with a wider margin.
-static bool createThunks(std::vector<Chunk *> &Chunks, int Margin) {
+static bool createThunks(OutputSection *OS, int Margin) {
   bool AddressesChanged = false;
   DenseMap<uint64_t, Defined *> LastThunks;
   size_t ThunksSize = 0;
   // Recheck Chunks.size() each iteration, since we can insert more
   // elements into it.
-  for (size_t I = 0; I != Chunks.size(); ++I) {
-    SectionChunk *SC = dyn_cast_or_null<SectionChunk>(Chunks[I]);
+  for (size_t I = 0; I != OS->Chunks.size(); ++I) {
+    SectionChunk *SC = dyn_cast_or_null<SectionChunk>(OS->Chunks[I]);
     if (!SC)
       continue;
     size_t ThunkInsertionSpot = I + 1;
@@ -388,7 +413,8 @@ static bool createThunks(std::vector<Chunk *> &Chunks,
         Chunk *ThunkChunk = Thunk->getChunk();
         ThunkChunk->setRVA(
             ThunkInsertionRVA); // Estimate of where it will be located.
-        Chunks.insert(Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
+        ThunkChunk->setOutputSection(OS);
+        OS->Chunks.insert(OS->Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
         ThunkInsertionSpot++;
         ThunksSize += ThunkChunk->getSize();
         ThunkInsertionRVA += ThunkChunk->getSize();
@@ -428,7 +454,7 @@ static bool verifyRanges(const std::vector<Chunk *> Ch
 // Assign addresses and add thunks if necessary.
 void Writer::finalizeAddresses() {
   assignAddresses();
-  if (Config->Machine != ARMNT)
+  if (Config->Machine != ARMNT && Config->Machine != ARM64)
     return;
 
   size_t OrigNumChunks = 0;
@@ -477,7 +503,7 @@ void Writer::finalizeAddresses() {
     // to avoid things going out of range due to the added thunks.
     bool AddressesChanged = false;
     for (OutputSection *Sec : OutputSections)
-      AddressesChanged |= createThunks(Sec->Chunks, Margin);
+      AddressesChanged |= createThunks(Sec, Margin);
     // If the verification above thought we needed thunks, we should have
     // added some.
     assert(AddressesChanged);

Modified: vendor/lld/dist-release_80/ELF/ICF.cpp
==============================================================================
--- vendor/lld/dist-release_80/ELF/ICF.cpp	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/ELF/ICF.cpp	Tue Feb  5 18:39:57 2019	(r343802)
@@ -426,16 +426,17 @@ void ICF<ELFT>::forEachClass(llvm::function_ref<void(s
 // Combine the hashes of the sections referenced by the given section into its
 // hash.
 template <class ELFT, class RelTy>
-static void combineRelocHashes(InputSection *IS, ArrayRef<RelTy> Rels) {
-  uint32_t Hash = IS->Class[1];
+static void combineRelocHashes(unsigned Cnt, InputSection *IS,
+                               ArrayRef<RelTy> Rels) {
+  uint32_t Hash = IS->Class[Cnt % 2];
   for (RelTy Rel : Rels) {
     Symbol &S = IS->template getFile<ELFT>()->getRelocTargetSym(Rel);
     if (auto *D = dyn_cast<Defined>(&S))
       if (auto *RelSec = dyn_cast_or_null<InputSection>(D->Section))
-        Hash ^= RelSec->Class[1];
+        Hash += RelSec->Class[Cnt % 2];
   }
   // Set MSB to 1 to avoid collisions with non-hash IDs.
-  IS->Class[0] = Hash | (1U << 31);
+  IS->Class[(Cnt + 1) % 2] = Hash | (1U << 31);
 }
 
 static void print(const Twine &S) {
@@ -453,15 +454,17 @@ template <class ELFT> void ICF<ELFT>::run() {
 
   // Initially, we use hash values to partition sections.
   parallelForEach(Sections, [&](InputSection *S) {
-    S->Class[1] = xxHash64(S->data());
+    S->Class[0] = xxHash64(S->data());
   });
 
-  parallelForEach(Sections, [&](InputSection *S) {
-    if (S->AreRelocsRela)
-      combineRelocHashes<ELFT>(S, S->template relas<ELFT>());
-    else
-      combineRelocHashes<ELFT>(S, S->template rels<ELFT>());
-  });
+  for (unsigned Cnt = 0; Cnt != 2; ++Cnt) {
+    parallelForEach(Sections, [&](InputSection *S) {
+      if (S->AreRelocsRela)
+        combineRelocHashes<ELFT>(Cnt, S, S->template relas<ELFT>());
+      else
+        combineRelocHashes<ELFT>(Cnt, S, S->template rels<ELFT>());
+    });
+  }
 
   // From now on, sections in Sections vector are ordered so that sections
   // in the same equivalence class are consecutive in the vector.

Modified: vendor/lld/dist-release_80/ELF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist-release_80/ELF/InputFiles.cpp	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/ELF/InputFiles.cpp	Tue Feb  5 18:39:57 2019	(r343802)
@@ -320,17 +320,6 @@ StringRef ObjFile<ELFT>::getShtGroupSignature(ArrayRef
   return Signature;
 }
 
-template <class ELFT>
-ArrayRef<typename ObjFile<ELFT>::Elf_Word>
-ObjFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
-  const ELFFile<ELFT> &Obj = this->getObj();
-  ArrayRef<Elf_Word> Entries =
-      CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
-  if (Entries.empty() || Entries[0] != GRP_COMDAT)
-    fatal(toString(this) + ": unsupported SHT_GROUP format");
-  return Entries.slice(1);
-}
-
 template <class ELFT> bool ObjFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
   // On a regular link we don't merge sections if -O0 (default is -O1). This
   // sometimes makes the linker significantly faster, although the output will
@@ -440,26 +429,34 @@ void ObjFile<ELFT>::initializeSections(
     case SHT_GROUP: {
       // De-duplicate section groups by their signatures.
       StringRef Signature = getShtGroupSignature(ObjSections, Sec);
-      bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
       this->Sections[I] = &InputSection::Discarded;
 
-      // We only support GRP_COMDAT type of group. Get the all entries of the
-      // section here to let getShtGroupEntries to check the type early for us.
-      ArrayRef<Elf_Word> Entries = getShtGroupEntries(Sec);
 
-      // If it is a new section group, we want to keep group members.
-      // Group leader sections, which contain indices of group members, are
-      // discarded because they are useless beyond this point. The only
-      // exception is the -r option because in order to produce re-linkable
-      // object files, we want to pass through basically everything.
+      ArrayRef<Elf_Word> Entries =
+          CHECK(Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), this);
+      if (Entries.empty())
+        fatal(toString(this) + ": empty SHT_GROUP");
+
+      // The first word of a SHT_GROUP section contains flags. Currently,
+      // the standard defines only "GRP_COMDAT" flag for the COMDAT group.
+      // An group with the empty flag doesn't define anything; such sections
+      // are just skipped.
+      if (Entries[0] == 0)
+        continue;
+
+      if (Entries[0] != GRP_COMDAT)
+        fatal(toString(this) + ": unsupported SHT_GROUP format");
+
+      bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
       if (IsNew) {
         if (Config->Relocatable)
           this->Sections[I] = createInputSection(Sec);
-        continue;
+	continue;
       }
 
+
       // Otherwise, discard group members.
-      for (uint32_t SecIndex : Entries) {
+      for (uint32_t SecIndex : Entries.slice(1)) {
         if (SecIndex >= Size)
           fatal(toString(this) +
                 ": invalid section index in group: " + Twine(SecIndex));
@@ -739,7 +736,8 @@ InputSectionBase *ObjFile<ELFT>::createInputSection(co
   // sections. Drop those sections to avoid duplicate symbol errors.
   // FIXME: This is glibc PR20543, we should remove this hack once that has been
   // fixed for a while.
-  if (Name.startswith(".gnu.linkonce."))
+  if (Name == ".gnu.linkonce.t.__x86.get_pc_thunk.bx" ||
+      Name == ".gnu.linkonce.t.__i686.get_pc_thunk.bx")
     return &InputSection::Discarded;
 
   // If we are creating a new .build-id section, strip existing .build-id

Modified: vendor/lld/dist-release_80/ELF/InputFiles.h
==============================================================================
--- vendor/lld/dist-release_80/ELF/InputFiles.h	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/ELF/InputFiles.h	Tue Feb  5 18:39:57 2019	(r343802)
@@ -175,7 +175,6 @@ template <class ELFT> class ObjFile : public ELFFileBa
 
   StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
                                  const Elf_Shdr &Sec);
-  ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec);
 
 public:
   static bool classof(const InputFile *F) { return F->kind() == Base::ObjKind; }

Modified: vendor/lld/dist-release_80/ELF/ScriptParser.cpp
==============================================================================
--- vendor/lld/dist-release_80/ELF/ScriptParser.cpp	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/ELF/ScriptParser.cpp	Tue Feb  5 18:39:57 2019	(r343802)
@@ -94,7 +94,6 @@ class ScriptParser final : ScriptLexer { (private)
   SortSectionPolicy readSortKind();
   SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
   SymbolAssignment *readAssignment(StringRef Tok);
-  std::tuple<ELFKind, uint16_t, bool> readBfdName();
   void readSort();
   Expr readAssert();
   Expr readConstant();
@@ -385,39 +384,24 @@ void ScriptParser::readOutputArch() {
     skip();
 }
 
-std::tuple<ELFKind, uint16_t, bool> ScriptParser::readBfdName() {
-  StringRef S = unquote(next());
-  if (S == "elf32-i386")
-    return std::make_tuple(ELF32LEKind, EM_386, false);
-  if (S == "elf32-iamcu")
-    return std::make_tuple(ELF32LEKind, EM_IAMCU, false);
-  if (S == "elf32-littlearm")
-    return std::make_tuple(ELF32LEKind, EM_ARM, false);
-  if (S == "elf32-x86-64")
-    return std::make_tuple(ELF32LEKind, EM_X86_64, false);
-  if (S == "elf64-littleaarch64")
-    return std::make_tuple(ELF64LEKind, EM_AARCH64, false);
-  if (S == "elf64-powerpc")
-    return std::make_tuple(ELF64BEKind, EM_PPC64, false);
-  if (S == "elf64-powerpcle")
-    return std::make_tuple(ELF64LEKind, EM_PPC64, false);
-  if (S == "elf64-x86-64")
-    return std::make_tuple(ELF64LEKind, EM_X86_64, false);
-  if (S == "elf32-tradbigmips")
-    return std::make_tuple(ELF32BEKind, EM_MIPS, false);
-  if (S == "elf32-ntradbigmips")
-    return std::make_tuple(ELF32BEKind, EM_MIPS, true);
-  if (S == "elf32-tradlittlemips")
-    return std::make_tuple(ELF32LEKind, EM_MIPS, false);
-  if (S == "elf32-ntradlittlemips")
-    return std::make_tuple(ELF32LEKind, EM_MIPS, true);
-  if (S == "elf64-tradbigmips")
-    return std::make_tuple(ELF64BEKind, EM_MIPS, false);
-  if (S == "elf64-tradlittlemips")
-    return std::make_tuple(ELF64LEKind, EM_MIPS, false);
-
-  setError("unknown output format name: " + S);
-  return std::make_tuple(ELFNoneKind, EM_NONE, false);
+static std::pair<ELFKind, uint16_t> parseBfdName(StringRef S) {
+  return StringSwitch<std::pair<ELFKind, uint16_t>>(S)
+      .Case("elf32-i386", {ELF32LEKind, EM_386})
+      .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
+      .Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
+      .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
+      .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
+      .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
+      .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
+      .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
+      .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
+      .Case("elf32-tradbigmips", {ELF32BEKind, EM_MIPS})
+      .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS})
+      .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS})
+      .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
+      .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS})
+      .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
+      .Default({ELFNoneKind, EM_NONE});
 }
 
 // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little).
@@ -425,9 +409,16 @@ std::tuple<ELFKind, uint16_t, bool> ScriptParser::read
 void ScriptParser::readOutputFormat() {
   expect("(");
 
-  std::tuple<ELFKind, uint16_t, bool> BfdTuple = readBfdName();
-  if (Config->EKind == ELFNoneKind)
-    std::tie(Config->EKind, Config->EMachine, Config->MipsN32Abi) = BfdTuple;
+  StringRef Name = unquote(next());
+  StringRef S = Name;
+  if (S.consume_back("-freebsd"))
+    Config->OSABI = ELFOSABI_FREEBSD;
+
+  std::tie(Config->EKind, Config->EMachine) = parseBfdName(S);
+  if (Config->EMachine == EM_NONE)
+    setError("unknown output format name: " + Name);
+  if (S == "elf32-ntradlittlemips" || S == "elf32-ntradbigmips")
+    Config->MipsN32Abi = true;
 
   if (consume(")"))
     return;

Modified: vendor/lld/dist-release_80/ELF/SyntheticSections.cpp
==============================================================================
--- vendor/lld/dist-release_80/ELF/SyntheticSections.cpp	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/ELF/SyntheticSections.cpp	Tue Feb  5 18:39:57 2019	(r343802)
@@ -1513,8 +1513,10 @@ void RelocationBaseSection::finalizeContents() {
   else
     getParent()->Link = 0;
 
-  if (In.RelaIplt == this || In.RelaPlt == this)
+  if (In.RelaPlt == this)
     getParent()->Info = In.GotPlt->getParent()->SectionIndex;
+  if (In.RelaIplt == this)
+    getParent()->Info = In.IgotPlt->getParent()->SectionIndex;
 }
 
 RelrBaseSection::RelrBaseSection()

Modified: vendor/lld/dist-release_80/MinGW/Options.td
==============================================================================
--- vendor/lld/dist-release_80/MinGW/Options.td	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/MinGW/Options.td	Tue Feb  5 18:39:57 2019	(r343802)
@@ -78,3 +78,9 @@ def version: F<"version">, HelpText<"Display the versi
 def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
 def alias_strip_s: Flag<["-"], "s">, Alias<strip_all>;
 def alias_strip_S: Flag<["-"], "S">, Alias<strip_debug>;
+
+// Ignored options
+def: S<"plugin">;
+def: J<"plugin=">;
+def: S<"plugin-opt">;
+def: J<"plugin-opt=">;

Modified: vendor/lld/dist-release_80/docs/ReleaseNotes.rst
==============================================================================
--- vendor/lld/dist-release_80/docs/ReleaseNotes.rst	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/docs/ReleaseNotes.rst	Tue Feb  5 18:39:57 2019	(r343802)
@@ -40,6 +40,9 @@ ELF Improvements
 
 * The following flags have been added: ``-z interpose``, ``-z global``
 
+* lld now uses the ``sigrie`` instruction as a trap instruction for
+  MIPS targets.
+
 COFF Improvements
 -----------------
 
@@ -65,6 +68,13 @@ MinGW Improvements
   from GCC in setups with DWARF exceptions though, where object files are
   linked in a different order than with GNU ld, inserting a DWARF exception
   table terminator too early.)
+
+* lld now supports COFF embedded directives for linking to nondefault
+  libraries, just like for the normal COFF target.
+
+* Actually generate a codeview build id signature, even if not creating a PDB.
+  Previously, the ``--build-id`` option did not actually generate a build id
+  unless ``--pdb`` was specified.
 
 MachO Improvements
 ------------------

Added: vendor/lld/dist-release_80/test/COFF/arm-thumb-thunks-pdb.s
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/lld/dist-release_80/test/COFF/arm-thumb-thunks-pdb.s	Tue Feb  5 18:39:57 2019	(r343802)
@@ -0,0 +1,18 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -debug -pdb:%t.pdb -verbose 2>&1 | FileCheck %s --check-prefix=VERBOSE
+
+// VERBOSE: Added 1 thunks with margin {{.*}} in {{.*}} passes
+
+    .syntax unified
+    .globl main
+    .globl func1
+    .text
+main:
+    bne func1
+    bx lr
+    .section .text$a, "xr"
+    .space 0x100000
+    .section .text$b, "xr"
+func1:
+    bx lr

Added: vendor/lld/dist-release_80/test/COFF/arm64-thunks.s
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/lld/dist-release_80/test/COFF/arm64-thunks.s	Tue Feb  5 18:39:57 2019	(r343802)
@@ -0,0 +1,27 @@
+// REQUIRES: aarch64
+// RUN: llvm-mc -filetype=obj -triple=aarch64-windows %s -o %t.obj
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
+// RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
+
+// VERBOSE: Added 1 thunks with margin {{.*}} in 1 passes
+
+    .globl main
+    .globl func1
+    .text
+main:
+    tbz w0, #0, func1
+    ret
+    .section .text$a, "xr"
+    .space 0x8000
+    .section .text$b, "xr"
+func1:
+    ret
+
+// DISASM: 0000000140001000 .text:
+// DISASM: 140001000:      40 00 00 36     tbz     w0, #0, #8 <.text+0x8>
+// DISASM: 140001004:      c0 03 5f d6     ret
+// DISASM: 140001008:      50 00 00 90     adrp    x16, #32768
+// DISASM: 14000100c:      10 52 00 91     add     x16, x16, #20
+// DISASM: 140001010:      00 02 1f d6     br      x16
+
+// DISASM: 140009014:      c0 03 5f d6     ret

Modified: vendor/lld/dist-release_80/test/COFF/imports.test
==============================================================================
--- vendor/lld/dist-release_80/test/COFF/imports.test	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/test/COFF/imports.test	Tue Feb  5 18:39:57 2019	(r343802)
@@ -34,3 +34,16 @@ IMPORT-NEXT:   Symbol: ExitProcess (0)
 IMPORT-NEXT:   Symbol:  (50)
 IMPORT-NEXT:   Symbol: MessageBoxA (1)
 IMPORT-NEXT: }
+
+# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /merge:.rdata=.text \
+# RUN:   %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess
+# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=MERGE %s
+
+MERGE:      Import {
+MERGE-NEXT:   Name: std64.dll
+MERGE-NEXT:   ImportLookupTableRVA: 0x1090
+MERGE-NEXT:   ImportAddressTableRVA: 0x10B0
+MERGE-NEXT:   Symbol: ExitProcess (0)
+MERGE-NEXT:   Symbol:  (50)
+MERGE-NEXT:   Symbol: MessageBoxA (1)
+MERGE-NEXT: }

Modified: vendor/lld/dist-release_80/test/ELF/arm-gnu-ifunc.s
==============================================================================
--- vendor/lld/dist-release_80/test/ELF/arm-gnu-ifunc.s	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/test/ELF/arm-gnu-ifunc.s	Tue Feb  5 18:39:57 2019	(r343802)
@@ -35,6 +35,8 @@ _start:
 // CHECK-NEXT:     Address: 0x100F4
 // CHECK-NEXT:     Offset: 0xF4
 // CHECK-NEXT:     Size: 16
+// CHECK-NEXT:     Link:
+// CHECK-NEXT:     Info: 4
 // CHECK:          Name: .plt
 // CHECK-NEXT:     Type: SHT_PROGBITS
 // CHECK-NEXT:     Flags [
@@ -44,7 +46,8 @@ _start:
 // CHECK-NEXT:     Address: 0x11020
 // CHECK-NEXT:     Offset: 0x1020
 // CHECK-NEXT:     Size: 32
-// CHECK:          Name: .got
+// CHECK:          Index: 4
+// CHECK-NEXT:     Name: .got
 // CHECK-NEXT:     Type: SHT_PROGBITS
 // CHECK-NEXT:     Flags [
 // CHECK-NEXT:       SHF_ALLOC

Modified: vendor/lld/dist-release_80/test/ELF/comdat-linkonce.s
==============================================================================
--- vendor/lld/dist-release_80/test/ELF/comdat-linkonce.s	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/test/ELF/comdat-linkonce.s	Tue Feb  5 18:39:57 2019	(r343802)
@@ -4,7 +4,12 @@
 // RUN: ld.lld -shared %t.o %t2.o -o %t
 // RUN: ld.lld -shared %t2.o %t.o -o %t
 
-.section .gnu.linkonce.t.zed
+.section .gnu.linkonce.t.__x86.get_pc_thunk.bx
 .globl abc
 abc:
+nop
+
+.section .gnu.linkonce.t.__i686.get_pc_thunk.bx
+.globl def
+def:
 nop

Modified: vendor/lld/dist-release_80/test/ELF/emulation-aarch64.s
==============================================================================
--- vendor/lld/dist-release_80/test/ELF/emulation-aarch64.s	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/test/ELF/emulation-aarch64.s	Tue Feb  5 18:39:57 2019	(r343802)
@@ -30,5 +30,28 @@
 # AARCH64-NEXT:   Flags [ (0x0)
 # AARCH64-NEXT:   ]
 
+# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %taarch64fbsd
+# RUN: echo 'OUTPUT_FORMAT(elf64-aarch64-freebsd)' > %taarch64fbsd.script
+# RUN: ld.lld %taarch64fbsd.script %taarch64fbsd -o %t2aarch64fbsd
+# RUN: llvm-readobj -file-headers %t2aarch64fbsd | FileCheck --check-prefix=AARCH64-FBSD %s
+# AARCH64-FBSD:      ElfHeader {
+# AARCH64-FBSD-NEXT:   Ident {
+# AARCH64-FBSD-NEXT:     Magic: (7F 45 4C 46)
+# AARCH64-FBSD-NEXT:     Class: 64-bit (0x2)
+# AARCH64-FBSD-NEXT:     DataEncoding: LittleEndian (0x1)
+# AARCH64-FBSD-NEXT:     FileVersion: 1
+# AARCH64-FBSD-NEXT:     OS/ABI: FreeBSD (0x9)
+# AARCH64-FBSD-NEXT:     ABIVersion: 0
+# AARCH64-FBSD-NEXT:     Unused: (00 00 00 00 00 00 00)
+# AARCH64-FBSD-NEXT:   }
+# AARCH64-FBSD-NEXT:   Type: Executable (0x2)
+# AARCH64-FBSD-NEXT:   Machine: EM_AARCH64 (0xB7)
+# AARCH64-FBSD-NEXT:   Version: 1
+# AARCH64-FBSD-NEXT:   Entry:
+# AARCH64-FBSD-NEXT:   ProgramHeaderOffset: 0x40
+# AARCH64-FBSD-NEXT:   SectionHeaderOffset:
+# AARCH64-FBSD-NEXT:   Flags [ (0x0)
+# AARCH64-FBSD-NEXT:   ]
+
 .globl _start
 _start:

Modified: vendor/lld/dist-release_80/test/ELF/emulation-ppc.s
==============================================================================
--- vendor/lld/dist-release_80/test/ELF/emulation-ppc.s	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/test/ELF/emulation-ppc.s	Tue Feb  5 18:39:57 2019	(r343802)
@@ -35,6 +35,38 @@
 # PPC64-NEXT:   StringTableSectionIndex:
 # PPC64-NEXT: }
 
+# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-freebsd %s -o %tppc64fbsd
+# RUN: echo 'OUTPUT_FORMAT(elf64-powerpc-freebsd)' > %tppc64fbsd.script
+# RUN: ld.lld %tppc64fbsd.script  %tppc64fbsd -o %t2ppc64fbsd
+# RUN: llvm-readobj -file-headers %t2ppc64fbsd | FileCheck --check-prefix=PPC64-FBSD %s
+
+# PPC64-FBSD:      ElfHeader {
+# PPC64-FBSD-NEXT:   Ident {
+# PPC64-FBSD-NEXT:     Magic: (7F 45 4C 46)
+# PPC64-FBSD-NEXT:     Class: 64-bit (0x2)
+# PPC64-FBSD-NEXT:     DataEncoding: BigEndian (0x2)
+# PPC64-FBSD-NEXT:     FileVersion: 1
+# PPC64-FBSD-NEXT:     OS/ABI: FreeBSD (0x9)
+# PPC64-FBSD-NEXT:     ABIVersion: 0
+# PPC64-FBSD-NEXT:     Unused: (00 00 00 00 00 00 00)
+# PPC64-FBSD-NEXT:   }
+# PPC64-FBSD-NEXT:   Type: Executable (0x2)
+# PPC64-FBSD-NEXT:   Machine: EM_PPC64 (0x15)
+# PPC64-FBSD-NEXT:   Version: 1
+# PPC64-FBSD-NEXT:   Entry:
+# PPC64-FBSD-NEXT:   ProgramHeaderOffset: 0x40
+# PPC64-FBSD-NEXT:   SectionHeaderOffset:
+# PPC64-FBSD-NEXT:   Flags [ (0x2)
+# PPC64-FBSD-NEXT:     0x2
+# PPC64-FBSD-NEXT:   ]
+# PPC64-FBSD-NEXT:   HeaderSize: 64
+# PPC64-FBSD-NEXT:   ProgramHeaderEntrySize: 56
+# PPC64-FBSD-NEXT:   ProgramHeaderCount:
+# PPC64-FBSD-NEXT:   SectionHeaderEntrySize: 64
+# PPC64-FBSD-NEXT:   SectionHeaderCount:
+# PPC64-FBSD-NEXT:   StringTableSectionIndex:
+# PPC64-FBSD-NEXT: }
+
 # RUN: llvm-mc -filetype=obj -triple=powerpc64le-unknown-linux %s -o %tppc64le
 # RUN: ld.lld -m elf64lppc %tppc64le -o %t2ppc64le
 # RUN: llvm-readobj -file-headers %t2ppc64le | FileCheck --check-prefix=PPC64LE %s

Modified: vendor/lld/dist-release_80/test/ELF/emulation-x86.s
==============================================================================
--- vendor/lld/dist-release_80/test/ELF/emulation-x86.s	Tue Feb  5 18:39:51 2019	(r343801)
+++ vendor/lld/dist-release_80/test/ELF/emulation-x86.s	Tue Feb  5 18:39:57 2019	(r343802)
@@ -7,6 +7,9 @@
 # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv
 # RUN: ld.lld -m elf_amd64_fbsd %t.sysv -o %t.freebsd
 # RUN: llvm-readobj -file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s
+# RUN: echo 'OUTPUT_FORMAT(elf64-x86-64-freebsd)' > %t4x64.script
+# RUN: ld.lld %t4x64.script %tx64 -o %t4x64
+# RUN: llvm-readobj -file-headers %t4x64 | FileCheck --check-prefix=AMD64 %s
 # AMD64:      ElfHeader {
 # AMD64-NEXT:   Ident {
 # AMD64-NEXT:     Magic: (7F 45 4C 46)
@@ -137,10 +140,13 @@
 # X86-NEXT: }
 
 # RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd
-# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86_fbsd
-# RUN: llvm-readobj -file-headers %t2x86_fbsd | FileCheck --check-prefix=X86FBSD %s
+# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86fbsd
+# RUN: llvm-readobj -file-headers %t2x86fbsd | FileCheck --check-prefix=X86FBSD %s
 # RUN: ld.lld %tx86fbsd -o %t3x86fbsd
 # RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s
+# RUN: echo 'OUTPUT_FORMAT(elf32-i386-freebsd)' > %t4x86fbsd.script
+# RUN: ld.lld %t4x86fbsd.script %tx86fbsd -o %t4x86fbsd
+# RUN: llvm-readobj -file-headers %t4x86fbsd | FileCheck --check-prefix=X86FBSD %s
 # X86FBSD:      ElfHeader {
 # X86FBSD-NEXT:   Ident {
 # X86FBSD-NEXT:     Magic: (7F 45 4C 46)

Added: vendor/lld/dist-release_80/test/ELF/no-discard-this_module.s
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/lld/dist-release_80/test/ELF/no-discard-this_module.s	Tue Feb  5 18:39:57 2019	(r343802)
@@ -0,0 +1,41 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-linux-gnu -save-temp-labels %s -o %t
+// RUN: ld.lld %t -o %t2
+// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
+
+.global _start
+_start:
+
+// This section and symbol is used by Linux kernel modules. Ensure it's not
+// accidentally discarded.
+.section .gnu.linkonce.this_module:
+__this_module:
+.byte 0x00
+
+// CHECK: Section {
+// CHECK:    Index:
+// CHECK:    Name: .gnu.linkonce.this_module
+// CHECK-NEXT:    Type: SHT_PROGBITS
+// CHECK-NEXT:    Flags [
+// CHECK-NEXT:    ]
+// CHECK-NEXT:    Address:
+// CHECK-NEXT:    Offset:
+// CHECK-NEXT:    Size:
+// CHECK-NEXT:    Link:
+// CHECK-NEXT:    Info:
+// CHECK-NEXT:    AddressAlignment:
+// CHECK-NEXT:    EntrySize:
+// CHECK-NEXT:    SectionData (
+// CHECK-NEXT:      0000: 00                                   |.|
+// CHECK-NEXT:    )
+// CHECK-NEXT:  }
+
+// CHECK:  Symbol {
+// CHECK:    Name: __this_module
+// CHECK-NEXT:    Value:
+// CHECK-NEXT:    Size:
+// CHECK-NEXT:    Binding: Local
+// CHECK-NEXT:    Type: None
+// CHECK-NEXT:    Other:
+// CHECK-NEXT:    Section: .gnu.linkonce.this_module:
+// CHECK-NEXT:  }

Added: vendor/lld/dist-release_80/test/ELF/sht-group-empty.test
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/lld/dist-release_80/test/ELF/sht-group-empty.test	Tue Feb  5 18:39:57 2019	(r343802)
@@ -0,0 +1,55 @@
+# RUN: yaml2obj %s -o %t.o
+# RUN: ld.lld %t.o %t.o -o %t -r
+# RUN: llvm-readobj -s %t | FileCheck %s
+
+# CHECK:     Name: .text.foo
+# CHECK:     Name: .rela.text.foo
+
+--- !ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_REL
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .group
+    Type:            SHT_GROUP
+    Link:            .symtab
+    Info:            foo
+    Members:
+      - SectionOrType:    GRP_COMDAT
+      - SectionOrType:    .text.foo
+      - SectionOrType:    .text.bar
+      - SectionOrType:    .note
+  - Name:            .note
+    Type:            SHT_NOTE
+    Flags:           [ SHF_GROUP ]
+  - Name:            .text.foo
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+  - Name:            .text.bar
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
+  - Name:            .rela.text.foo
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK, SHF_GROUP ]
+    Link:            .symtab
+    Info:            .text.foo
+    Relocations:
+      - Offset:          0x0000000000000000
+        Symbol:          foo
+        Type:            R_X86_64_64
+  - Name:            .rela.text.bar
+    Type:            SHT_RELA
+    Flags:           [ SHF_INFO_LINK, SHF_GROUP ]
+    Link:            .symtab
+    Info:            .text.bar
+    Relocations:
+      - Offset:          0x0000000000000000
+        Symbol:          bar
+        Type:            R_X86_64_64
+Symbols:
+  Global:
+    - Name:            foo
+    - Name:            bar
+



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201902051839.x15Idvsc063691>