Skip to content

Commit 7fd3849

Browse files
committed
[ELF] Move --print-archive-stats= and --why-extract= beside --warn-backrefs report
So that early errors don't suppress their output.
1 parent acf2000 commit 7fd3849

File tree

8 files changed

+76
-73
lines changed

8 files changed

+76
-73
lines changed

lld/ELF/Driver.cpp

+54-3
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ bool elf::link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
103103
objectFiles.clear();
104104
sharedFiles.clear();
105105
backwardReferences.clear();
106-
whyExtract.clear();
107106
symAux.clear();
108107

109108
tar = nullptr;
@@ -1697,7 +1696,7 @@ static void handleUndefined(Symbol *sym, const char *option) {
16971696
return;
16981697
sym->extract();
16991698
if (!config->whyExtract.empty())
1700-
whyExtract.emplace_back(option, sym->file, *sym);
1699+
driver->whyExtract.emplace_back(option, sym->file, *sym);
17011700
}
17021701

17031702
// As an extension to GNU linkers, lld supports a variant of `-u`
@@ -1733,6 +1732,55 @@ static void handleLibcall(StringRef name) {
17331732
sym->extract();
17341733
}
17351734

1735+
void LinkerDriver::writeArchiveStats() const {
1736+
if (config->printArchiveStats.empty())
1737+
return;
1738+
1739+
std::error_code ec;
1740+
raw_fd_ostream os(config->printArchiveStats, ec, sys::fs::OF_None);
1741+
if (ec) {
1742+
error("--print-archive-stats=: cannot open " + config->printArchiveStats +
1743+
": " + ec.message());
1744+
return;
1745+
}
1746+
1747+
os << "members\textracted\tarchive\n";
1748+
1749+
SmallVector<StringRef, 0> archives;
1750+
DenseMap<CachedHashStringRef, unsigned> all, extracted;
1751+
for (ELFFileBase *file : objectFiles)
1752+
if (file->archiveName.size())
1753+
++extracted[CachedHashStringRef(file->archiveName)];
1754+
for (BitcodeFile *file : bitcodeFiles)
1755+
if (file->archiveName.size())
1756+
++extracted[CachedHashStringRef(file->archiveName)];
1757+
for (std::pair<StringRef, unsigned> f : archiveFiles) {
1758+
unsigned &v = extracted[CachedHashString(f.first)];
1759+
os << f.second << '\t' << v << '\t' << f.first << '\n';
1760+
// If the archive occurs multiple times, other instances have a count of 0.
1761+
v = 0;
1762+
}
1763+
}
1764+
1765+
void LinkerDriver::writeWhyExtract() const {
1766+
if (config->whyExtract.empty())
1767+
return;
1768+
1769+
std::error_code ec;
1770+
raw_fd_ostream os(config->whyExtract, ec, sys::fs::OF_None);
1771+
if (ec) {
1772+
error("cannot open --why-extract= file " + config->whyExtract + ": " +
1773+
ec.message());
1774+
return;
1775+
}
1776+
1777+
os << "reference\textracted\tsymbol\n";
1778+
for (auto &entry : whyExtract) {
1779+
os << std::get<0>(entry) << '\t' << toString(std::get<1>(entry)) << '\t'
1780+
<< toString(std::get<2>(entry)) << '\n';
1781+
}
1782+
}
1783+
17361784
// Handle --dependency-file=<path>. If that option is given, lld creates a
17371785
// file at a given path with the following contents:
17381786
//
@@ -2436,8 +2484,11 @@ void LinkerDriver::link(opt::InputArgList &args) {
24362484
const size_t numObjsBeforeLTO = objectFiles.size();
24372485
invokeELFT(compileBitcodeFiles, skipLinkedOutput);
24382486

2439-
// Symbol resolution finished. Report backward reference problems.
2487+
// Symbol resolution finished. Report backward reference problems,
2488+
// --print-archive-stats=, and --why-extract=.
24402489
reportBackrefs();
2490+
writeArchiveStats();
2491+
writeWhyExtract();
24412492
if (errorCount())
24422493
return;
24432494

lld/ELF/Driver.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
namespace lld {
1919
namespace elf {
20+
class InputFile;
21+
class Symbol;
2022

2123
extern std::unique_ptr<class LinkerDriver> driver;
2224

@@ -31,6 +33,8 @@ class LinkerDriver {
3133
void inferMachineType();
3234
void link(llvm::opt::InputArgList &args);
3335
template <class ELFT> void compileBitcodeFiles(bool skipLinkedOutput);
36+
void writeArchiveStats() const;
37+
void writeWhyExtract() const;
3438

3539
// True if we are in --whole-archive and --no-whole-archive.
3640
bool inWholeArchive = false;
@@ -42,9 +46,12 @@ class LinkerDriver {
4246
std::unique_ptr<BitcodeCompiler> lto;
4347

4448
std::vector<InputFile *> files;
49+
SmallVector<std::pair<StringRef, unsigned>, 0> archiveFiles;
4550

4651
public:
47-
SmallVector<std::pair<StringRef, unsigned>, 0> archiveFiles;
52+
// A tuple of (reference, extractedFile, sym). Used by --why-extract=.
53+
SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>, 0>
54+
whyExtract;
4855
};
4956

5057
// Parses command line options.

lld/ELF/MapFile.cpp

-50
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
//===----------------------------------------------------------------------===//
2020

2121
#include "MapFile.h"
22-
#include "Driver.h"
2322
#include "InputFiles.h"
2423
#include "LinkerScript.h"
2524
#include "OutputSections.h"
@@ -211,25 +210,6 @@ static void writeMapFile(raw_fd_ostream &os) {
211210
}
212211
}
213212

214-
void elf::writeWhyExtract() {
215-
if (config->whyExtract.empty())
216-
return;
217-
218-
std::error_code ec;
219-
raw_fd_ostream os(config->whyExtract, ec, sys::fs::OF_None);
220-
if (ec) {
221-
error("cannot open --why-extract= file " + config->whyExtract + ": " +
222-
ec.message());
223-
return;
224-
}
225-
226-
os << "reference\textracted\tsymbol\n";
227-
for (auto &entry : whyExtract) {
228-
os << std::get<0>(entry) << '\t' << toString(std::get<1>(entry)) << '\t'
229-
<< toString(std::get<2>(entry)) << '\n';
230-
}
231-
}
232-
233213
// Output a cross reference table to stdout. This is for --cref.
234214
//
235215
// For each global symbol, we print out a file that defines the symbol
@@ -294,33 +274,3 @@ void elf::writeMapAndCref() {
294274
if (config->cref)
295275
writeCref(os);
296276
}
297-
298-
void elf::writeArchiveStats() {
299-
if (config->printArchiveStats.empty())
300-
return;
301-
302-
std::error_code ec;
303-
raw_fd_ostream os(config->printArchiveStats, ec, sys::fs::OF_None);
304-
if (ec) {
305-
error("--print-archive-stats=: cannot open " + config->printArchiveStats +
306-
": " + ec.message());
307-
return;
308-
}
309-
310-
os << "members\textracted\tarchive\n";
311-
312-
SmallVector<StringRef, 0> archives;
313-
DenseMap<CachedHashStringRef, unsigned> all, extracted;
314-
for (ELFFileBase *file : objectFiles)
315-
if (file->archiveName.size())
316-
++extracted[CachedHashStringRef(file->archiveName)];
317-
for (BitcodeFile *file : bitcodeFiles)
318-
if (file->archiveName.size())
319-
++extracted[CachedHashStringRef(file->archiveName)];
320-
for (std::pair<StringRef, unsigned> f : driver->archiveFiles) {
321-
unsigned &v = extracted[CachedHashString(f.first)];
322-
os << f.second << '\t' << v << '\t' << f.first << '\n';
323-
// If the archive occurs multiple times, other instances have a count of 0.
324-
v = 0;
325-
}
326-
}

lld/ELF/MapFile.h

-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
namespace lld {
1313
namespace elf {
1414
void writeMapAndCref();
15-
void writeWhyExtract();
16-
void writeArchiveStats();
1715
} // namespace elf
1816
} // namespace lld
1917

lld/ELF/Symbols.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "Symbols.h"
10+
#include "Driver.h"
1011
#include "InputFiles.h"
1112
#include "InputSection.h"
1213
#include "OutputSections.h"
@@ -50,8 +51,6 @@ Defined *ElfSym::riscvGlobalPointer;
5051
Defined *ElfSym::tlsModuleBase;
5152
DenseMap<const Symbol *, std::pair<const InputFile *, const InputFile *>>
5253
elf::backwardReferences;
53-
SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>, 0>
54-
elf::whyExtract;
5554
SmallVector<SymbolAux, 0> elf::symAux;
5655

5756
static uint64_t getSymVA(const Symbol &sym, int64_t addend) {
@@ -288,7 +287,7 @@ void elf::printTraceSymbol(const Symbol &sym, StringRef name) {
288287

289288
static void recordWhyExtract(const InputFile *reference,
290289
const InputFile &extracted, const Symbol &sym) {
291-
whyExtract.emplace_back(toString(reference), &extracted, sym);
290+
driver->whyExtract.emplace_back(toString(reference), &extracted, sym);
292291
}
293292

294293
void elf::maybeWarnUnorderableSymbol(const Symbol *sym) {

lld/ELF/Symbols.h

-5
Original file line numberDiff line numberDiff line change
@@ -569,11 +569,6 @@ extern llvm::DenseMap<const Symbol *,
569569
std::pair<const InputFile *, const InputFile *>>
570570
backwardReferences;
571571

572-
// A tuple of (reference, extractedFile, sym). Used by --why-extract=.
573-
extern SmallVector<std::tuple<std::string, const InputFile *, const Symbol &>,
574-
0>
575-
whyExtract;
576-
577572
} // namespace elf
578573
} // namespace lld
579574

lld/ELF/Writer.cpp

+3-7
Original file line numberDiff line numberDiff line change
@@ -561,14 +561,10 @@ template <class ELFT> void Writer<ELFT>::run() {
561561
for (Partition &part : partitions)
562562
setPhdrs(part);
563563

564-
565-
// Handle --print-map(-M)/--Map, --why-extract=, --cref and
566-
// --print-archive-stats=. Dump them before checkSections() because the files
567-
// may be useful in case checkSections() or openFile() fails, for example, due
568-
// to an erroneous file size.
564+
// Handle --print-map(-M)/--Map and --cref. Dump them before checkSections()
565+
// because the files may be useful in case checkSections() or openFile()
566+
// fails, for example, due to an erroneous file size.
569567
writeMapAndCref();
570-
writeWhyExtract();
571-
writeArchiveStats();
572568

573569
if (config->checkSections)
574570
checkSections();

lld/test/ELF/why-extract.s

+9-2
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,21 @@
3030
# CHECK2-NEXT:main.o a_b.a(a_b.o) a
3131
# CHECK2-NEXT:a_b.a(a_b.o) b.a(b.o) b()
3232

33+
## An undefined symbol error does not suppress the output.
34+
# RUN: not ld.lld main.o a_b.a -o /dev/null --why-extract=why3.txt
35+
# RUN: FileCheck %s --input-file=why3.txt --check-prefix=CHECK3 --match-full-lines --strict-whitespace
36+
3337
## Check that backward references are supported.
3438
## - means stdout.
35-
# RUN: ld.lld b.a a_b.a main.o -o /dev/null --why-extract=- | FileCheck %s --check-prefix=CHECK3
39+
# RUN: ld.lld b.a a_b.a main.o -o /dev/null --why-extract=- | FileCheck %s --check-prefix=CHECK4
3640

3741
# CHECK3:reference extracted symbol
38-
# CHECK3-NEXT:a_b.a(a_b.o) b.a(b.o) b()
3942
# CHECK3-NEXT:main.o a_b.a(a_b.o) a
4043

44+
# CHECK4:reference extracted symbol
45+
# CHECK4-NEXT:a_b.a(a_b.o) b.a(b.o) b()
46+
# CHECK4-NEXT:main.o a_b.a(a_b.o) a
47+
4148
# RUN: ld.lld main.o a_b.a b.a -o /dev/null --no-demangle --why-extract=- | FileCheck %s --check-prefix=MANGLED
4249

4350
# MANGLED: a_b.a(a_b.o) b.a(b.o) _Z1bv

0 commit comments

Comments
 (0)