diff options
author | Rui Ueyama <ruiu@google.com> | 2018-03-14 20:29:45 +0000 |
---|---|---|
committer | Rui Ueyama <ruiu@google.com> | 2018-03-14 20:29:45 +0000 |
commit | db46a62e2bc56697347ccb681dc673b7e276d3ce (patch) | |
tree | 1c8d3fb7b2d5e86ab61efa3c533a488864dd8c08 /lld/ELF/MapFile.cpp | |
parent | 115b0673b67fe826cee1bc7a145c324ec41c2140 (diff) | |
download | bcm5719-llvm-db46a62e2bc56697347ccb681dc673b7e276d3ce.tar.gz bcm5719-llvm-db46a62e2bc56697347ccb681dc673b7e276d3ce.zip |
Implement --cref.
This is an option to print out a table of symbols and filenames.
The output format of this option is the same as GNU, so that it can be
processed by the same scripts as before after migrating from GNU to lld.
This option is mildly useful; we can live without it. But it is pretty
convenient sometimes, and it can be implemented in 50 lines of code, so
I think lld should support this option.
Differential Revision: https://reviews.llvm.org/D44336
llvm-svn: 327565
Diffstat (limited to 'lld/ELF/MapFile.cpp')
-rw-r--r-- | lld/ELF/MapFile.cpp | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp index 1887e8b264e..b8d4007968d 100644 --- a/lld/ELF/MapFile.cpp +++ b/lld/ELF/MapFile.cpp @@ -28,6 +28,8 @@ #include "SyntheticSections.h" #include "lld/Common/Strings.h" #include "lld/Common/Threads.h" +#include "llvm/ADT/MapVector.h" +#include "llvm/ADT/SetVector.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -146,3 +148,50 @@ void elf::writeMapFile() { } } } + +static void print(StringRef A, StringRef B) { + outs() << left_justify(A, 49) << " " << B << "\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 +// followed by files that uses that symbol. Here is an example. +// +// strlen /lib/x86_64-linux-gnu/libc.so.6 +// tools/lld/tools/lld/CMakeFiles/lld.dir/lld.cpp.o +// lib/libLLVMSupport.a(PrettyStackTrace.cpp.o) +// +// In this case, strlen is defined by libc.so.6 and used by other two +// files. +void elf::writeCrossReferenceTable() { + if (!Config->Cref) + return; + + // Collect symbols and files. + MapVector<Symbol *, SetVector<InputFile *>> Map; + for (InputFile *File : ObjectFiles) { + for (Symbol *Sym : File->getSymbols()) { + if (isa<SharedSymbol>(Sym)) + Map[Sym].insert(File); + if (auto *D = dyn_cast<Defined>(Sym)) + if (!D->isLocal() && (!D->Section || D->Section->Live)) + Map[D].insert(File); + } + } + + // Print out a header. + outs() << "Cross Reference Table\n\n"; + print("Symbol", "File"); + + // Print out a table. + for (auto KV : Map) { + Symbol *Sym = KV.first; + SetVector<InputFile *> &Files = KV.second; + + print(toString(*Sym), toString(Sym->File)); + for (InputFile *File : Files) + if (File != Sym->File) + print("", toString(File)); + } +} |