Index: lld/trunk/COFF/Driver.cpp =================================================================== --- lld/trunk/COFF/Driver.cpp +++ lld/trunk/COFF/Driver.cpp @@ -34,6 +34,7 @@ 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 @@ 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: lld/trunk/COFF/Options.td =================================================================== --- lld/trunk/COFF/Options.td +++ lld/trunk/COFF/Options.td @@ -88,8 +88,8 @@ 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: lld/trunk/COFF/SymbolTable.h =================================================================== --- lld/trunk/COFF/SymbolTable.h +++ lld/trunk/COFF/SymbolTable.h @@ -12,6 +12,7 @@ #include "InputFiles.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/raw_ostream.h" #include namespace llvm { @@ -62,6 +63,9 @@ // 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: lld/trunk/COFF/SymbolTable.cpp =================================================================== --- lld/trunk/COFF/SymbolTable.cpp +++ lld/trunk/COFF/SymbolTable.cpp @@ -237,6 +237,17 @@ } } +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(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: lld/trunk/COFF/Symbols.h =================================================================== --- lld/trunk/COFF/Symbols.h +++ lld/trunk/COFF/Symbols.h @@ -134,6 +134,7 @@ 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; } Index: lld/trunk/test/COFF/lldmap.test =================================================================== --- lld/trunk/test/COFF/lldmap.test +++ lld/trunk/test/COFF/lldmap.test @@ -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