svn commit: r293846 - in vendor/lld/dist: . COFF ELF lib/Config lib/Core lib/Driver lib/ReaderWriter lib/ReaderWriter/ELF lib/ReaderWriter/ELF/AArch64 lib/ReaderWriter/ELF/AMDGPU lib/ReaderWriter/E...

Dimitry Andric dim at FreeBSD.org
Wed Jan 13 20:06:08 UTC 2016


Author: dim
Date: Wed Jan 13 20:06:04 2016
New Revision: 293846
URL: https://svnweb.freebsd.org/changeset/base/293846

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

Added:
  vendor/lld/dist/test/ELF/Inputs/aarch64-condb-reloc.s   (contents, props changed)
  vendor/lld/dist/test/ELF/Inputs/aarch64-tls-ie.s   (contents, props changed)
  vendor/lld/dist/test/ELF/Inputs/aarch64-tstbr14-reloc.s   (contents, props changed)
  vendor/lld/dist/test/ELF/Inputs/mips-gp-disp.so   (contents, props changed)
  vendor/lld/dist/test/ELF/Inputs/wrap.s   (contents, props changed)
  vendor/lld/dist/test/ELF/aarch64-condb-reloc.s   (contents, props changed)
  vendor/lld/dist/test/ELF/aarch64-gnu-ifunc-nosym.s   (contents, props changed)
  vendor/lld/dist/test/ELF/aarch64-gnu-ifunc.s   (contents, props changed)
  vendor/lld/dist/test/ELF/aarch64-tls-ie.s   (contents, props changed)
  vendor/lld/dist/test/ELF/aarch64-tstbr14-reloc.s   (contents, props changed)
  vendor/lld/dist/test/ELF/amdgpu-entry.s   (contents, props changed)
  vendor/lld/dist/test/ELF/amdgpu-globals.s   (contents, props changed)
  vendor/lld/dist/test/ELF/amdgpu-kernels.s   (contents, props changed)
  vendor/lld/dist/test/ELF/basic-ppc.s   (contents, props changed)
  vendor/lld/dist/test/ELF/mips-gp-disp.s   (contents, props changed)
  vendor/lld/dist/test/ELF/ppc-relocs.s   (contents, props changed)
  vendor/lld/dist/test/ELF/wrap.s   (contents, props changed)
  vendor/lld/dist/test/mach-o/do-not-emit-unwind-fde-arm64.yaml
Deleted:
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.cpp
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUExecutableWriter.h
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.cpp
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPULinkingContext.h
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.cpp
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPURelocationHandler.h
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.cpp
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUSymbolTable.h
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.cpp
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/AMDGPUTargetHandler.h
  vendor/lld/dist/lib/ReaderWriter/ELF/AMDGPU/CMakeLists.txt
  vendor/lld/dist/test/old-elf/AMDGPU/hsa.test
Modified:
  vendor/lld/dist/CMakeLists.txt
  vendor/lld/dist/COFF/CMakeLists.txt
  vendor/lld/dist/COFF/Chunks.cpp
  vendor/lld/dist/COFF/Chunks.h
  vendor/lld/dist/COFF/Config.h
  vendor/lld/dist/COFF/DLL.cpp
  vendor/lld/dist/COFF/Driver.cpp
  vendor/lld/dist/COFF/DriverUtils.cpp
  vendor/lld/dist/COFF/InputFiles.cpp
  vendor/lld/dist/COFF/Writer.cpp
  vendor/lld/dist/ELF/CMakeLists.txt
  vendor/lld/dist/ELF/Driver.cpp
  vendor/lld/dist/ELF/Driver.h
  vendor/lld/dist/ELF/DriverUtils.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/LinkerScript.cpp
  vendor/lld/dist/ELF/MarkLive.cpp
  vendor/lld/dist/ELF/Options.td
  vendor/lld/dist/ELF/OutputSections.cpp
  vendor/lld/dist/ELF/OutputSections.h
  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/Target.cpp
  vendor/lld/dist/ELF/Target.h
  vendor/lld/dist/ELF/Writer.cpp
  vendor/lld/dist/lib/Config/CMakeLists.txt
  vendor/lld/dist/lib/Core/CMakeLists.txt
  vendor/lld/dist/lib/Driver/CMakeLists.txt
  vendor/lld/dist/lib/Driver/GnuLdDriver.cpp
  vendor/lld/dist/lib/ReaderWriter/CMakeLists.txt
  vendor/lld/dist/lib/ReaderWriter/ELF/AArch64/CMakeLists.txt
  vendor/lld/dist/lib/ReaderWriter/ELF/ARM/CMakeLists.txt
  vendor/lld/dist/lib/ReaderWriter/ELF/CMakeLists.txt
  vendor/lld/dist/lib/ReaderWriter/ELF/ELFLinkingContext.cpp
  vendor/lld/dist/lib/ReaderWriter/ELF/Hexagon/CMakeLists.txt
  vendor/lld/dist/lib/ReaderWriter/ELF/Mips/CMakeLists.txt
  vendor/lld/dist/lib/ReaderWriter/ELF/X86/CMakeLists.txt
  vendor/lld/dist/lib/ReaderWriter/ELF/X86_64/CMakeLists.txt
  vendor/lld/dist/lib/ReaderWriter/ELF/X86_64/ExampleSubTarget/CMakeLists.txt
  vendor/lld/dist/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/CMakeLists.txt
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
  vendor/lld/dist/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
  vendor/lld/dist/lib/ReaderWriter/YAML/CMakeLists.txt
  vendor/lld/dist/test/COFF/export.test
  vendor/lld/dist/test/ELF/basic-aarch64.s
  vendor/lld/dist/test/ELF/basic-mips.s
  vendor/lld/dist/test/ELF/basic.s
  vendor/lld/dist/test/ELF/basic32.s
  vendor/lld/dist/test/ELF/basic64be.s
  vendor/lld/dist/test/ELF/discard-none.s
  vendor/lld/dist/test/ELF/linkerscript-sections.s
  vendor/lld/dist/test/ELF/relocation-copy.s
  vendor/lld/dist/test/ELF/string-table.s
  vendor/lld/dist/test/lit.cfg
  vendor/lld/dist/test/mach-o/arm64-reloc-negDelta32-fixup.yaml
  vendor/lld/dist/test/mach-o/parse-data-relocs-arm64.yaml

Modified: vendor/lld/dist/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/CMakeLists.txt	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/CMakeLists.txt	Wed Jan 13 20:06:04 2016	(r293846)
@@ -1,4 +1,5 @@
 set(LLD_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+set(LLD_INCLUDE_DIR ${LLD_SOURCE_DIR}/include )
 set(LLD_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
 
 # Compute the LLD version from the LLVM version.
@@ -86,6 +87,12 @@ if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
     )
 endif()
 
+macro(add_lld_library name)
+  add_llvm_library(${name} ${ARGN})
+  set_target_properties(${name} PROPERTIES FOLDER "lld libraries")
+endmacro(add_lld_library)
+
+
 add_subdirectory(lib)
 add_subdirectory(tools)
 

Modified: vendor/lld/dist/COFF/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/COFF/CMakeLists.txt	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/COFF/CMakeLists.txt	Wed Jan 13 20:06:04 2016	(r293846)
@@ -2,7 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Options.td)
 tablegen(LLVM Options.inc -gen-opt-parser-defs)
 add_public_tablegen_target(COFFOptionsTableGen)
 
-add_llvm_library(lldCOFF
+add_lld_library(lldCOFF
   Chunks.cpp
   DLL.cpp
   Driver.cpp

Modified: vendor/lld/dist/COFF/Chunks.cpp
==============================================================================
--- vendor/lld/dist/COFF/Chunks.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/COFF/Chunks.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -310,7 +310,7 @@ void SEHTableChunk::writeTo(uint8_t *Buf
 BaserelChunk::BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End) {
   // Block header consists of 4 byte page RVA and 4 byte block size.
   // Each entry is 2 byte. Last entry may be padding.
-  Data.resize(RoundUpToAlignment((End - Begin) * 2 + 8, 4));
+  Data.resize(align((End - Begin) * 2 + 8, 4));
   uint8_t *P = Data.data();
   write32le(P, Page);
   write32le(P + 4, Data.size());

Modified: vendor/lld/dist/COFF/Chunks.h
==============================================================================
--- vendor/lld/dist/COFF/Chunks.h	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/COFF/Chunks.h	Wed Jan 13 20:06:04 2016	(r293846)
@@ -326,6 +326,10 @@ public:
   uint8_t Type;
 };
 
+inline uint64_t align(uint64_t Value, uint64_t Align) {
+  return llvm::RoundUpToAlignment(Value, Align);
+}
+
 } // namespace coff
 } // namespace lld
 

Modified: vendor/lld/dist/COFF/Config.h
==============================================================================
--- vendor/lld/dist/COFF/Config.h	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/COFF/Config.h	Wed Jan 13 20:06:04 2016	(r293846)
@@ -25,6 +25,7 @@ using llvm::COFF::WindowsSubsystem;
 using llvm::StringRef;
 class DefinedAbsolute;
 class DefinedRelative;
+class StringChunk;
 class Undefined;
 
 // Short aliases.
@@ -42,6 +43,12 @@ struct Export {
   bool Data = false;
   bool Private = false;
 
+  // If an export is a form of /export:foo=dllname.bar, that means
+  // that foo should be exported as an alias to bar in the DLL.
+  // ForwardTo is set to "dllname.bar" part. Usually empty.
+  StringRef ForwardTo;
+  StringChunk *ForwardChunk = nullptr;
+
   // True if this /export option was in .drectves section.
   bool Directives = false;
   StringRef SymbolName;

Modified: vendor/lld/dist/COFF/DLL.cpp
==============================================================================
--- vendor/lld/dist/COFF/DLL.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/COFF/DLL.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -45,7 +45,7 @@ public:
   size_t getSize() const override {
     // Starts with 2 byte Hint field, followed by a null-terminated string,
     // ends with 0 or 1 byte padding.
-    return RoundUpToAlignment(Name.size() + 3, 2);
+    return align(Name.size() + 3, 2);
   }
 
   void writeTo(uint8_t *Buf) const override {
@@ -320,8 +320,12 @@ public:
 
   void writeTo(uint8_t *Buf) const override {
     for (Export &E : Config->Exports) {
-      auto *D = cast<Defined>(E.Sym->repl());
-      write32le(Buf + OutputSectionOff + E.Ordinal * 4, D->getRVA());
+      uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
+      if (E.ForwardChunk) {
+        write32le(P, E.ForwardChunk->getRVA());
+      } else {
+        write32le(P, cast<Defined>(E.Sym->repl())->getRVA());
+      }
     }
   }
 
@@ -539,6 +543,15 @@ EdataContents::EdataContents() {
   for (Export &E : Config->Exports)
     if (!E.Noname)
       Names.push_back(new StringChunk(E.ExportName));
+
+  std::vector<Chunk *> Forwards;
+  for (Export &E : Config->Exports) {
+    if (E.ForwardTo.empty())
+      continue;
+    E.ForwardChunk = new StringChunk(E.ForwardTo);
+    Forwards.push_back(E.ForwardChunk);
+  }
+
   auto *NameTab = new NamePointersChunk(Names);
   auto *OrdinalTab = new ExportOrdinalChunk(Names.size());
   auto *Dir = new ExportDirectoryChunk(MaxOrdinal, Names.size(), DLLName,
@@ -550,6 +563,8 @@ EdataContents::EdataContents() {
   Chunks.push_back(std::unique_ptr<Chunk>(OrdinalTab));
   for (Chunk *C : Names)
     Chunks.push_back(std::unique_ptr<Chunk>(C));
+  for (Chunk *C : Forwards)
+    Chunks.push_back(std::unique_ptr<Chunk>(C));
 }
 
 } // namespace coff

Modified: vendor/lld/dist/COFF/Driver.cpp
==============================================================================
--- vendor/lld/dist/COFF/Driver.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/COFF/Driver.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -586,6 +586,8 @@ void LinkerDriver::link(llvm::ArrayRef<c
 
     // Windows specific -- Make sure we resolve all dllexported symbols.
     for (Export &E : Config->Exports) {
+      if (!E.ForwardTo.empty())
+        continue;
       E.Sym = addUndefined(E.Name);
       if (!E.Directives)
         Symtab.mangleMaybe(E.Sym);

Modified: vendor/lld/dist/COFF/DriverUtils.cpp
==============================================================================
--- vendor/lld/dist/COFF/DriverUtils.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/COFF/DriverUtils.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -321,7 +321,8 @@ void createSideBySideManifest() {
 }
 
 // Parse a string in the form of
-// "<name>[=<internalname>][, at ordinal[,NONAME]][,DATA][,PRIVATE]".
+// "<name>[=<internalname>][, at ordinal[,NONAME]][,DATA][,PRIVATE]"
+// or "<name>=<dllname>.<name>".
 // Used for parsing /export arguments.
 Export parseExport(StringRef Arg) {
   Export E;
@@ -329,12 +330,25 @@ Export parseExport(StringRef Arg) {
   std::tie(E.Name, Rest) = Arg.split(",");
   if (E.Name.empty())
     goto err;
+
   if (E.Name.find('=') != StringRef::npos) {
-    std::tie(E.ExtName, E.Name) = E.Name.split("=");
+    StringRef X, Y;
+    std::tie(X, Y) = E.Name.split("=");
+
+    // If "<name>=<dllname>.<name>".
+    if (Y.find(".") != StringRef::npos) {
+      E.Name = X;
+      E.ForwardTo = Y;
+      return E;
+    }
+
+    E.ExtName = X;
+    E.Name = Y;
     if (E.Name.empty())
       goto err;
   }
 
+  // If "<name>=<internalname>[, at ordinal[,NONAME]][,DATA][,PRIVATE]"
   while (!Rest.empty()) {
     StringRef Tok;
     std::tie(Tok, Rest) = Rest.split(",");
@@ -388,15 +402,22 @@ void fixupExports() {
   }
 
   for (Export &E : Config->Exports) {
-    if (Undefined *U = cast_or_null<Undefined>(E.Sym->WeakAlias)) {
+    if (!E.ForwardTo.empty()) {
+      E.SymbolName = E.Name;
+    } else if (Undefined *U = cast_or_null<Undefined>(E.Sym->WeakAlias)) {
       E.SymbolName = U->getName();
     } else {
       E.SymbolName = E.Sym->getName();
     }
   }
 
-  for (Export &E : Config->Exports)
-    E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName);
+  for (Export &E : Config->Exports) {
+    if (!E.ForwardTo.empty()) {
+      E.ExportName = undecorate(E.Name);
+    } else {
+      E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName);
+    }
+  }
 
   // Uniquefy by name.
   std::map<StringRef, Export *> Map;

Modified: vendor/lld/dist/COFF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist/COFF/InputFiles.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/COFF/InputFiles.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -23,7 +23,6 @@
 using namespace llvm::COFF;
 using namespace llvm::object;
 using namespace llvm::support::endian;
-using llvm::RoundUpToAlignment;
 using llvm::Triple;
 using llvm::support::ulittle32_t;
 using llvm::sys::fs::file_magic;

Modified: vendor/lld/dist/COFF/Writer.cpp
==============================================================================
--- vendor/lld/dist/COFF/Writer.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/COFF/Writer.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -163,13 +163,13 @@ void OutputSection::addChunk(Chunk *C) {
   Chunks.push_back(C);
   C->setOutputSection(this);
   uint64_t Off = Header.VirtualSize;
-  Off = RoundUpToAlignment(Off, C->getAlign());
+  Off = align(Off, C->getAlign());
   C->setRVA(Off);
   C->setOutputSectionOff(Off);
   Off += C->getSize();
   Header.VirtualSize = Off;
   if (C->hasData())
-    Header.SizeOfRawData = RoundUpToAlignment(Off, SectorSize);
+    Header.SizeOfRawData = align(Off, SectorSize);
 }
 
 void OutputSection::addPermissions(uint32_t C) {
@@ -448,15 +448,14 @@ void Writer::createSymbolAndStringTable(
   OutputSection *LastSection = OutputSections.back();
   // We position the symbol table to be adjacent to the end of the last section.
   uint64_t FileOff =
-      LastSection->getFileOff() +
-      RoundUpToAlignment(LastSection->getRawSize(), SectorSize);
+      LastSection->getFileOff() + align(LastSection->getRawSize(), SectorSize);
   if (!OutputSymtab.empty()) {
     PointerToSymbolTable = FileOff;
     FileOff += OutputSymtab.size() * sizeof(coff_symbol16);
   }
   if (!Strtab.empty())
     FileOff += Strtab.size() + 4;
-  FileSize = RoundUpToAlignment(FileOff, SectorSize);
+  FileSize = align(FileOff, SectorSize);
 }
 
 // Visits all sections to assign incremental, non-overlapping RVAs and
@@ -467,7 +466,7 @@ void Writer::assignAddresses() {
                   sizeof(coff_section) * OutputSections.size();
   SizeOfHeaders +=
       Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header);
-  SizeOfHeaders = RoundUpToAlignment(SizeOfHeaders, SectorSize);
+  SizeOfHeaders = align(SizeOfHeaders, SectorSize);
   uint64_t RVA = 0x1000; // The first page is kept unmapped.
   FileSize = SizeOfHeaders;
   // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because
@@ -481,10 +480,10 @@ void Writer::assignAddresses() {
       addBaserels(Sec);
     Sec->setRVA(RVA);
     Sec->setFileOffset(FileSize);
-    RVA += RoundUpToAlignment(Sec->getVirtualSize(), PageSize);
-    FileSize += RoundUpToAlignment(Sec->getRawSize(), SectorSize);
+    RVA += align(Sec->getVirtualSize(), PageSize);
+    FileSize += align(Sec->getRawSize(), SectorSize);
   }
-  SizeOfImage = SizeOfHeaders + RoundUpToAlignment(RVA - 0x1000, PageSize);
+  SizeOfImage = SizeOfHeaders + align(RVA - 0x1000, PageSize);
 }
 
 template <typename PEHeaderTy> void Writer::writeHeader() {

Modified: vendor/lld/dist/ELF/CMakeLists.txt
==============================================================================
--- vendor/lld/dist/ELF/CMakeLists.txt	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/CMakeLists.txt	Wed Jan 13 20:06:04 2016	(r293846)
@@ -2,7 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Options.td)
 tablegen(LLVM Options.inc -gen-opt-parser-defs)
 add_public_tablegen_target(ELFOptionsTableGen)
 
-add_llvm_library(lldELF2
+add_lld_library(lldELF2
   Driver.cpp
   DriverUtils.cpp
   Error.cpp

Modified: vendor/lld/dist/ELF/Driver.cpp
==============================================================================
--- vendor/lld/dist/ELF/Driver.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/Driver.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -26,10 +26,10 @@ using namespace llvm::object;
 using namespace lld;
 using namespace lld::elf2;
 
-Configuration *lld::elf2::Config;
-LinkerDriver *lld::elf2::Driver;
+Configuration *elf2::Config;
+LinkerDriver *elf2::Driver;
 
-void lld::elf2::link(ArrayRef<const char *> Args) {
+void elf2::link(ArrayRef<const char *> Args) {
   Configuration C;
   LinkerDriver D;
   Config = &C;
@@ -42,9 +42,9 @@ static std::pair<ELFKind, uint16_t> pars
     return {ELF32BEKind, EM_MIPS};
   if (S == "elf32ltsmip")
     return {ELF32LEKind, EM_MIPS};
-  if (S == "elf32ppc")
+  if (S == "elf32ppc" || S == "elf32ppc_fbsd")
     return {ELF32BEKind, EM_PPC};
-  if (S == "elf64ppc")
+  if (S == "elf64ppc" || S == "elf64ppc_fbsd")
     return {ELF64BEKind, EM_PPC64};
   if (S == "elf_i386")
     return {ELF32LEKind, EM_386};
@@ -107,6 +107,24 @@ void LinkerDriver::addFile(StringRef Pat
   }
 }
 
+// Some command line options or some combinations of them are not allowed.
+// This function checks for such errors.
+static void checkOptions(opt::InputArgList &Args) {
+  // Traditional linkers can generate re-linkable object files instead
+  // of executables or DSOs. We don't support that since the feature
+  // does not seem to provide more value than the static archiver.
+  if (Args.hasArg(OPT_relocatable))
+    error("-r option is not supported. Use 'ar' command instead.");
+
+  // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
+  // table which is a relatively new feature.
+  if (Config->EMachine == EM_MIPS && Config->GnuHash)
+    error("The .gnu.hash section is not compatible with the MIPS target.");
+
+  if (Config->EMachine == EM_AMDGPU && !Config->Entry.empty())
+    error("-e option is not valid for AMDGPU.");
+}
+
 static StringRef
 getString(opt::InputArgList &Args, unsigned Key, StringRef Default = "") {
   if (auto *Arg = Args.getLastArg(Key))
@@ -125,13 +143,9 @@ void LinkerDriver::main(ArrayRef<const c
   initSymbols();
 
   opt::InputArgList Args = parseArgs(&Alloc, ArgsArr);
+  readConfigs(Args);
   createFiles(Args);
-
-  // Traditional linkers can generate re-linkable object files instead
-  // of executables or DSOs. We don't support that since the feature
-  // does not seem to provide more value than the static archiver.
-  if (Args.hasArg(OPT_relocatable))
-    error("-r option is not supported. Use 'ar' command instead.");
+  checkOptions(Args);
 
   switch (Config->EKind) {
   case ELF32LEKind:
@@ -151,7 +165,8 @@ void LinkerDriver::main(ArrayRef<const c
   }
 }
 
-void LinkerDriver::createFiles(opt::InputArgList &Args) {
+// Initializes Config members by the command line options.
+void LinkerDriver::readConfigs(opt::InputArgList &Args) {
   for (auto *Arg : Args.filtered(OPT_L))
     Config->SearchPaths.push_back(Arg->getValue());
 
@@ -162,10 +177,9 @@ void LinkerDriver::createFiles(opt::Inpu
     Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":");
 
   if (auto *Arg = Args.getLastArg(OPT_m)) {
+    // Parse ELF{32,64}{LE,BE} and CPU type.
     StringRef S = Arg->getValue();
-    std::pair<ELFKind, uint16_t> P = parseEmulation(S);
-    Config->EKind = P.first;
-    Config->EMachine = P.second;
+    std::tie(Config->EKind, Config->EMachine) = parseEmulation(S);
     Config->Emulation = S;
   }
 
@@ -217,7 +231,9 @@ void LinkerDriver::createFiles(opt::Inpu
 
   for (auto *Arg : Args.filtered(OPT_undefined))
     Config->Undefined.push_back(Arg->getValue());
+}
 
+void LinkerDriver::createFiles(opt::InputArgList &Args) {
   for (auto *Arg : Args) {
     switch (Arg->getOption().getID()) {
     case OPT_l:
@@ -250,9 +266,6 @@ void LinkerDriver::createFiles(opt::Inpu
 
   if (Files.empty())
     error("no input files.");
-
-  if (Config->GnuHash && Config->EMachine == EM_MIPS)
-    error("The .gnu.hash section is not compatible with the MIPS target.");
 }
 
 template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
@@ -261,7 +274,10 @@ template <class ELFT> void LinkerDriver:
 
   if (!Config->Shared) {
     // Add entry symbol.
-    if (Config->Entry.empty())
+    //
+    // There is no entry symbol for AMDGPU binaries, so skip adding one to avoid
+    // having and undefined symbol.
+    if (Config->Entry.empty() && Config->EMachine != EM_AMDGPU)
       Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start";
 
     // In the assembly for 32 bit x86 the _GLOBAL_OFFSET_TABLE_ symbol
@@ -288,8 +304,9 @@ template <class ELFT> void LinkerDriver:
 
   if (Config->EMachine == EM_MIPS) {
     // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
-    // start of function and gp pointer into GOT.
-    Config->MipsGpDisp = Symtab.addIgnored("_gp_disp");
+    // start of function and gp pointer into GOT. Use 'strong' variant of
+    // the addIgnored to prevent '_gp_disp' substitution.
+    Config->MipsGpDisp = Symtab.addIgnoredStrong("_gp_disp");
 
     // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
     // so that it points to an absolute address which is relative to GOT.
@@ -304,6 +321,9 @@ template <class ELFT> void LinkerDriver:
   for (StringRef S : Config->Undefined)
     Symtab.addUndefinedOpt(S);
 
+  for (auto *Arg : Args.filtered(OPT_wrap))
+    Symtab.wrap(Arg->getValue());
+
   if (Config->OutputFile.empty())
     Config->OutputFile = "a.out";
 

Modified: vendor/lld/dist/ELF/Driver.h
==============================================================================
--- vendor/lld/dist/ELF/Driver.h	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/Driver.h	Wed Jan 13 20:06:04 2016	(r293846)
@@ -26,14 +26,12 @@ void link(ArrayRef<const char *> Args);
 class LinkerDriver {
 public:
   void main(ArrayRef<const char *> Args);
-  void createFiles(llvm::opt::InputArgList &Args);
-  template <class ELFT> void link(llvm::opt::InputArgList &Args);
-
   void addFile(StringRef Path);
 
 private:
-  template <template <class> class T>
-  std::unique_ptr<InputFile> createELFInputFile(MemoryBufferRef MB);
+  void readConfigs(llvm::opt::InputArgList &Args);
+  void createFiles(llvm::opt::InputArgList &Args);
+  template <class ELFT> void link(llvm::opt::InputArgList &Args);
 
   llvm::BumpPtrAllocator Alloc;
   bool WholeArchive = false;

Modified: vendor/lld/dist/ELF/DriverUtils.cpp
==============================================================================
--- vendor/lld/dist/ELF/DriverUtils.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/DriverUtils.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -51,8 +51,8 @@ public:
 };
 
 // Parses a given list of options.
-opt::InputArgList lld::elf2::parseArgs(llvm::BumpPtrAllocator *A,
-                                       ArrayRef<const char *> Argv) {
+opt::InputArgList elf2::parseArgs(llvm::BumpPtrAllocator *A,
+                                  ArrayRef<const char *> Argv) {
   // Make InputArgList from string vectors.
   ELFOptTable Table;
   unsigned MissingIndex;
@@ -79,7 +79,7 @@ opt::InputArgList lld::elf2::parseArgs(l
   return Args;
 }
 
-std::string lld::elf2::findFromSearchPaths(StringRef Path) {
+std::string elf2::findFromSearchPaths(StringRef Path) {
   for (StringRef Dir : Config->SearchPaths) {
     std::string FullPath = buildSysrootedPath(Dir, Path);
     if (sys::fs::exists(FullPath))
@@ -90,7 +90,7 @@ std::string lld::elf2::findFromSearchPat
 
 // Searches a given library from input search paths, which are filled
 // from -L command line switches. Returns a path to an existent library file.
-std::string lld::elf2::searchLibrary(StringRef Path) {
+std::string elf2::searchLibrary(StringRef Path) {
   std::vector<std::string> Names;
   if (Path[0] == ':') {
     Names.push_back(Path.drop_front());
@@ -110,7 +110,7 @@ std::string lld::elf2::searchLibrary(Str
 // Makes a path by concatenating Dir and File.
 // If Dir starts with '=' the result will be preceded by Sysroot,
 // which can be set with --sysroot command line switch.
-std::string lld::elf2::buildSysrootedPath(StringRef Dir, StringRef File) {
+std::string elf2::buildSysrootedPath(StringRef Dir, StringRef File) {
   SmallString<128> Path;
   if (Dir.startswith("="))
     sys::path::append(Path, Config->Sysroot, Dir.substr(1), File);

Modified: vendor/lld/dist/ELF/InputFiles.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputFiles.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/InputFiles.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -92,7 +92,9 @@ typename ObjectFile<ELFT>::Elf_Sym_Range
 }
 
 template <class ELFT> uint32_t ObjectFile<ELFT>::getMipsGp0() const {
-  return MipsReginfo ? MipsReginfo->getGp0() : 0;
+  if (MipsReginfo)
+    return MipsReginfo->Reginfo->ri_gp_value;
+  return 0;
 }
 
 template <class ELFT>
@@ -132,13 +134,13 @@ StringRef ObjectFile<ELFT>::getShtGroupS
 }
 
 template <class ELFT>
-ArrayRef<typename ObjectFile<ELFT>::GroupEntryType>
+ArrayRef<typename ObjectFile<ELFT>::uint32_X>
 ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
   const ELFFile<ELFT> &Obj = this->ELFObj;
-  ErrorOr<ArrayRef<GroupEntryType>> EntriesOrErr =
-      Obj.template getSectionContentsAsArray<GroupEntryType>(&Sec);
+  ErrorOr<ArrayRef<uint32_X>> EntriesOrErr =
+      Obj.template getSectionContentsAsArray<uint32_X>(&Sec);
   error(EntriesOrErr);
-  ArrayRef<GroupEntryType> Entries = *EntriesOrErr;
+  ArrayRef<uint32_X> Entries = *EntriesOrErr;
   if (Entries.empty() || Entries[0] != GRP_COMDAT)
     error("Unsupported SHT_GROUP format");
   return Entries.slice(1);
@@ -187,8 +189,7 @@ void ObjectFile<ELFT>::initializeSection
       Sections[I] = &InputSection<ELFT>::Discarded;
       if (ComdatGroups.insert(getShtGroupSignature(Sec)).second)
         continue;
-      for (GroupEntryType E : getShtGroupEntries(Sec)) {
-        uint32_t SecIndex = E;
+      for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
         if (SecIndex >= Size)
           error("Invalid section index in group");
         Sections[SecIndex] = &InputSection<ELFT>::Discarded;

Modified: vendor/lld/dist/ELF/InputFiles.h
==============================================================================
--- vendor/lld/dist/ELF/InputFiles.h	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/InputFiles.h	Wed Jan 13 20:06:04 2016	(r293846)
@@ -91,10 +91,13 @@ template <class ELFT> class ObjectFile :
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word;
   typedef typename llvm::object::ELFFile<ELFT>::uintX_t uintX_t;
 
+  // uint32 in ELFT's byte order
   typedef llvm::support::detail::packed_endian_specific_integral<
-      uint32_t, ELFT::TargetEndianness, 2> GroupEntryType;
+      uint32_t, ELFT::TargetEndianness, 2>
+      uint32_X;
+
   StringRef getShtGroupSignature(const Elf_Shdr &Sec);
-  ArrayRef<GroupEntryType> getShtGroupEntries(const Elf_Shdr &Sec);
+  ArrayRef<uint32_X> getShtGroupEntries(const Elf_Shdr &Sec);
 
 public:
   static bool classof(const InputFile *F) {

Modified: vendor/lld/dist/ELF/InputSection.cpp
==============================================================================
--- vendor/lld/dist/ELF/InputSection.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/InputSection.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -52,7 +52,9 @@ InputSectionBase<ELFT>::getOffset(uintX_
   case Merge:
     return cast<MergeInputSection<ELFT>>(this)->getOffset(Offset);
   case MipsReginfo:
-    return cast<MipsReginfoInputSection<ELFT>>(this)->getOffset(Offset);
+    // MIPS .reginfo sections are consumed by the linker,
+    // so it should never be copied to output.
+    llvm_unreachable("MIPS .reginfo reached writeTo().");
   }
   llvm_unreachable("Invalid section kind");
 }
@@ -209,7 +211,6 @@ void InputSectionBase<ELFT>::relocate(ui
     uintX_t SymVA = getSymVA<ELFT>(*Body);
     if (Target->relocNeedsPlt(Type, *Body)) {
       SymVA = Out<ELFT>::Plt->getEntryAddr(*Body);
-      Type = Target->getPltRefReloc(Type);
     } else if (Target->relocNeedsGot(Type, *Body)) {
       SymVA = Out<ELFT>::Got->getEntryAddr(*Body);
       if (Body->isTls())
@@ -217,8 +218,13 @@ void InputSectionBase<ELFT>::relocate(ui
     } else if (!Target->needsCopyRel(Type, *Body) &&
                isa<SharedSymbol<ELFT>>(*Body)) {
       continue;
-    } else if (Target->isTlsDynReloc(Type, *Body) ||
-               Target->isSizeDynReloc(Type, *Body)) {
+    } else if (Target->isTlsDynReloc(Type, *Body)) {
+      continue;
+    } else if (Target->isSizeReloc(Type) && canBePreempted(Body, false)) {
+      // A SIZE relocation is supposed to set a symbol size, but if a symbol
+      // can be preempted, the size at runtime may be different than link time.
+      // If that's the case, we leave the field alone rather than filling it
+      // with a possibly incorrect value.
       continue;
     } else if (Config->EMachine == EM_MIPS) {
       if (Type == R_MIPS_HI16 && Body == Config->MipsGpDisp)
@@ -346,22 +352,13 @@ MergeInputSection<ELFT>::getOffset(uintX
 
 template <class ELFT>
 MipsReginfoInputSection<ELFT>::MipsReginfoInputSection(ObjectFile<ELFT> *F,
-                                                       const Elf_Shdr *Header)
-    : InputSectionBase<ELFT>(F, Header, InputSectionBase<ELFT>::MipsReginfo) {}
-
-template <class ELFT>
-uint32_t MipsReginfoInputSection<ELFT>::getGeneralMask() const {
-  ArrayRef<uint8_t> D = this->getSectionData();
-  if (D.size() != sizeof(Elf_Mips_RegInfo))
-    error("Invalid size of .reginfo section");
-  return reinterpret_cast<const Elf_Mips_RegInfo *>(D.data())->ri_gprmask;
-}
-
-template <class ELFT> uint32_t MipsReginfoInputSection<ELFT>::getGp0() const {
+                                                       const Elf_Shdr *Hdr)
+    : InputSectionBase<ELFT>(F, Hdr, InputSectionBase<ELFT>::MipsReginfo) {
+  // Initialize this->Reginfo.
   ArrayRef<uint8_t> D = this->getSectionData();
-  if (D.size() != sizeof(Elf_Mips_RegInfo))
+  if (D.size() != sizeof(Elf_Mips_RegInfo<ELFT>))
     error("Invalid size of .reginfo section");
-  return reinterpret_cast<const Elf_Mips_RegInfo *>(D.data())->ri_gp_value;
+  Reginfo = reinterpret_cast<const Elf_Mips_RegInfo<ELFT> *>(D.data());
 }
 
 template <class ELFT>

Modified: vendor/lld/dist/ELF/InputSection.h
==============================================================================
--- vendor/lld/dist/ELF/InputSection.h	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/InputSection.h	Wed Jan 13 20:06:04 2016	(r293846)
@@ -177,16 +177,13 @@ public:
 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
 template <class ELFT>
 class MipsReginfoInputSection : public InputSectionBase<ELFT> {
-  typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
   typedef typename llvm::object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
 
 public:
-  MipsReginfoInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Header);
-
-  uint32_t getGeneralMask() const;
-  uint32_t getGp0() const;
-
+  MipsReginfoInputSection(ObjectFile<ELFT> *F, const Elf_Shdr *Hdr);
   static bool classof(const InputSectionBase<ELFT> *S);
+
+  const llvm::object::Elf_Mips_RegInfo<ELFT> *Reginfo;
 };
 
 } // namespace elf2

Modified: vendor/lld/dist/ELF/LinkerScript.cpp
==============================================================================
--- vendor/lld/dist/ELF/LinkerScript.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/LinkerScript.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -312,7 +312,7 @@ static bool isUnderSysroot(StringRef Pat
 }
 
 // Entry point. The other functions or classes are private to this file.
-void lld::elf2::readLinkerScript(BumpPtrAllocator *A, MemoryBufferRef MB) {
+void elf2::readLinkerScript(BumpPtrAllocator *A, MemoryBufferRef MB) {
   StringRef Path = MB.getBufferIdentifier();
   LinkerScript(A, MB.getBuffer(), isUnderSysroot(Path)).run();
 }

Modified: vendor/lld/dist/ELF/MarkLive.cpp
==============================================================================
--- vendor/lld/dist/ELF/MarkLive.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/MarkLive.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -79,7 +79,7 @@ template <class ELFT> static bool isRese
 // This is the main function of the garbage collector.
 // Starting from GC-root sections, this function visits all reachable
 // sections to set their "Live" bits.
-template <class ELFT> void lld::elf2::markLive(SymbolTable<ELFT> *Symtab) {
+template <class ELFT> void elf2::markLive(SymbolTable<ELFT> *Symtab) {
   SmallVector<InputSection<ELFT> *, 256> Q;
 
   auto Enqueue = [&](InputSectionBase<ELFT> *Sec) {
@@ -116,16 +116,15 @@ template <class ELFT> void lld::elf2::ma
   // Preserve special sections.
   for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab->getObjectFiles())
     for (InputSectionBase<ELFT> *Sec : F->getSections())
-      if (Sec && Sec != &InputSection<ELFT>::Discarded)
-        if (isReserved(Sec))
-          Enqueue(Sec);
+      if (Sec && Sec != &InputSection<ELFT>::Discarded && isReserved(Sec))
+        Enqueue(Sec);
 
   // Mark all reachable sections.
   while (!Q.empty())
     forEachSuccessor<ELFT>(Q.pop_back_val(), Enqueue);
 }
 
-template void lld::elf2::markLive<ELF32LE>(SymbolTable<ELF32LE> *);
-template void lld::elf2::markLive<ELF32BE>(SymbolTable<ELF32BE> *);
-template void lld::elf2::markLive<ELF64LE>(SymbolTable<ELF64LE> *);
-template void lld::elf2::markLive<ELF64BE>(SymbolTable<ELF64BE> *);
+template void elf2::markLive<ELF32LE>(SymbolTable<ELF32LE> *);
+template void elf2::markLive<ELF32BE>(SymbolTable<ELF32BE> *);
+template void elf2::markLive<ELF64LE>(SymbolTable<ELF64LE> *);
+template void elf2::markLive<ELF64BE>(SymbolTable<ELF64BE> *);

Modified: vendor/lld/dist/ELF/Options.td
==============================================================================
--- vendor/lld/dist/ELF/Options.td	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/Options.td	Wed Jan 13 20:06:04 2016	(r293846)
@@ -109,6 +109,9 @@ def verbose : Flag<["--"], "verbose">;
 def whole_archive : Flag<["--", "-"], "whole-archive">,
   HelpText<"Force load of all members in a static library">;
 
+def wrap : Separate<["--", "-"], "wrap">, MetaVarName<"<symbol>">,
+  HelpText<"Use wrapper functions for symbol">;
+
 def z : JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">,
   HelpText<"Linker option extensions">;
 
@@ -136,6 +139,7 @@ def alias_soname_soname : Separate<["-"]
 def alias_script_T : Separate<["-"], "T">, Alias<script>;
 def alias_strip_all: Flag<["-"], "s">, Alias<strip_all>;
 def alias_undefined_u : Separate<["-"], "u">, Alias<undefined>;
+def alias_wrap_wrap : Joined<["--", "-"], "wrap=">, Alias<wrap>;
 
 // Our symbol resolution algorithm handles symbols in archive files differently
 // than traditional linkers, so we don't need --start-group and --end-group.

Modified: vendor/lld/dist/ELF/OutputSections.cpp
==============================================================================
--- vendor/lld/dist/ELF/OutputSections.cpp	Wed Jan 13 20:05:34 2016	(r293845)
+++ vendor/lld/dist/ELF/OutputSections.cpp	Wed Jan 13 20:06:04 2016	(r293846)
@@ -21,21 +21,20 @@ using namespace llvm::ELF;
 using namespace lld;
 using namespace lld::elf2;
 
-bool lld::elf2::HasGotOffRel = false;
+bool elf2::HasGotOffRel = false;
 
 template <class ELFT>
-OutputSectionBase<ELFT>::OutputSectionBase(StringRef Name, uint32_t sh_type,
-                                           uintX_t sh_flags)
+OutputSectionBase<ELFT>::OutputSectionBase(StringRef Name, uint32_t Type,
+                                           uintX_t Flags)
     : Name(Name) {
   memset(&Header, 0, sizeof(Elf_Shdr));
-  Header.sh_type = sh_type;
-  Header.sh_flags = sh_flags;
+  Header.sh_type = Type;
+  Header.sh_flags = Flags;
 }
 
 template <class ELFT>
 GotPltSection<ELFT>::GotPltSection()
-    : OutputSectionBase<ELFT>(".got.plt", llvm::ELF::SHT_PROGBITS,
-                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE) {
+    : OutputSectionBase<ELFT>(".got.plt", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
   this->Header.sh_addralign = sizeof(uintX_t);
 }
 
@@ -70,10 +69,9 @@ template <class ELFT> void GotPltSection
 
 template <class ELFT>
 GotSection<ELFT>::GotSection()
-    : OutputSectionBase<ELFT>(".got", llvm::ELF::SHT_PROGBITS,
-                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE) {
+    : OutputSectionBase<ELFT>(".got", SHT_PROGBITS, SHF_ALLOC | SHF_WRITE) {
   if (Config->EMachine == EM_MIPS)
-    this->Header.sh_flags |= llvm::ELF::SHF_MIPS_GPREL;
+    this->Header.sh_flags |= SHF_MIPS_GPREL;
   this->Header.sh_addralign = sizeof(uintX_t);
 }
 
@@ -120,7 +118,7 @@ const SymbolBody *GotSection<ELFT>::getM
 
 template <class ELFT>
 unsigned GotSection<ELFT>::getMipsLocalEntriesNum() const {
-  // TODO: Update when the suppoort of GOT entries for local symbols is added.
+  // TODO: Update when the support of GOT entries for local symbols is added.
   return Target->getGotHeaderEntriesNum();
 }
 
@@ -151,8 +149,7 @@ template <class ELFT> void GotSection<EL
 
 template <class ELFT>
 PltSection<ELFT>::PltSection()
-    : OutputSectionBase<ELFT>(".plt", llvm::ELF::SHT_PROGBITS,
-                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_EXECINSTR) {
+    : OutputSectionBase<ELFT>(".plt", SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR) {
   this->Header.sh_addralign = 16;
 }
 
@@ -199,9 +196,7 @@ template <class ELFT> void PltSection<EL
 
 template <class ELFT>
 RelocationSection<ELFT>::RelocationSection(StringRef Name, bool IsRela)
-    : OutputSectionBase<ELFT>(Name,
-                              IsRela ? llvm::ELF::SHT_RELA : llvm::ELF::SHT_REL,
-                              llvm::ELF::SHF_ALLOC),
+    : OutputSectionBase<ELFT>(Name, IsRela ? SHT_RELA : SHT_REL, SHF_ALLOC),
       IsRela(IsRela) {
   this->Header.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
   this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
@@ -328,15 +323,14 @@ template <class ELFT> void RelocationSec
 
 template <class ELFT>
 InterpSection<ELFT>::InterpSection()
-    : OutputSectionBase<ELFT>(".interp", llvm::ELF::SHT_PROGBITS,
-                              llvm::ELF::SHF_ALLOC) {
+    : OutputSectionBase<ELFT>(".interp", SHT_PROGBITS, SHF_ALLOC) {
   this->Header.sh_size = Config->DynamicLinker.size() + 1;
   this->Header.sh_addralign = 1;
 }
 
 template <class ELFT>
 void OutputSectionBase<ELFT>::writeHeaderTo(Elf_Shdr *SHdr) {
-  Header.sh_name = Out<ELFT>::ShStrTab->getOffset(Name);
+  Header.sh_name = Out<ELFT>::ShStrTab->addString(Name);
   *SHdr = Header;
 }
 
@@ -346,8 +340,7 @@ template <class ELFT> void InterpSection
 
 template <class ELFT>
 HashTableSection<ELFT>::HashTableSection()
-    : OutputSectionBase<ELFT>(".hash", llvm::ELF::SHT_HASH,
-                              llvm::ELF::SHF_ALLOC) {
+    : OutputSectionBase<ELFT>(".hash", SHT_HASH, SHF_ALLOC) {
   this->Header.sh_entsize = sizeof(Elf_Word);
   this->Header.sh_addralign = sizeof(Elf_Word);
 }
@@ -404,8 +397,7 @@ static uint32_t hashGnu(StringRef Name) 
 
 template <class ELFT>
 GnuHashTableSection<ELFT>::GnuHashTableSection()
-    : OutputSectionBase<ELFT>(".gnu.hash", llvm::ELF::SHT_GNU_HASH,
-                              llvm::ELF::SHF_ALLOC) {
+    : OutputSectionBase<ELFT>(".gnu.hash", SHT_GNU_HASH, SHF_ALLOC) {
   this->Header.sh_entsize = ELFT::Is64Bits ? 0 : 4;
   this->Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
 }
@@ -545,8 +537,7 @@ void GnuHashTableSection<ELFT>::addSymbo
 
 template <class ELFT>
 DynamicSection<ELFT>::DynamicSection(SymbolTable<ELFT> &SymTab)
-    : OutputSectionBase<ELFT>(".dynamic", llvm::ELF::SHT_DYNAMIC,
-                              llvm::ELF::SHF_ALLOC | llvm::ELF::SHF_WRITE),
+    : OutputSectionBase<ELFT>(".dynamic", SHT_DYNAMIC, SHF_ALLOC | SHF_WRITE),
       SymTab(SymTab) {
   Elf_Shdr &Header = this->Header;
   Header.sh_addralign = ELFT::Is64Bits ? 8 : 4;
@@ -556,7 +547,7 @@ DynamicSection<ELFT>::DynamicSection(Sym
   // See "Special Section" in Chapter 4 in the following document:
   // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
   if (Config->EMachine == EM_MIPS)
-    Header.sh_flags = llvm::ELF::SHF_ALLOC;
+    Header.sh_flags = SHF_ALLOC;
 }
 
 template <class ELFT> void DynamicSection<ELFT>::finalize() {
@@ -590,12 +581,12 @@ template <class ELFT> void DynamicSectio
 
   if (!Config->RPath.empty()) {
     ++NumEntries; // DT_RUNPATH / DT_RPATH
-    Out<ELFT>::DynStrTab->add(Config->RPath);
+    Out<ELFT>::DynStrTab->reserve(Config->RPath);
   }
 
   if (!Config->SoName.empty()) {
     ++NumEntries; // DT_SONAME
-    Out<ELFT>::DynStrTab->add(Config->SoName);
+    Out<ELFT>::DynStrTab->reserve(Config->SoName);
   }
 
   if (PreInitArraySec)
@@ -608,7 +599,7 @@ template <class ELFT> void DynamicSectio
   for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles()) {
     if (!F->isNeeded())
       continue;
-    Out<ELFT>::DynStrTab->add(F->getSoName());
+    Out<ELFT>::DynStrTab->reserve(F->getSoName());
     ++NumEntries;
   }
 
@@ -696,7 +687,7 @@ template <class ELFT> void DynamicSectio
   WritePtr(DT_SYMTAB, Out<ELFT>::DynSymTab->getVA());
   WritePtr(DT_SYMENT, sizeof(Elf_Sym));
   WritePtr(DT_STRTAB, Out<ELFT>::DynStrTab->getVA());
-  WriteVal(DT_STRSZ, Out<ELFT>::DynStrTab->data().size());
+  WriteVal(DT_STRSZ, Out<ELFT>::DynStrTab->getSize());
   if (Out<ELFT>::GnuHashTab)
     WritePtr(DT_GNU_HASH, Out<ELFT>::GnuHashTab->getVA());
   if (Out<ELFT>::HashTab)
@@ -712,10 +703,10 @@ template <class ELFT> void DynamicSectio
   //   DT_RPATH is used for indirect dependencies as well.
   if (!Config->RPath.empty())
     WriteVal(Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
-             Out<ELFT>::DynStrTab->getOffset(Config->RPath));
+             Out<ELFT>::DynStrTab->addString(Config->RPath));
 
   if (!Config->SoName.empty())
-    WriteVal(DT_SONAME, Out<ELFT>::DynStrTab->getOffset(Config->SoName));
+    WriteVal(DT_SONAME, Out<ELFT>::DynStrTab->addString(Config->SoName));
 
   auto WriteArray = [&](int32_t T1, int32_t T2,
                         const OutputSectionBase<ELFT> *Sec) {
@@ -730,7 +721,7 @@ template <class ELFT> void DynamicSectio
 
   for (const std::unique_ptr<SharedFile<ELFT>> &F : SymTab.getSharedFiles())
     if (F->isNeeded())
-      WriteVal(DT_NEEDED, Out<ELFT>::DynStrTab->getOffset(F->getSoName()));
+      WriteVal(DT_NEEDED, Out<ELFT>::DynStrTab->addString(F->getSoName()));
 
   if (InitSym)
     WritePtr(DT_INIT, getSymVA<ELFT>(*InitSym));
@@ -765,9 +756,9 @@ template <class ELFT> void DynamicSectio
 }
 
 template <class ELFT>
-OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t sh_type,
-                                   uintX_t sh_flags)
-    : OutputSectionBase<ELFT>(Name, sh_type, sh_flags) {}
+OutputSection<ELFT>::OutputSection(StringRef Name, uint32_t Type,
+                                   uintX_t Flags)
+    : OutputSectionBase<ELFT>(Name, Type, Flags) {}
 
 template <class ELFT>
 void OutputSection<ELFT>::addSection(InputSectionBase<ELFT> *C) {
@@ -779,14 +770,14 @@ void OutputSection<ELFT>::addSection(Inp
     this->Header.sh_addralign = Align;
 
   uintX_t Off = this->Header.sh_size;
-  Off = RoundUpToAlignment(Off, Align);
+  Off = align(Off, Align);
   S->OutSecOff = Off;
   Off += S->getSize();
   this->Header.sh_size = Off;
 }
 
 template <class ELFT>
-typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) {
+typename ELFFile<ELFT>::uintX_t elf2::getSymVA(const SymbolBody &S) {
   switch (S.kind()) {
   case SymbolBody::DefinedSyntheticKind: {
     auto &D = cast<DefinedSynthetic<ELFT>>(S);
@@ -797,6 +788,11 @@ typename ELFFile<ELFT>::uintX_t lld::elf
     InputSectionBase<ELFT> *SC = DR.Section;
     if (!SC)
       return DR.Sym.st_value;
+
+    // Symbol offsets for AMDGPU need to be the offset in bytes of the symbol
+    // from the beginning of the section.
+    if (Config->EMachine == EM_AMDGPU)
+      return SC->getOffset(DR.Sym);
     if (DR.Sym.getType() == STT_TLS)
       return SC->OutSec->getVA() + SC->getOffset(DR.Sym) -
              Out<ELFT>::TlsPhdr->p_vaddr;
@@ -824,9 +820,9 @@ typename ELFFile<ELFT>::uintX_t lld::elf
 // For non-local symbols, use getSymVA instead.
 template <class ELFT, bool IsRela>
 typename ELFFile<ELFT>::uintX_t
-lld::elf2::getLocalRelTarget(const ObjectFile<ELFT> &File,
-                             const Elf_Rel_Impl<ELFT, IsRela> &RI,
-                             typename ELFFile<ELFT>::uintX_t Addend) {
+elf2::getLocalRelTarget(const ObjectFile<ELFT> &File,
+                        const Elf_Rel_Impl<ELFT, IsRela> &RI,
+                        typename ELFFile<ELFT>::uintX_t Addend) {
   typedef typename ELFFile<ELFT>::Elf_Sym Elf_Sym;
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
 
@@ -868,7 +864,7 @@ lld::elf2::getLocalRelTarget(const Objec
 
 // Returns true if a symbol can be replaced at load-time by a symbol
 // with the same name defined in other ELF executable or DSO.
-bool lld::elf2::canBePreempted(const SymbolBody *Body, bool NeedsGot) {
+bool elf2::canBePreempted(const SymbolBody *Body, bool NeedsGot) {
   if (!Body)
     return false;  // Body is a local symbol.
   if (Body->isShared())
@@ -910,9 +906,9 @@ template <class ELFT> void OutputSection
 }
 
 template <class ELFT>
-EHOutputSection<ELFT>::EHOutputSection(StringRef Name, uint32_t sh_type,
-                                       uintX_t sh_flags)
-    : OutputSectionBase<ELFT>(Name, sh_type, sh_flags) {}
+EHOutputSection<ELFT>::EHOutputSection(StringRef Name, uint32_t Type,
+                                       uintX_t Flags)
+    : OutputSectionBase<ELFT>(Name, Type, Flags) {}
 
 template <class ELFT>
 EHRegion<ELFT>::EHRegion(EHInputSection<ELFT> *S, unsigned Index)
@@ -980,7 +976,7 @@ void EHOutputSection<ELFT>::addSectionAu
       auto P = CieMap.insert(std::make_pair(CieInfo, Cies.size()));
       if (P.second) {
         Cies.push_back(C);
-        this->Header.sh_size += RoundUpToAlignment(Length, sizeof(uintX_t));
+        this->Header.sh_size += align(Length, sizeof(uintX_t));
       }
       OffsetToIndex[Offset] = P.first->second;
     } else {
@@ -993,7 +989,7 @@ void EHOutputSection<ELFT>::addSectionAu
         if (I == OffsetToIndex.end())
           error("Invalid CIE reference");
         Cies[I->second].Fdes.push_back(EHRegion<ELFT>(S, Index));
-        this->Header.sh_size += RoundUpToAlignment(Length, sizeof(uintX_t));
+        this->Header.sh_size += align(Length, sizeof(uintX_t));
       }
     }
 
@@ -1046,7 +1042,7 @@ static typename ELFFile<ELFT>::uintX_t w
                                                             uint8_t *Buf) {
   typedef typename ELFFile<ELFT>::uintX_t uintX_t;
   const endianness E = ELFT::TargetEndianness;
-  uint64_t Len = RoundUpToAlignment(Data.size(), sizeof(uintX_t));
+  uint64_t Len = align(Data.size(), sizeof(uintX_t));
   write32<E>(Buf, Len - 4);
   memcpy(Buf + 4, Data.data() + 4, Data.size() - 4);
   return Len;
@@ -1083,9 +1079,9 @@ template <class ELFT> void EHOutputSecti
 }
 
 template <class ELFT>
-MergeOutputSection<ELFT>::MergeOutputSection(StringRef Name, uint32_t sh_type,
-                                             uintX_t sh_flags)
-    : OutputSectionBase<ELFT>(Name, sh_type, sh_flags) {}
+MergeOutputSection<ELFT>::MergeOutputSection(StringRef Name, uint32_t Type,

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


More information about the svn-src-all mailing list