COFF: Implement /lldmap flag.
authorPeter Collingbourne <peter@pcc.me.uk>
Fri, 26 Jun 2015 18:58:24 +0000 (18:58 +0000)
committerPeter Collingbourne <peter@pcc.me.uk>
Fri, 26 Jun 2015 18:58:24 +0000 (18:58 +0000)
This flag can be used to produce a map file, which is essentially a list
of objects linked into the final output file together with the RVAs of
their symbols. Because our format differs from MSVC's we expose it as a
separate flag.

Differential Revision: http://reviews.llvm.org/D10773

llvm-svn: 240812

lld/COFF/Driver.cpp
lld/COFF/Options.td
lld/COFF/SymbolTable.cpp
lld/COFF/SymbolTable.h
lld/COFF/Symbols.h
lld/test/COFF/lldmap.test [new file with mode: 0644]

index 7c1612c..a14e637 100644 (file)
@@ -34,6 +34,7 @@ using llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
 using llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI;
 using llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI;
 using llvm::sys::Process;
+using llvm::sys::fs::OpenFlags::F_Text;
 using llvm::sys::fs::file_magic;
 using llvm::sys::fs::identify_magic;
 
@@ -597,6 +598,17 @@ bool LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
     llvm::errs() << EC.message() << "\n";
     return false;
   }
+
+  if (auto *Arg = Args.getLastArg(OPT_lldmap)) {
+    std::error_code EC;
+    llvm::raw_fd_ostream Out(Arg->getValue(), EC, F_Text);
+    if (EC) {
+      llvm::errs() << EC.message() << "\n";
+      return false;
+    }
+    Symtab.printMap(Out);
+  }
+
   return true;
 }
 
index 0a145ab..fe7abbf 100644 (file)
@@ -88,8 +88,8 @@ def help_q : Flag<["/?", "-?"], "">, Alias<help>;
 
 def DASH_DASH : Option<["--"], "", KIND_REMAINING_ARGS>;
 
-// Flag for debug
-def lldmoduledeffile : Joined<["/", "-"], "lldmoduledeffile:">;
+// Flags for debugging
+def lldmap : Joined<["/", "-"], "lldmap:">;
 
 //==============================================================================
 // The flags below do nothing. They are defined only for link.exe compatibility.
index 112ffb3..054aa11 100644 (file)
@@ -237,6 +237,17 @@ void SymbolTable::dump() {
   }
 }
 
+void SymbolTable::printMap(llvm::raw_ostream &OS) {
+  for (ObjectFile *File : ObjectFiles) {
+    OS << File->getShortName() << ":\n";
+    for (SymbolBody *Body : File->getSymbols())
+      if (auto *R = dyn_cast<DefinedRegular>(Body))
+        if (R->isLive())
+          OS << Twine::utohexstr(Config->ImageBase + R->getRVA())
+             << " " << R->getName() << "\n";
+  }
+}
+
 std::error_code SymbolTable::addCombinedLTOObject() {
   if (BitcodeFiles.empty())
     return std::error_code();
index 595a97c..d96401a 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "InputFiles.h"
 #include "llvm/Support/Allocator.h"
+#include "llvm/Support/raw_ostream.h"
 #include <unordered_map>
 
 namespace llvm {
@@ -62,6 +63,9 @@ public:
   // Dump contents of the symbol table to stderr.
   void dump();
 
+  // Print a layout map to OS.
+  void printMap(llvm::raw_ostream &OS);
+
   // Build a COFF object representing the combined contents of BitcodeFiles
   // and add it to the symbol table. Called after all files are added and
   // before the writer writes results to a file.
index 8afbdc6..e0cb7b1 100644 (file)
@@ -134,6 +134,7 @@ public:
   int compare(SymbolBody *Other) override;
   std::string getDebugName() override;
   bool isCOMDAT() { return IsCOMDAT; }
+  bool isLive() const { return (*Data)->isLive(); }
   void markLive() { (*Data)->markLive(); }
   Chunk *getChunk() { return *Data; }
 
diff --git a/lld/test/COFF/lldmap.test b/lld/test/COFF/lldmap.test
new file mode 100644 (file)
index 0000000..027eb7a
--- /dev/null
@@ -0,0 +1,8 @@
+# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
+# RUN: lld -flavor link2 /out:%t.exe /lldmap:%t.map %t.obj
+# RUN: FileCheck %s < %t.map
+
+# CHECK: .obj:
+# CHECK-NEXT: 140001000 .text$mn
+# CHECK-NEXT: 140001000 .data
+# CHECK-NEXT: 140001000 mainCRTStartup