[lld] 7fd3849 - [ELF] Move --print-archive-stats= and --why-extract= beside --warn-backrefs report

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sun Feb 27 12:23:14 PST 2022


Author: Fangrui Song
Date: 2022-02-27T20:23:09Z
New Revision: 7fd3849b3565a1e22719338c6cebea9bcb023fca

URL: https://github.com/llvm/llvm-project/commit/7fd3849b3565a1e22719338c6cebea9bcb023fca
DIFF: https://github.com/llvm/llvm-project/commit/7fd3849b3565a1e22719338c6cebea9bcb023fca.diff

LOG: [ELF] Move --print-archive-stats= and --why-extract= beside --warn-backrefs report

So that early errors don't suppress their output.

Added: 
    

Modified: 
    lld/ELF/Driver.cpp
    lld/ELF/Driver.h
    lld/ELF/MapFile.cpp
    lld/ELF/MapFile.h
    lld/ELF/Symbols.cpp
    lld/ELF/Symbols.h
    lld/ELF/Writer.cpp
    lld/test/ELF/why-extract.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 4951eb91edb67..78350260ee4b0 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -103,7 +103,6 @@ bool elf::link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
     objectFiles.clear();
     sharedFiles.clear();
     backwardReferences.clear();
-    whyExtract.clear();
     symAux.clear();
 
     tar = nullptr;
@@ -1697,7 +1696,7 @@ static void handleUndefined(Symbol *sym, const char *option) {
     return;
   sym->extract();
   if (!config->whyExtract.empty())
-    whyExtract.emplace_back(option, sym->file, *sym);
+    driver->whyExtract.emplace_back(option, sym->file, *sym);
 }
 
 // As an extension to GNU linkers, lld supports a variant of `-u`
@@ -1733,6 +1732,55 @@ static void handleLibcall(StringRef name) {
     sym->extract();
 }
 
+void LinkerDriver::writeArchiveStats() const {
+  if (config->printArchiveStats.empty())
+    return;
+
+  std::error_code ec;
+  raw_fd_ostream os(config->printArchiveStats, ec, sys::fs::OF_None);
+  if (ec) {
+    error("--print-archive-stats=: cannot open " + config->printArchiveStats +
+          ": " + ec.message());
+    return;
+  }
+
+  os << "members\textracted\tarchive\n";
+
+  SmallVector<StringRef, 0> archives;
+  DenseMap<CachedHashStringRef, unsigned> all, extracted;
+  for (ELFFileBase *file : objectFiles)
+    if (file->archiveName.size())
+      ++extracted[CachedHashStringRef(file->archiveName)];
+  for (BitcodeFile *file : bitcodeFiles)
+    if (file->archiveName.size())
+      ++extracted[CachedHashStringRef(file->archiveName)];
+  for (std::pair<StringRef, unsigned> f : archiveFiles) {
+    unsigned &v = extracted[CachedHashString(f.first)];
+    os << f.second << '\t' << v << '\t' << f.first << '\n';
+    // If the archive occurs multiple times, other instances have a count of 0.
+    v = 0;
+  }
+}
+
+void LinkerDriver::writeWhyExtract() const {
+  if (config->whyExtract.empty())
+    return;
+
+  std::error_code ec;
+  raw_fd_ostream os(config->whyExtract, ec, sys::fs::OF_None);
+  if (ec) {
+    error("cannot open --why-extract= file " + config->whyExtract + ": " +
+          ec.message());
+    return;
+  }
+
+  os << "reference\textracted\tsymbol\n";
+  for (auto &entry : whyExtract) {
+    os << std::get<0>(entry) << '\t' << toString(std::get<1>(entry)) << '\t'
+       << toString(std::get<2>(entry)) << '\n';
+  }
+}
+
 // Handle --dependency-file=<path>. If that option is given, lld creates a
 // file at a given path with the following contents:
 //
@@ -2436,8 +2484,11 @@ void LinkerDriver::link(opt::InputArgList &args) {
   const size_t numObjsBeforeLTO = objectFiles.size();
   invokeELFT(compileBitcodeFiles, skipLinkedOutput);
 
-  // Symbol resolution finished. Report backward reference problems.
+  // Symbol resolution finished. Report backward reference problems,
+  // --print-archive-stats=, and --why-extract=.
   reportBackrefs();
+  writeArchiveStats();
+  writeWhyExtract();
   if (errorCount())
     return;
 

diff  --git a/lld/ELF/Driver.h b/lld/ELF/Driver.h
index 8a7e5e4e2df47..0ec47d2a8121e 100644
--- a/lld/ELF/Driver.h
+++ b/lld/ELF/Driver.h
@@ -17,6 +17,8 @@
 
 namespace lld {
 namespace elf {
+class InputFile;
+class Symbol;
 
 extern std::unique_ptr<class LinkerDriver> driver;
 
@@ -31,6 +33,8 @@ class LinkerDriver {
   void inferMachineType();
   void link(llvm::opt::InputArgList &args);
   template <class ELFT> void compileBitcodeFiles(bool skipLinkedOutput);
+  void writeArchiveStats() const;
+  void writeWhyExtract() const;
 
   // True if we are in --whole-archive and --no-whole-archive.
   bool inWholeArchive = false;
@@ -42,9 +46,12 @@ class LinkerDriver {
   std::unique_ptr<BitcodeCompiler> lto;
 
   std::vector<InputFile *> files;
+  SmallVector<std::pair<StringRef, unsigned>, 0> archiveFiles;
 
 public:
-  SmallVector<std::pair<StringRef, unsigned>, 0> archiveFiles;
+  // A tuple of (reference, extractedFile, sym). Used by --why-extract=.
+  SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>, 0>
+      whyExtract;
 };
 
 // Parses command line options.

diff  --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index 54cacb8780dc8..461c3a0b7d60f 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -19,7 +19,6 @@
 //===----------------------------------------------------------------------===//
 
 #include "MapFile.h"
-#include "Driver.h"
 #include "InputFiles.h"
 #include "LinkerScript.h"
 #include "OutputSections.h"
@@ -211,25 +210,6 @@ static void writeMapFile(raw_fd_ostream &os) {
   }
 }
 
-void elf::writeWhyExtract() {
-  if (config->whyExtract.empty())
-    return;
-
-  std::error_code ec;
-  raw_fd_ostream os(config->whyExtract, ec, sys::fs::OF_None);
-  if (ec) {
-    error("cannot open --why-extract= file " + config->whyExtract + ": " +
-          ec.message());
-    return;
-  }
-
-  os << "reference\textracted\tsymbol\n";
-  for (auto &entry : whyExtract) {
-    os << std::get<0>(entry) << '\t' << toString(std::get<1>(entry)) << '\t'
-       << toString(std::get<2>(entry)) << '\n';
-  }
-}
-
 // Output a cross reference table to stdout. This is for --cref.
 //
 // For each global symbol, we print out a file that defines the symbol
@@ -294,33 +274,3 @@ void elf::writeMapAndCref() {
   if (config->cref)
     writeCref(os);
 }
-
-void elf::writeArchiveStats() {
-  if (config->printArchiveStats.empty())
-    return;
-
-  std::error_code ec;
-  raw_fd_ostream os(config->printArchiveStats, ec, sys::fs::OF_None);
-  if (ec) {
-    error("--print-archive-stats=: cannot open " + config->printArchiveStats +
-          ": " + ec.message());
-    return;
-  }
-
-  os << "members\textracted\tarchive\n";
-
-  SmallVector<StringRef, 0> archives;
-  DenseMap<CachedHashStringRef, unsigned> all, extracted;
-  for (ELFFileBase *file : objectFiles)
-    if (file->archiveName.size())
-      ++extracted[CachedHashStringRef(file->archiveName)];
-  for (BitcodeFile *file : bitcodeFiles)
-    if (file->archiveName.size())
-      ++extracted[CachedHashStringRef(file->archiveName)];
-  for (std::pair<StringRef, unsigned> f : driver->archiveFiles) {
-    unsigned &v = extracted[CachedHashString(f.first)];
-    os << f.second << '\t' << v << '\t' << f.first << '\n';
-    // If the archive occurs multiple times, other instances have a count of 0.
-    v = 0;
-  }
-}

diff  --git a/lld/ELF/MapFile.h b/lld/ELF/MapFile.h
index df548988c03b4..36bd1d2d1703d 100644
--- a/lld/ELF/MapFile.h
+++ b/lld/ELF/MapFile.h
@@ -12,8 +12,6 @@
 namespace lld {
 namespace elf {
 void writeMapAndCref();
-void writeWhyExtract();
-void writeArchiveStats();
 } // namespace elf
 } // namespace lld
 

diff  --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index b142ea6812b7f..4fab75ab7526c 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -7,6 +7,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "Symbols.h"
+#include "Driver.h"
 #include "InputFiles.h"
 #include "InputSection.h"
 #include "OutputSections.h"
@@ -50,8 +51,6 @@ Defined *ElfSym::riscvGlobalPointer;
 Defined *ElfSym::tlsModuleBase;
 DenseMap<const Symbol *, std::pair<const InputFile *, const InputFile *>>
     elf::backwardReferences;
-SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>, 0>
-    elf::whyExtract;
 SmallVector<SymbolAux, 0> elf::symAux;
 
 static uint64_t getSymVA(const Symbol &sym, int64_t addend) {
@@ -288,7 +287,7 @@ void elf::printTraceSymbol(const Symbol &sym, StringRef name) {
 
 static void recordWhyExtract(const InputFile *reference,
                              const InputFile &extracted, const Symbol &sym) {
-  whyExtract.emplace_back(toString(reference), &extracted, sym);
+  driver->whyExtract.emplace_back(toString(reference), &extracted, sym);
 }
 
 void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {

diff  --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 920569bcecf9b..4108cb8220aa9 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -569,11 +569,6 @@ extern llvm::DenseMap<const Symbol *,
                       std::pair<const InputFile *, const InputFile *>>
     backwardReferences;
 
-// A tuple of (reference, extractedFile, sym). Used by --why-extract=.
-extern SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>,
-                   0>
-    whyExtract;
-
 } // namespace elf
 } // namespace lld
 

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index 59177ffcacf52..62c4d0b5a366e 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -561,14 +561,10 @@ template <class ELFT> void Writer<ELFT>::run() {
   for (Partition &part : partitions)
     setPhdrs(part);
 
-
-  // Handle --print-map(-M)/--Map, --why-extract=, --cref and
-  // --print-archive-stats=. Dump them before checkSections() because the files
-  // may be useful in case checkSections() or openFile() fails, for example, due
-  // to an erroneous file size.
+  // Handle --print-map(-M)/--Map and --cref. Dump them before checkSections()
+  // because the files may be useful in case checkSections() or openFile()
+  // fails, for example, due to an erroneous file size.
   writeMapAndCref();
-  writeWhyExtract();
-  writeArchiveStats();
 
   if (config->checkSections)
     checkSections();

diff  --git a/lld/test/ELF/why-extract.s b/lld/test/ELF/why-extract.s
index 3b3a11f28cd74..a41db8d9fd49a 100644
--- a/lld/test/ELF/why-extract.s
+++ b/lld/test/ELF/why-extract.s
@@ -30,14 +30,21 @@
 # CHECK2-NEXT:main.o	a_b.a(a_b.o)	a
 # CHECK2-NEXT:a_b.a(a_b.o)	b.a(b.o)	b()
 
+## An undefined symbol error does not suppress the output.
+# RUN: not ld.lld main.o a_b.a -o /dev/null --why-extract=why3.txt
+# RUN: FileCheck %s --input-file=why3.txt --check-prefix=CHECK3 --match-full-lines --strict-whitespace
+
 ## Check that backward references are supported.
 ## - means stdout.
-# RUN: ld.lld b.a a_b.a main.o -o /dev/null --why-extract=- | FileCheck %s --check-prefix=CHECK3
+# RUN: ld.lld b.a a_b.a main.o -o /dev/null --why-extract=- | FileCheck %s --check-prefix=CHECK4
 
 #      CHECK3:reference	extracted	symbol
-# CHECK3-NEXT:a_b.a(a_b.o)	b.a(b.o)	b()
 # CHECK3-NEXT:main.o	a_b.a(a_b.o)	a
 
+#      CHECK4:reference	extracted	symbol
+# CHECK4-NEXT:a_b.a(a_b.o)	b.a(b.o)	b()
+# CHECK4-NEXT:main.o	a_b.a(a_b.o)	a
+
 # RUN: ld.lld main.o a_b.a b.a -o /dev/null --no-demangle --why-extract=- | FileCheck %s --check-prefix=MANGLED
 
 # MANGLED: a_b.a(a_b.o)	b.a(b.o)	_Z1bv


        


More information about the llvm-commits mailing list