From 3151958cbdbc626884c3dc2872f350def0594041 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 28 Apr 2017 23:29:15 +0000 Subject: [PATCH] Replace PrettyPrinter class in MapFile.cpp with a few non-member functions. Since the output format has been simplified, the class to print out a map file doesn't seem to be needed anymore. We can replace it with a few non-member functions. llvm-svn: 301715 --- lld/ELF/MapFile.cpp | 120 +++++++++++++++++++++++++--------------------------- 1 file changed, 57 insertions(+), 63 deletions(-) diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp index 3017863..7412359 100644 --- a/lld/ELF/MapFile.cpp +++ b/lld/ELF/MapFile.cpp @@ -33,26 +33,8 @@ using namespace llvm::object; using namespace lld; using namespace lld::elf; -namespace { -template class PrettyPrinter { -public: - PrettyPrinter(); - void print(raw_ostream &OS, ArrayRef OutputSections); - -private: - void writeInputSection(raw_ostream &OS, const InputSection *IS); - - // Maps sections to their symbols. - DenseMap> Symbols; - - // Contains a string like this - // - // 0020100e 00000000 0 f(int) - // - // for each symbol. - DenseMap SymStr; -}; -} // namespace +typedef DenseMap> + SymbolMapTy; // Print out the first three columns of a line. template @@ -64,69 +46,55 @@ static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size, static std::string indent(int Depth) { return std::string(Depth * 8, ' '); } -template PrettyPrinter::PrettyPrinter() { - // Collect all symbols that we want to print out. - std::vector Syms; +// Returns a list of all symbols that we want to print out. +template std::vector getSymbols() { + std::vector V; for (elf::ObjectFile *File : Symtab::X->getObjectFiles()) for (SymbolBody *B : File->getSymbols()) if (B->File == File && !B->isSection()) if (auto *Sym = dyn_cast(B)) if (Sym->Section) - Syms.push_back(Sym); + V.push_back(Sym); + return V; +} - // Initialize the map from sections to their symbols. - for (DefinedRegular *Sym : Syms) - Symbols[Sym->Section].push_back(Sym); +// Returns a map from sections to their symbols. +template +SymbolMapTy getSectionSyms(ArrayRef Syms) { + SymbolMapTy Ret; + for (DefinedRegular *S : Syms) + Ret[S->Section].push_back(S); // Sort symbols by address. We want to print out symbols in the // order in the output file rather than the order they appeared // in the input files. - for (auto &It : Symbols) { + for (auto &It : Ret) { SmallVectorImpl &V = It.second; std::sort(V.begin(), V.end(), [](DefinedRegular *A, DefinedRegular *B) { return A->getVA() < B->getVA(); }); } + return Ret; +} - // Construct a map from symbols to their stringified representations. - // Demangling symbols is slow, so we use the parallel-for. +// Construct a map from symbols to their stringified representations. +// Demangling symbols (which is what toString() does) is slow, so +// we do that in batch using parallel-for. +template +DenseMap +getSymbolStrings(ArrayRef Syms) { std::vector Str(Syms.size()); parallelFor(0, Syms.size(), [&](size_t I) { raw_string_ostream OS(Str[I]); writeHeader(OS, Syms[I]->getVA(), Syms[I]->template getSize(), 0); - OS << indent(2) << toString(*Syms[I]) << '\n'; + OS << indent(2) << toString(*Syms[I]); }); - for (size_t I = 0, E = Syms.size(); I < E; ++I) - SymStr[Syms[I]] = std::move(Str[I]); -} - -template -void PrettyPrinter::writeInputSection(raw_ostream &OS, - const InputSection *IS) { - // Write a line for each symbol defined in the given section. - writeHeader(OS, IS->OutSec->Addr + IS->OutSecOff, IS->getSize(), - IS->Alignment); - OS << indent(1) << toString(IS) << '\n'; - for (DefinedRegular *Sym : Symbols[IS]) - OS << SymStr[Sym]; -} -template -void PrettyPrinter::print(raw_ostream &OS, - ArrayRef OutputSections) { - // Print out the header line. - int W = ELFT::Is64Bits ? 16 : 8; - OS << left_justify("Address", W) << ' ' << left_justify("Size", W) - << " Align Out In Symbol\n"; - - // Print out a mapfile. - for (OutputSection *Sec : OutputSections) { - writeHeader(OS, Sec->Addr, Sec->Size, Sec->Alignment); - OS << Sec->Name << '\n'; - for (InputSection *IS : Sec->Sections) - writeInputSection(OS, IS); - } + DenseMap Ret; + for (size_t I = 0, E = Syms.size(); I < E; ++I) + Ret[Syms[I]] = std::move(Str[I]); + return Ret; } template @@ -134,12 +102,38 @@ void elf::writeMapFile(ArrayRef OutputSections) { if (Config->MapFile.empty()) return; + // Open a map file for writing. std::error_code EC; raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None); - if (EC) + if (EC) { error("cannot open " + Config->MapFile + ": " + EC.message()); - else - PrettyPrinter().print(OS, OutputSections); + return; + } + + // Collect symbol info that we want to print out. + std::vector Syms = getSymbols(); + SymbolMapTy SectionSyms = getSectionSyms(Syms); + DenseMap SymStr = getSymbolStrings(Syms); + + // Print out the header line. + int W = ELFT::Is64Bits ? 16 : 8; + OS << left_justify("Address", W) << ' ' << left_justify("Size", W) + << " Align Out In Symbol\n"; + + // Print out file contents. + for (OutputSection *OSec : OutputSections) { + writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment); + OS << OSec->Name << '\n'; + + // Dump symbols for each input section. + for (InputSection *IS : OSec->Sections) { + writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), + IS->Alignment); + OS << indent(1) << toString(IS) << '\n'; + for (DefinedRegular *Sym : SectionSyms[IS]) + OS << SymStr[Sym] << '\n'; + } + } } template void elf::writeMapFile(ArrayRef); -- 2.7.4