Skip to content

Instantly share code, notes, and snippets.

@rui314
Last active March 1, 2019 00:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rui314/4eab9f328a5568b682d11c84d328cdaa to your computer and use it in GitHub Desktop.
Save rui314/4eab9f328a5568b682d11c84d328cdaa to your computer and use it in GitHub Desktop.
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