[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