Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Apr 2017 21:21:19 +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: r317226 - in vendor/lld/dist: COFF ELF test/COFF test/ELF
Message-ID:  <201704202121.v3KLLJBr002994@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dim
Date: Thu Apr 20 21:21:19 2017
New Revision: 317226
URL: https://svnweb.freebsd.org/changeset/base/317226

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

Added:
  vendor/lld/dist/test/ELF/compress-debug-sections.s   (contents, props changed)
Modified:
  vendor/lld/dist/COFF/Driver.cpp
  vendor/lld/dist/COFF/DriverUtils.cpp
  vendor/lld/dist/ELF/Config.h
  vendor/lld/dist/ELF/Driver.cpp
  vendor/lld/dist/ELF/LinkerScript.cpp
  vendor/lld/dist/ELF/LinkerScript.h
  vendor/lld/dist/ELF/Options.td
  vendor/lld/dist/ELF/OutputSections.cpp
  vendor/lld/dist/ELF/OutputSections.h
  vendor/lld/dist/ELF/Writer.cpp
  vendor/lld/dist/test/COFF/msvclto.ll
  vendor/lld/dist/test/ELF/tls-offset.s

Modified: vendor/lld/dist/COFF/Driver.cpp
==============================================================================
--- vendor/lld/dist/COFF/Driver.cpp	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/COFF/Driver.cpp	Thu Apr 20 21:21:19 2017	(r317226)
@@ -509,7 +509,7 @@ filterBitcodeFiles(StringRef Path, std::
 
 // Create response file contents and invoke the MSVC linker.
 void LinkerDriver::invokeMSVC(opt::InputArgList &Args) {
-  std::string Rsp = "/nologo ";
+  std::string Rsp = "/nologo\n";
   std::vector<std::string> Temps;
 
   for (auto *Arg : Args) {
@@ -528,14 +528,14 @@ void LinkerDriver::invokeMSVC(opt::Input
     case OPT_INPUT: {
       if (Optional<StringRef> Path = doFindFile(Arg->getValue())) {
         if (Optional<std::string> S = filterBitcodeFiles(*Path, Temps))
-          Rsp += quote(*S) + " ";
+          Rsp += quote(*S) + "\n";
         continue;
       }
-      Rsp += quote(Arg->getValue()) + " ";
+      Rsp += quote(Arg->getValue()) + "\n";
       break;
     }
     default:
-      Rsp += toString(Arg) + " ";
+      Rsp += toString(Arg) + "\n";
     }
   }
 

Modified: vendor/lld/dist/COFF/DriverUtils.cpp
==============================================================================
--- vendor/lld/dist/COFF/DriverUtils.cpp	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/COFF/DriverUtils.cpp	Thu Apr 20 21:21:19 2017	(r317226)
@@ -634,7 +634,7 @@ void runMSVCLinker(std::string Rsp, Arra
   std::vector<TemporaryFile> Temps;
   for (StringRef S : Objects) {
     Temps.emplace_back("lto", "obj", S);
-    Rsp += quote(Temps.back().Path) + " ";
+    Rsp += quote(Temps.back().Path) + "\n";
   }
 
   log("link.exe " + Rsp);

Modified: vendor/lld/dist/ELF/Config.h
==============================================================================
--- vendor/lld/dist/ELF/Config.h	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/ELF/Config.h	Thu Apr 20 21:21:19 2017	(r317226)
@@ -104,6 +104,7 @@ struct Configuration {
   bool Bsymbolic;
   bool BsymbolicFunctions;
   bool ColorDiagnostics = false;
+  bool CompressDebugSections;
   bool DefineCommon;
   bool Demangle = true;
   bool DisableVerify;

Modified: vendor/lld/dist/ELF/Driver.cpp
==============================================================================
--- vendor/lld/dist/ELF/Driver.cpp	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/ELF/Driver.cpp	Thu Apr 20 21:21:19 2017	(r317226)
@@ -45,6 +45,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Object/Decompressor.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/TarWriter.h"
 #include "llvm/Support/TargetSelect.h"
@@ -564,12 +565,24 @@ static std::vector<StringRef> getLines(M
   return Ret;
 }
 
+static bool getCompressDebugSections(opt::InputArgList &Args) {
+  if (auto *Arg = Args.getLastArg(OPT_compress_debug_sections)) {
+    StringRef S = Arg->getValue();
+    if (S == "zlib")
+      return zlib::isAvailable();
+    if (S != "none")
+      error("unknown --compress-debug-sections value: " + S);
+  }
+  return false;
+}
+
 // Initializes Config members by the command line options.
 void LinkerDriver::readConfigs(opt::InputArgList &Args) {
   Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
   Config->AuxiliaryList = getArgs(Args, OPT_auxiliary);
   Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
   Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
+  Config->CompressDebugSections = getCompressDebugSections(Args);
   Config->DefineCommon = getArg(Args, OPT_define_common, OPT_no_define_common,
                                 !Args.hasArg(OPT_relocatable));
   Config->Demangle = getArg(Args, OPT_demangle, OPT_no_demangle, true);

Modified: vendor/lld/dist/ELF/LinkerScript.cpp
==============================================================================
--- vendor/lld/dist/ELF/LinkerScript.cpp	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/ELF/LinkerScript.cpp	Thu Apr 20 21:21:19 2017	(r317226)
@@ -413,6 +413,56 @@ void LinkerScript::processCommands(Outpu
   CurOutSec = nullptr;
 }
 
+void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) {
+  std::vector<BaseCommand *> Commands;
+
+  // Define start address
+  uint64_t StartAddr = Config->ImageBase;
+  if (AllocateHeader)
+    StartAddr += elf::getHeaderSize();
+
+  // The Sections with -T<section> are sorted in order of ascending address
+  // we must use this if it is lower than StartAddr as calls to setDot() must
+  // be monotonically increasing
+  if (!Config->SectionStartMap.empty()) {
+    uint64_t LowestSecStart = Config->SectionStartMap.begin()->second;
+    StartAddr = std::min(StartAddr, LowestSecStart);
+  }
+  Commands.push_back(
+      make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
+
+  // For each OutputSection that needs a VA fabricate an OutputSectionCommand
+  // with an InputSectionDescription describing the InputSections
+  for (OutputSection *Sec : *OutputSections) {
+    if (!(Sec->Flags & SHF_ALLOC))
+      continue;
+
+    auto I = Config->SectionStartMap.find(Sec->Name);
+    if (I != Config->SectionStartMap.end())
+      Commands.push_back(
+          make<SymbolAssignment>(".", [=] { return I->second; }, ""));
+
+    auto *OSCmd = make<OutputSectionCommand>(Sec->Name);
+    OSCmd->Sec = Sec;
+    if (Sec->PageAlign)
+      OSCmd->AddrExpr = [=] {
+        return alignTo(Script->getDot(), Config->MaxPageSize);
+      };
+    Commands.push_back(OSCmd);
+    if (Sec->Sections.size()) {
+      auto *ISD = make<InputSectionDescription>("");
+      OSCmd->Commands.push_back(ISD);
+      for (InputSection *ISec : Sec->Sections) {
+        ISD->Sections.push_back(ISec);
+        ISec->Assigned = true;
+      }
+    }
+  }
+  // SECTIONS commands run before other non SECTIONS commands
+  Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end());
+  Opt.Commands = std::move(Commands);
+}
+
 // Add sections that didn't match any sections command.
 void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
   for (InputSectionBase *S : InputSections)

Modified: vendor/lld/dist/ELF/LinkerScript.h
==============================================================================
--- vendor/lld/dist/ELF/LinkerScript.h	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/ELF/LinkerScript.h	Thu Apr 20 21:21:19 2017	(r317226)
@@ -256,6 +256,7 @@ public:
   bool isDefined(StringRef S);
 
   std::vector<OutputSection *> *OutputSections;
+  void fabricateDefaultCommands(bool AllocateHeader);
   void addOrphanSections(OutputSectionFactory &Factory);
   void removeEmptyCommands();
   void adjustSectionsBeforeSorting();

Modified: vendor/lld/dist/ELF/Options.td
==============================================================================
--- vendor/lld/dist/ELF/Options.td	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/ELF/Options.td	Thu Apr 20 21:21:19 2017	(r317226)
@@ -22,6 +22,9 @@ def build_id: F<"build-id">, HelpText<"G
 
 def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">;
 
+def compress_debug_sections : J<"compress-debug-sections=">,
+  HelpText<"Compress DWARF debug sections">;
+
 def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
   HelpText<"Add a directory to the library search path">;
 

Modified: vendor/lld/dist/ELF/OutputSections.cpp
==============================================================================
--- vendor/lld/dist/ELF/OutputSections.cpp	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/ELF/OutputSections.cpp	Thu Apr 20 21:21:19 2017	(r317226)
@@ -16,6 +16,7 @@
 #include "SyntheticSections.h"
 #include "Target.h"
 #include "Threads.h"
+#include "llvm/Support/Compression.h"
 #include "llvm/Support/Dwarf.h"
 #include "llvm/Support/MD5.h"
 #include "llvm/Support/MathExtras.h"
@@ -83,6 +84,33 @@ static bool compareByFilePosition(InputS
   return LA->OutSecOff < LB->OutSecOff;
 }
 
+// Compress section contents if this section contains debug info.
+template <class ELFT> void OutputSection::maybeCompress() {
+  typedef typename ELFT::Chdr Elf_Chdr;
+
+  // Compress only DWARF debug sections.
+  if (!Config->CompressDebugSections || (Flags & SHF_ALLOC) ||
+      !Name.startswith(".debug_"))
+    return;
+
+  // Create a section header.
+  ZDebugHeader.resize(sizeof(Elf_Chdr));
+  auto *Hdr = reinterpret_cast<Elf_Chdr *>(ZDebugHeader.data());
+  Hdr->ch_type = ELFCOMPRESS_ZLIB;
+  Hdr->ch_size = Size;
+  Hdr->ch_addralign = Alignment;
+
+  // Write section contents to a temporary buffer and compress it.
+  std::vector<uint8_t> Buf(Size);
+  writeTo<ELFT>(Buf.data());
+  if (Error E = zlib::compress(toStringRef(Buf), CompressedData))
+    fatal("compress failed: " + llvm::toString(std::move(E)));
+
+  // Update section headers.
+  Size = sizeof(Elf_Chdr) + CompressedData.size();
+  Flags |= SHF_COMPRESSED;
+}
+
 template <class ELFT> void OutputSection::finalize() {
   if ((this->Flags & SHF_LINK_ORDER) && !this->Sections.empty()) {
     std::sort(Sections.begin(), Sections.end(), compareByFilePosition);
@@ -245,6 +273,15 @@ uint32_t OutputSection::getFiller() {
 template <class ELFT> void OutputSection::writeTo(uint8_t *Buf) {
   Loc = Buf;
 
+  // We may have already rendered compressed content when using
+  // -compress-debug-sections option. Write it together with header.
+  if (!CompressedData.empty()) {
+    memcpy(Buf, ZDebugHeader.data(), ZDebugHeader.size());
+    memcpy(Buf + ZDebugHeader.size(), CompressedData.data(),
+           CompressedData.size());
+    return;
+  }
+
   // Write leading padding.
   uint32_t Filler = getFiller();
   if (Filler)
@@ -422,6 +459,11 @@ template void OutputSection::finalize<EL
 template void OutputSection::finalize<ELF64LE>();
 template void OutputSection::finalize<ELF64BE>();
 
+template void OutputSection::maybeCompress<ELF32LE>();
+template void OutputSection::maybeCompress<ELF32BE>();
+template void OutputSection::maybeCompress<ELF64LE>();
+template void OutputSection::maybeCompress<ELF64BE>();
+
 template void OutputSection::writeTo<ELF32LE>(uint8_t *Buf);
 template void OutputSection::writeTo<ELF32BE>(uint8_t *Buf);
 template void OutputSection::writeTo<ELF64LE>(uint8_t *Buf);

Modified: vendor/lld/dist/ELF/OutputSections.h
==============================================================================
--- vendor/lld/dist/ELF/OutputSections.h	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/ELF/OutputSections.h	Thu Apr 20 21:21:19 2017	(r317226)
@@ -84,9 +84,14 @@ public:
   uint32_t getFiller();
   template <class ELFT> void writeTo(uint8_t *Buf);
   template <class ELFT> void finalize();
+  template <class ELFT> void maybeCompress();
   void assignOffsets();
   std::vector<InputSection *> Sections;
 
+  // Used for implementation of --compress-debug-sections option.
+  std::vector<uint8_t> ZDebugHeader;
+  llvm::SmallVector<char, 1> CompressedData;
+
   // Location in the output buffer.
   uint8_t *Loc = nullptr;
 };

Modified: vendor/lld/dist/ELF/Writer.cpp
==============================================================================
--- vendor/lld/dist/ELF/Writer.cpp	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/ELF/Writer.cpp	Thu Apr 20 21:21:19 2017	(r317226)
@@ -19,6 +19,7 @@
 #include "SymbolTable.h"
 #include "SyntheticSections.h"
 #include "Target.h"
+#include "Threads.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/FileOutputBuffer.h"
@@ -58,7 +59,6 @@ private:
   std::vector<PhdrEntry> createPhdrs();
   void removeEmptyPTLoad();
   void addPtArmExid(std::vector<PhdrEntry> &Phdrs);
-  void assignAddresses();
   void assignFileOffsets();
   void assignFileOffsetsBinary();
   void setPhdrs();
@@ -250,13 +250,11 @@ template <class ELFT> void Writer<ELFT>:
   if (Config->Relocatable) {
     assignFileOffsets();
   } else {
-    if (Script->Opt.HasSections) {
-      Script->assignAddresses(Phdrs);
-    } else {
+    if (!Script->Opt.HasSections) {
       fixSectionAlignments();
-      assignAddresses();
-      Script->processNonSectionCommands();
+      Script->fabricateDefaultCommands(Config->MaxPageSize);
     }
+    Script->assignAddresses(Phdrs);
 
     // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
     // 0 sized region. This has to be done late since only after assignAddresses
@@ -1216,6 +1214,12 @@ template <class ELFT> void Writer<ELFT>:
   for (OutputSection *Sec : OutputSections)
     Sec->finalize<ELFT>();
 
+  // If -compressed-debug-sections is specified, we need to compress
+  // .debug_* sections. Do it right now because it changes the size of
+  // output sections.
+  parallelForEach(OutputSections.begin(), OutputSections.end(),
+                  [](OutputSection *S) { S->maybeCompress<ELFT>(); });
+
   // createThunks may have added local symbols to the static symbol table
   applySynthetic({In<ELFT>::SymTab, In<ELFT>::ShStrTab, In<ELFT>::StrTab},
                  [](SyntheticSection *SS) { SS->postThunkContents(); });
@@ -1502,37 +1506,6 @@ template <class ELFT> void Writer<ELFT>:
   AllocateHeader = allocateHeaders(Phdrs, OutputSections, Min);
 }
 
-// Assign VAs (addresses at run-time) to output sections.
-template <class ELFT> void Writer<ELFT>::assignAddresses() {
-  uint64_t VA = Config->ImageBase;
-  uint64_t ThreadBssOffset = 0;
-
-  if (AllocateHeader)
-    VA += getHeaderSize();
-
-  for (OutputSection *Sec : OutputSections) {
-    uint32_t Alignment = Sec->Alignment;
-    if (Sec->PageAlign)
-      Alignment = std::max<uint32_t>(Alignment, Config->MaxPageSize);
-
-    auto I = Config->SectionStartMap.find(Sec->Name);
-    if (I != Config->SectionStartMap.end())
-      VA = I->second;
-
-    // We only assign VAs to allocated sections.
-    if (needsPtLoad(Sec)) {
-      VA = alignTo(VA, Alignment);
-      Sec->Addr = VA;
-      VA += Sec->Size;
-    } else if (Sec->Flags & SHF_TLS && Sec->Type == SHT_NOBITS) {
-      uint64_t TVA = VA + ThreadBssOffset;
-      TVA = alignTo(TVA, Alignment);
-      Sec->Addr = TVA;
-      ThreadBssOffset = TVA - VA + Sec->Size;
-    }
-  }
-}
-
 // Adjusts the file alignment for a given output section and returns
 // its new file offset. The file offset must be the same with its
 // virtual address (modulo the page size) so that the loader can load

Modified: vendor/lld/dist/test/COFF/msvclto.ll
==============================================================================
--- vendor/lld/dist/test/COFF/msvclto.ll	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/test/COFF/msvclto.ll	Thu Apr 20 21:21:19 2017	(r317226)
@@ -5,7 +5,8 @@
 ; RUN:   /entry:main /verbose > %t.log || true
 ; RUN: FileCheck %s < %t.log
 
-; CHECK: /opt:icf /entry:main /verbose
+; CHECK: /opt:icf /entry:main
+; CHECK: /verbose
 
 target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-pc-windows-msvc"

Added: vendor/lld/dist/test/ELF/compress-debug-sections.s
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ vendor/lld/dist/test/ELF/compress-debug-sections.s	Thu Apr 20 21:21:19 2017	(r317226)
@@ -0,0 +1,32 @@
+# REQUIRES: x86, zlib
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld %t.o -o %t1 --compress-debug-sections=zlib
+
+# RUN: llvm-objdump -s %t1 | FileCheck %s --check-prefix=ZLIBCONTENT
+# ZLIBCONTENT:     Contents of section .debug_str:
+# ZLIBCONTENT-NOT: AAAAAAAAA
+
+# RUN: llvm-readobj -s %t1 | FileCheck %s --check-prefix=ZLIBFLAGS
+# ZLIBFLAGS:       Section {
+# ZLIBFLAGS:         Index:
+# ZLIBFLAGS:         Name: .debug_str
+# ZLIBFLAGS-NEXT:    Type: SHT_PROGBITS
+# ZLIBFLAGS-NEXT:    Flags [
+# ZLIBFLAGS-NEXT:      SHF_COMPRESSED
+
+# RUN: llvm-dwarfdump %t1 -debug-dump=str | \
+# RUN:   FileCheck %s --check-prefix=DEBUGSTR
+# DEBUGSTR:     .debug_str contents:
+# DEBUGSTR-NEXT:  AAAAAAAAAAAAAAAAAAAAAAAAAAA
+# DEBUGSTR-NEXT:  BBBBBBBBBBBBBBBBBBBBBBBBBBB
+
+# RUN: not ld.lld %t.o -o %t1 --compress-debug-sections=zlib-gabi 2>&1 | \
+# RUN:   FileCheck -check-prefix=ERR %s
+# ERR: unknown --compress-debug-sections value: zlib-gabi
+
+.section .debug_str,"MS",@progbits,1
+.Linfo_string0:
+  .asciz "AAAAAAAAAAAAAAAAAAAAAAAAAAA"
+.Linfo_string1:
+  .asciz "BBBBBBBBBBBBBBBBBBBBBBBBBBB"

Modified: vendor/lld/dist/test/ELF/tls-offset.s
==============================================================================
--- vendor/lld/dist/test/ELF/tls-offset.s	Thu Apr 20 21:21:16 2017	(r317225)
+++ vendor/lld/dist/test/ELF/tls-offset.s	Thu Apr 20 21:21:19 2017	(r317226)
@@ -2,7 +2,17 @@
 // RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
 // RUN: ld.lld %t -o %tout
 // RUN: llvm-readobj -s %tout | FileCheck %s
-
+// RUN: echo "SECTIONS { \
+// RUN:   . = 0x201000; \
+// RUN:   .text : { *(.text) } \
+// RUN:   . = 0x202000; \
+// RUN:   .tdata : { *(.tdata) } \
+// RUN:   .tbss : { *(.tbss) } \
+// RUN:   .data.rel.ro : { *(.data.rel.ro) } \
+// RUN: }" > %t.script
+        // RUN: ld.lld -T %t.script %t -o %tout2
+// RUN: echo SCRIPT
+// RUN: llvm-readobj -s %tout2 | FileCheck %s
         .global _start
 _start:
         retq
@@ -51,6 +61,6 @@ _start:
 // CHECK-NEXT:   SHF_ALLOC
 // CHECK-NEXT:   SHF_WRITE
 // CHECK-NEXT: ]
-// CHECK-NEXT: Address: 0x202004
-// CHECK-NEXT: Offset: 0x2004
+// CHECK-NEXT: Address: 0x202010
+// CHECK-NEXT: Offset: 0x2010
 // CHECK-NEXT: Size: 4



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