Last active
March 1, 2019 00:39
-
-
Save rui314/4eab9f328a5568b682d11c84d328cdaa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp | |
index e2aa7e94452..ecc5124bae8 100644 | |
--- a/lld/ELF/Driver.cpp | |
+++ b/lld/ELF/Driver.cpp | |
@@ -29,6 +29,7 @@ | |
#include "InputFiles.h" | |
#include "InputSection.h" | |
#include "LinkerScript.h" | |
+#include "MapFile.h" | |
#include "MarkLive.h" | |
#include "OutputSections.h" | |
#include "ScriptParser.h" | |
@@ -1648,4 +1649,11 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { | |
// Write the result to the file. | |
writeResult<ELFT>(); | |
+ if (errorCount()) | |
+ return; | |
+ | |
+ // Handle -Map, -dot and -cref options. | |
+ writeMapFile(); | |
+ writeGraphviz(); | |
+ writeCrossReferenceTable(); | |
} | |
diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp | |
index cc5b31de543..ae70fa83a4b 100644 | |
--- a/lld/ELF/MapFile.cpp | |
+++ b/lld/ELF/MapFile.cpp | |
@@ -214,6 +214,38 @@ void elf::writeMapFile() { | |
} | |
} | |
+void elf::writeGraphviz() { | |
+ MapVector<InputSection *, uint32_t> Map; | |
+ | |
+ for (BaseCommand *Base : Script->SectionCommands) | |
+ if (auto *OS = dyn_cast<OutputSection>(Base)) | |
+ for (BaseCommand *Base : OS->SectionCommands) | |
+ if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) | |
+ for (InputSection *IS : ISD->Sections) | |
+ Map.insert({IS, Map.size()}); | |
+ | |
+ outs() << "digraph {\n"; | |
+ | |
+ for (std::pair<InputSection *, uint32_t> &KV : Map) | |
+ outs() << KV.second << "[label=\"" << toString(KV.first) << "\"];\n"; | |
+ | |
+ for (std::pair<InputSection *, uint32_t> &KV : Map) { | |
+ InputSection *From = KV.first; | |
+ uint32_t ID = KV.second; | |
+ DenseSet<InputSection *> Seen; | |
+ | |
+ for (Relocation &Rel : From->Relocations) | |
+ if (auto *Sym = dyn_cast<Defined>(Rel.Sym)) | |
+ if (!Sym->getName().empty()) | |
+ if (auto *To = dyn_cast_or_null<InputSection>(Sym->Section)) | |
+ if (!Seen.insert(To).second) | |
+ outs() << ID << "->" << Map[To] | |
+ << "[label=\"" << toString(*Sym) << "\"];\n"; | |
+ } | |
+ | |
+ outs() << "}\n"; | |
+} | |
+ | |
static void print(StringRef A, StringRef B) { | |
outs() << left_justify(A, 49) << " " << B << "\n"; | |
} | |
diff --git a/lld/ELF/MapFile.h b/lld/ELF/MapFile.h | |
index 7e7938919ed..746387d8fae 100644 | |
--- a/lld/ELF/MapFile.h | |
+++ b/lld/ELF/MapFile.h | |
@@ -12,6 +12,7 @@ | |
namespace lld { | |
namespace elf { | |
void writeMapFile(); | |
+void writeGraphviz(); | |
void writeCrossReferenceTable(); | |
} // namespace elf | |
} // namespace lld | |
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp | |
index 2282fe92a93..9d2135cee05 100644 | |
--- a/lld/ELF/Writer.cpp | |
+++ b/lld/ELF/Writer.cpp | |
@@ -12,7 +12,6 @@ | |
#include "Config.h" | |
#include "Filesystem.h" | |
#include "LinkerScript.h" | |
-#include "MapFile.h" | |
#include "OutputSections.h" | |
#include "Relocations.h" | |
#include "SymbolTable.h" | |
@@ -525,12 +524,6 @@ template <class ELFT> void Writer<ELFT>::run() { | |
if (errorCount()) | |
return; | |
- // Handle -Map and -cref options. | |
- writeMapFile(); | |
- writeCrossReferenceTable(); | |
- if (errorCount()) | |
- return; | |
- | |
if (auto E = Buffer->commit()) | |
error("failed to write to the output file: " + toString(std::move(E))); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment