11ebfc59cSRafael Espindola //===- MapFile.cpp --------------------------------------------------------===// 21ebfc59cSRafael Espindola // 31ebfc59cSRafael Espindola // The LLVM Linker 41ebfc59cSRafael Espindola // 51ebfc59cSRafael Espindola // This file is distributed under the University of Illinois Open Source 61ebfc59cSRafael Espindola // License. See LICENSE.TXT for details. 71ebfc59cSRafael Espindola // 81ebfc59cSRafael Espindola //===----------------------------------------------------------------------===// 91ebfc59cSRafael Espindola // 101ebfc59cSRafael Espindola // This file implements the -Map option. It shows lists in order and 111ebfc59cSRafael Espindola // hierarchically the output sections, input sections, input files and 121ebfc59cSRafael Espindola // symbol: 131ebfc59cSRafael Espindola // 143012b371SRui Ueyama // Address Size Align Out In Symbol 151ebfc59cSRafael Espindola // 00201000 00000015 4 .text 1637811379SRui Ueyama // 00201000 0000000e 4 test.o:(.text) 171ebfc59cSRafael Espindola // 0020100e 00000000 0 local 181ebfc59cSRafael Espindola // 00201005 00000000 0 f(int) 191ebfc59cSRafael Espindola // 201ebfc59cSRafael Espindola //===----------------------------------------------------------------------===// 211ebfc59cSRafael Espindola 221ebfc59cSRafael Espindola #include "MapFile.h" 231ebfc59cSRafael Espindola #include "InputFiles.h" 24a46f688eSRafael Espindola #include "LinkerScript.h" 251b414090SRafael Espindola #include "OutputSections.h" 26b882e591SRui Ueyama #include "SymbolTable.h" 27d26b52fdSRafael Espindola #include "Symbols.h" 28f2fe963dSGeorge Rimar #include "SyntheticSections.h" 29ee173718SRui Ueyama #include "lld/Common/Strings.h" 304f5c8c29SBob Haarman #include "lld/Common/Threads.h" 31db46a62eSRui Ueyama #include "llvm/ADT/MapVector.h" 32db46a62eSRui Ueyama #include "llvm/ADT/SetVector.h" 33543731f9SRui Ueyama #include "llvm/Support/raw_ostream.h" 341ebfc59cSRafael Espindola 351ebfc59cSRafael Espindola using namespace llvm; 361ebfc59cSRafael Espindola using namespace llvm::object; 371ebfc59cSRafael Espindola 381ebfc59cSRafael Espindola using namespace lld; 391ebfc59cSRafael Espindola using namespace lld::elf; 401ebfc59cSRafael Espindola 4131cd5da5SGeorge Rimar typedef DenseMap<const SectionBase *, SmallVector<Symbol *, 4>> SymbolMapTy; 42b882e591SRui Ueyama 43e1847da9SRui Ueyama static const std::string Indent8 = " "; // 8 spaces 44e1847da9SRui Ueyama static const std::string Indent16 = " "; // 16 spaces 459e0171fbSRui Ueyama 46b882e591SRui Ueyama // Print out the first three columns of a line. 47b882e591SRui Ueyama static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size, 48b882e591SRui Ueyama uint64_t Align) { 497b30dd1cSGeorge Rimar int W = Config->Is64 ? 16 : 8; 50b882e591SRui Ueyama OS << format("%0*llx %0*llx %5lld ", W, Addr, W, Size, Align); 511ebfc59cSRafael Espindola } 521ebfc59cSRafael Espindola 533151958cSRui Ueyama // Returns a list of all symbols that we want to print out. 5431cd5da5SGeorge Rimar static std::vector<Symbol *> getSymbols() { 5531cd5da5SGeorge Rimar std::vector<Symbol *> V; 5631cd5da5SGeorge Rimar for (InputFile *File : ObjectFiles) { 5731cd5da5SGeorge Rimar for (Symbol *B : File->getSymbols()) { 5831cd5da5SGeorge Rimar if (auto *SS = dyn_cast<SharedSymbol>(B)) 59ba7afd70SGeorge Rimar if (SS->CopyRelSec || SS->NeedsPltAddr) 6031cd5da5SGeorge Rimar V.push_back(SS); 61e9a9e0a1SPeter Collingbourne if (auto *DR = dyn_cast<Defined>(B)) 62dfebd360SRafael Espindola if (DR->File == File && !DR->isSection() && DR->Section && 63f456f572SRafael Espindola DR->Section->Live) 64f456f572SRafael Espindola V.push_back(DR); 6531cd5da5SGeorge Rimar } 6631cd5da5SGeorge Rimar } 673151958cSRui Ueyama return V; 683151958cSRui Ueyama } 69b882e591SRui Ueyama 703151958cSRui Ueyama // Returns a map from sections to their symbols. 7131cd5da5SGeorge Rimar static SymbolMapTy getSectionSyms(ArrayRef<Symbol *> Syms) { 723151958cSRui Ueyama SymbolMapTy Ret; 7331cd5da5SGeorge Rimar for (Symbol *S : Syms) { 74ba7afd70SGeorge Rimar if (auto *DR = dyn_cast<Defined>(S)) { 7531cd5da5SGeorge Rimar Ret[DR->Section].push_back(S); 76ba7afd70SGeorge Rimar continue; 77ba7afd70SGeorge Rimar } 78ba7afd70SGeorge Rimar 79ba7afd70SGeorge Rimar SharedSymbol *SS = cast<SharedSymbol>(S); 80ba7afd70SGeorge Rimar if (SS->CopyRelSec) 81ba7afd70SGeorge Rimar Ret[SS->CopyRelSec].push_back(S); 8231cd5da5SGeorge Rimar else 83ba7afd70SGeorge Rimar Ret[InX::Plt].push_back(S); 8431cd5da5SGeorge Rimar } 85b882e591SRui Ueyama 86b882e591SRui Ueyama // Sort symbols by address. We want to print out symbols in the 87b882e591SRui Ueyama // order in the output file rather than the order they appeared 88b882e591SRui Ueyama // in the input files. 893151958cSRui Ueyama for (auto &It : Ret) { 9031cd5da5SGeorge Rimar SmallVectorImpl<Symbol *> &V = It.second; 91f2fe963dSGeorge Rimar std::sort(V.begin(), V.end(), 9231cd5da5SGeorge Rimar [](Symbol *A, Symbol *B) { return A->getVA() < B->getVA(); }); 931ebfc59cSRafael Espindola } 943151958cSRui Ueyama return Ret; 953151958cSRui Ueyama } 961ebfc59cSRafael Espindola 97b882e591SRui Ueyama // Construct a map from symbols to their stringified representations. 983151958cSRui Ueyama // Demangling symbols (which is what toString() does) is slow, so 993151958cSRui Ueyama // we do that in batch using parallel-for. 10031cd5da5SGeorge Rimar static DenseMap<Symbol *, std::string> 10131cd5da5SGeorge Rimar getSymbolStrings(ArrayRef<Symbol *> Syms) { 102b882e591SRui Ueyama std::vector<std::string> Str(Syms.size()); 10333d903d1SRui Ueyama parallelForEachN(0, Syms.size(), [&](size_t I) { 104b882e591SRui Ueyama raw_string_ostream OS(Str[I]); 1057f9694a4SRui Ueyama writeHeader(OS, Syms[I]->getVA(), Syms[I]->getSize(), 0); 106e1847da9SRui Ueyama OS << Indent16 << toString(*Syms[I]); 107b882e591SRui Ueyama }); 1083151958cSRui Ueyama 10931cd5da5SGeorge Rimar DenseMap<Symbol *, std::string> Ret; 110b882e591SRui Ueyama for (size_t I = 0, E = Syms.size(); I < E; ++I) 1113151958cSRui Ueyama Ret[Syms[I]] = std::move(Str[I]); 1123151958cSRui Ueyama return Ret; 1131ebfc59cSRafael Espindola } 1141ebfc59cSRafael Espindola 115a5c1ed34SRui Ueyama // Print .eh_frame contents. Since the section consists of EhSectionPieces, 116a5c1ed34SRui Ueyama // we need a specialized printer for that section. 117a5c1ed34SRui Ueyama // 118a5c1ed34SRui Ueyama // .eh_frame tend to contain a lot of section pieces that are contiguous 119a5c1ed34SRui Ueyama // both in input file and output file. Such pieces are squashed before 120a5c1ed34SRui Ueyama // being displayed to make output compact. 121a5c1ed34SRui Ueyama static void printEhFrame(raw_ostream &OS, OutputSection *OSec) { 122a5c1ed34SRui Ueyama std::vector<EhSectionPiece> Pieces; 123a5c1ed34SRui Ueyama 124a5c1ed34SRui Ueyama auto Add = [&](const EhSectionPiece &P) { 125a5c1ed34SRui Ueyama // If P is adjacent to Last, squash the two. 126a5c1ed34SRui Ueyama if (!Pieces.empty()) { 127a5c1ed34SRui Ueyama EhSectionPiece &Last = Pieces.back(); 128a5c1ed34SRui Ueyama if (Last.Sec == P.Sec && Last.InputOff + Last.Size == P.InputOff && 129a5c1ed34SRui Ueyama Last.OutputOff + Last.Size == P.OutputOff) { 130a5c1ed34SRui Ueyama Last.Size += P.Size; 131a5c1ed34SRui Ueyama return; 132a5c1ed34SRui Ueyama } 133a5c1ed34SRui Ueyama } 134a5c1ed34SRui Ueyama Pieces.push_back(P); 135a5c1ed34SRui Ueyama }; 136a5c1ed34SRui Ueyama 137a5c1ed34SRui Ueyama // Gather section pieces. 138a5c1ed34SRui Ueyama for (const CieRecord *Rec : InX::EhFrame->getCieRecords()) { 139a5c1ed34SRui Ueyama Add(*Rec->Cie); 140a5c1ed34SRui Ueyama for (const EhSectionPiece *Fde : Rec->Fdes) 141a5c1ed34SRui Ueyama Add(*Fde); 142a5c1ed34SRui Ueyama } 143a5c1ed34SRui Ueyama 144a5c1ed34SRui Ueyama // Print out section pieces. 145a5c1ed34SRui Ueyama for (EhSectionPiece &P : Pieces) { 146a5c1ed34SRui Ueyama writeHeader(OS, OSec->Addr + P.OutputOff, P.Size, 0); 147a5c1ed34SRui Ueyama OS << Indent8 << toString(P.Sec->File) << ":(" << P.Sec->Name << "+0x" 148a5c1ed34SRui Ueyama << Twine::utohexstr(P.InputOff) + ")\n"; 149a5c1ed34SRui Ueyama } 150a5c1ed34SRui Ueyama } 151a5c1ed34SRui Ueyama 1527f9694a4SRui Ueyama void elf::writeMapFile() { 153543731f9SRui Ueyama if (Config->MapFile.empty()) 1541ebfc59cSRafael Espindola return; 1551ebfc59cSRafael Espindola 1563151958cSRui Ueyama // Open a map file for writing. 157543731f9SRui Ueyama std::error_code EC; 158543731f9SRui Ueyama raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None); 1593151958cSRui Ueyama if (EC) { 160c9807c33SRui Ueyama error("cannot open " + Config->MapFile + ": " + EC.message()); 1613151958cSRui Ueyama return; 1623151958cSRui Ueyama } 1633151958cSRui Ueyama 1643151958cSRui Ueyama // Collect symbol info that we want to print out. 16531cd5da5SGeorge Rimar std::vector<Symbol *> Syms = getSymbols(); 1667b30dd1cSGeorge Rimar SymbolMapTy SectionSyms = getSectionSyms(Syms); 16731cd5da5SGeorge Rimar DenseMap<Symbol *, std::string> SymStr = getSymbolStrings(Syms); 1683151958cSRui Ueyama 1693151958cSRui Ueyama // Print out the header line. 1707f9694a4SRui Ueyama int W = Config->Is64 ? 16 : 8; 1713151958cSRui Ueyama OS << left_justify("Address", W) << ' ' << left_justify("Size", W) 1723151958cSRui Ueyama << " Align Out In Symbol\n"; 1733151958cSRui Ueyama 1743151958cSRui Ueyama // Print out file contents. 1758c022ca7SRafael Espindola for (OutputSection *OSec : OutputSections) { 1767b30dd1cSGeorge Rimar writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment); 1773151958cSRui Ueyama OS << OSec->Name << '\n'; 1783151958cSRui Ueyama 1793151958cSRui Ueyama // Dump symbols for each input section. 180*84bcabcbSGeorge Rimar for (BaseCommand *Base : OSec->SectionCommands) { 181*84bcabcbSGeorge Rimar if (auto *ISD = dyn_cast<InputSectionDescription>(Base)) { 182*84bcabcbSGeorge Rimar for (InputSection *IS : ISD->Sections) { 183a5c1ed34SRui Ueyama if (IS == InX::EhFrame) { 184a5c1ed34SRui Ueyama printEhFrame(OS, OSec); 185a5c1ed34SRui Ueyama continue; 186a5c1ed34SRui Ueyama } 187a5c1ed34SRui Ueyama 188*84bcabcbSGeorge Rimar writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), 189*84bcabcbSGeorge Rimar IS->Alignment); 190e1847da9SRui Ueyama OS << Indent8 << toString(IS) << '\n'; 19131cd5da5SGeorge Rimar for (Symbol *Sym : SectionSyms[IS]) 1923151958cSRui Ueyama OS << SymStr[Sym] << '\n'; 1933151958cSRui Ueyama } 194*84bcabcbSGeorge Rimar continue; 195*84bcabcbSGeorge Rimar } 196*84bcabcbSGeorge Rimar 197*84bcabcbSGeorge Rimar if (auto *Cmd = dyn_cast<ByteCommand>(Base)) { 198*84bcabcbSGeorge Rimar writeHeader(OS, OSec->Addr + Cmd->Offset, Cmd->Size, 1); 199*84bcabcbSGeorge Rimar OS << Indent8 << Cmd->CommandString << '\n'; 200*84bcabcbSGeorge Rimar continue; 201*84bcabcbSGeorge Rimar } 202*84bcabcbSGeorge Rimar 203*84bcabcbSGeorge Rimar if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) { 204*84bcabcbSGeorge Rimar writeHeader(OS, OSec->Addr + Cmd->Offset, Cmd->Size, 1); 205*84bcabcbSGeorge Rimar OS << Indent8 << Cmd->CommandString << '\n'; 206*84bcabcbSGeorge Rimar continue; 207*84bcabcbSGeorge Rimar } 208*84bcabcbSGeorge Rimar } 2093151958cSRui Ueyama } 2101ebfc59cSRafael Espindola } 211db46a62eSRui Ueyama 212db46a62eSRui Ueyama static void print(StringRef A, StringRef B) { 213db46a62eSRui Ueyama outs() << left_justify(A, 49) << " " << B << "\n"; 214db46a62eSRui Ueyama } 215db46a62eSRui Ueyama 216db46a62eSRui Ueyama // Output a cross reference table to stdout. This is for --cref. 217db46a62eSRui Ueyama // 218db46a62eSRui Ueyama // For each global symbol, we print out a file that defines the symbol 219db46a62eSRui Ueyama // followed by files that uses that symbol. Here is an example. 220db46a62eSRui Ueyama // 221db46a62eSRui Ueyama // strlen /lib/x86_64-linux-gnu/libc.so.6 222db46a62eSRui Ueyama // tools/lld/tools/lld/CMakeFiles/lld.dir/lld.cpp.o 223db46a62eSRui Ueyama // lib/libLLVMSupport.a(PrettyStackTrace.cpp.o) 224db46a62eSRui Ueyama // 225db46a62eSRui Ueyama // In this case, strlen is defined by libc.so.6 and used by other two 226db46a62eSRui Ueyama // files. 227db46a62eSRui Ueyama void elf::writeCrossReferenceTable() { 228db46a62eSRui Ueyama if (!Config->Cref) 229db46a62eSRui Ueyama return; 230db46a62eSRui Ueyama 231db46a62eSRui Ueyama // Collect symbols and files. 232db46a62eSRui Ueyama MapVector<Symbol *, SetVector<InputFile *>> Map; 233db46a62eSRui Ueyama for (InputFile *File : ObjectFiles) { 234db46a62eSRui Ueyama for (Symbol *Sym : File->getSymbols()) { 235db46a62eSRui Ueyama if (isa<SharedSymbol>(Sym)) 236db46a62eSRui Ueyama Map[Sym].insert(File); 237db46a62eSRui Ueyama if (auto *D = dyn_cast<Defined>(Sym)) 238db46a62eSRui Ueyama if (!D->isLocal() && (!D->Section || D->Section->Live)) 239db46a62eSRui Ueyama Map[D].insert(File); 240db46a62eSRui Ueyama } 241db46a62eSRui Ueyama } 242db46a62eSRui Ueyama 243db46a62eSRui Ueyama // Print out a header. 244db46a62eSRui Ueyama outs() << "Cross Reference Table\n\n"; 245db46a62eSRui Ueyama print("Symbol", "File"); 246db46a62eSRui Ueyama 247db46a62eSRui Ueyama // Print out a table. 248db46a62eSRui Ueyama for (auto KV : Map) { 249db46a62eSRui Ueyama Symbol *Sym = KV.first; 250db46a62eSRui Ueyama SetVector<InputFile *> &Files = KV.second; 251db46a62eSRui Ueyama 252db46a62eSRui Ueyama print(toString(*Sym), toString(Sym->File)); 253db46a62eSRui Ueyama for (InputFile *File : Files) 254db46a62eSRui Ueyama if (File != Sym->File) 255db46a62eSRui Ueyama print("", toString(File)); 256db46a62eSRui Ueyama } 257db46a62eSRui Ueyama } 258