@@ -103,7 +103,6 @@ bool elf::link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
103
103
objectFiles.clear ();
104
104
sharedFiles.clear ();
105
105
backwardReferences.clear ();
106
- whyExtract.clear ();
107
106
symAux.clear ();
108
107
109
108
tar = nullptr ;
@@ -1697,7 +1696,7 @@ static void handleUndefined(Symbol *sym, const char *option) {
1697
1696
return ;
1698
1697
sym->extract ();
1699
1698
if (!config->whyExtract .empty ())
1700
- whyExtract.emplace_back (option, sym->file , *sym);
1699
+ driver-> whyExtract .emplace_back (option, sym->file , *sym);
1701
1700
}
1702
1701
1703
1702
// As an extension to GNU linkers, lld supports a variant of `-u`
@@ -1733,6 +1732,55 @@ static void handleLibcall(StringRef name) {
1733
1732
sym->extract ();
1734
1733
}
1735
1734
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\t extracted\t archive\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\t extracted\t symbol\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
+
1736
1784
// Handle --dependency-file=<path>. If that option is given, lld creates a
1737
1785
// file at a given path with the following contents:
1738
1786
//
@@ -2436,8 +2484,11 @@ void LinkerDriver::link(opt::InputArgList &args) {
2436
2484
const size_t numObjsBeforeLTO = objectFiles.size ();
2437
2485
invokeELFT (compileBitcodeFiles, skipLinkedOutput);
2438
2486
2439
- // Symbol resolution finished. Report backward reference problems.
2487
+ // Symbol resolution finished. Report backward reference problems,
2488
+ // --print-archive-stats=, and --why-extract=.
2440
2489
reportBackrefs ();
2490
+ writeArchiveStats ();
2491
+ writeWhyExtract ();
2441
2492
if (errorCount ())
2442
2493
return ;
2443
2494
0 commit comments