diff options
Diffstat (limited to 'ELF/MapFile.cpp')
-rw-r--r-- | ELF/MapFile.cpp | 95 |
1 files changed, 49 insertions, 46 deletions
diff --git a/ELF/MapFile.cpp b/ELF/MapFile.cpp index 2b2a95c47cf9..dcc829315e64 100644 --- a/ELF/MapFile.cpp +++ b/ELF/MapFile.cpp @@ -25,8 +25,9 @@ #include "OutputSections.h" #include "Strings.h" #include "SymbolTable.h" -#include "Threads.h" - +#include "Symbols.h" +#include "SyntheticSections.h" +#include "lld/Common/Threads.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; @@ -35,46 +36,57 @@ using namespace llvm::object; using namespace lld; using namespace lld::elf; -typedef DenseMap<const SectionBase *, SmallVector<DefinedRegular *, 4>> - SymbolMapTy; +typedef DenseMap<const SectionBase *, SmallVector<Symbol *, 4>> SymbolMapTy; // Print out the first three columns of a line. -template <class ELFT> static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size, uint64_t Align) { - int W = ELFT::Is64Bits ? 16 : 8; + int W = Config->Is64 ? 16 : 8; OS << format("%0*llx %0*llx %5lld ", W, Addr, W, Size, Align); } static std::string indent(int Depth) { return std::string(Depth * 8, ' '); } // Returns a list of all symbols that we want to print out. -template <class ELFT> std::vector<DefinedRegular *> getSymbols() { - std::vector<DefinedRegular *> V; - for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) - for (SymbolBody *B : File->getSymbols()) - if (B->File == File && !B->isSection()) - if (auto *Sym = dyn_cast<DefinedRegular>(B)) - if (Sym->Section && Sym->Section->Live) - V.push_back(Sym); +static std::vector<Symbol *> getSymbols() { + std::vector<Symbol *> V; + for (InputFile *File : ObjectFiles) { + for (Symbol *B : File->getSymbols()) { + if (auto *SS = dyn_cast<SharedSymbol>(B)) + if (SS->CopyRelSec || SS->NeedsPltAddr) + V.push_back(SS); + if (auto *DR = dyn_cast<Defined>(B)) + if (DR->File == File && !DR->isSection() && DR->Section && + DR->Section->Live) + V.push_back(DR); + } + } return V; } // Returns a map from sections to their symbols. -template <class ELFT> -SymbolMapTy getSectionSyms(ArrayRef<DefinedRegular *> Syms) { +static SymbolMapTy getSectionSyms(ArrayRef<Symbol *> Syms) { SymbolMapTy Ret; - for (DefinedRegular *S : Syms) - Ret[S->Section].push_back(S); + for (Symbol *S : Syms) { + if (auto *DR = dyn_cast<Defined>(S)) { + Ret[DR->Section].push_back(S); + continue; + } + + SharedSymbol *SS = cast<SharedSymbol>(S); + if (SS->CopyRelSec) + Ret[SS->CopyRelSec].push_back(S); + else + Ret[InX::Plt].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 : Ret) { - SmallVectorImpl<DefinedRegular *> &V = It.second; - std::sort(V.begin(), V.end(), [](DefinedRegular *A, DefinedRegular *B) { - return A->getVA() < B->getVA(); - }); + SmallVectorImpl<Symbol *> &V = It.second; + std::sort(V.begin(), V.end(), + [](Symbol *A, Symbol *B) { return A->getVA() < B->getVA(); }); } return Ret; } @@ -82,25 +94,22 @@ SymbolMapTy getSectionSyms(ArrayRef<DefinedRegular *> Syms) { // 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 <class ELFT> -DenseMap<DefinedRegular *, std::string> -getSymbolStrings(ArrayRef<DefinedRegular *> Syms) { +static DenseMap<Symbol *, std::string> +getSymbolStrings(ArrayRef<Symbol *> Syms) { std::vector<std::string> Str(Syms.size()); parallelForEachN(0, Syms.size(), [&](size_t I) { raw_string_ostream OS(Str[I]); - writeHeader<ELFT>(OS, Syms[I]->getVA(), Syms[I]->template getSize<ELFT>(), - 0); + writeHeader(OS, Syms[I]->getVA(), Syms[I]->getSize(), 0); OS << indent(2) << toString(*Syms[I]); }); - DenseMap<DefinedRegular *, std::string> Ret; + DenseMap<Symbol *, std::string> Ret; for (size_t I = 0, E = Syms.size(); I < E; ++I) Ret[Syms[I]] = std::move(Str[I]); return Ret; } -template <class ELFT> -void elf::writeMapFile(llvm::ArrayRef<OutputSectionCommand *> Script) { +void elf::writeMapFile() { if (Config->MapFile.empty()) return; @@ -113,38 +122,32 @@ void elf::writeMapFile(llvm::ArrayRef<OutputSectionCommand *> Script) { } // Collect symbol info that we want to print out. - std::vector<DefinedRegular *> Syms = getSymbols<ELFT>(); - SymbolMapTy SectionSyms = getSectionSyms<ELFT>(Syms); - DenseMap<DefinedRegular *, std::string> SymStr = getSymbolStrings<ELFT>(Syms); + std::vector<Symbol *> Syms = getSymbols(); + SymbolMapTy SectionSyms = getSectionSyms(Syms); + DenseMap<Symbol *, std::string> SymStr = getSymbolStrings(Syms); // Print out the header line. - int W = ELFT::Is64Bits ? 16 : 8; + int W = Config->Is64 ? 16 : 8; OS << left_justify("Address", W) << ' ' << left_justify("Size", W) << " Align Out In Symbol\n"; // Print out file contents. - for (OutputSectionCommand *Cmd : Script) { - OutputSection *OSec = Cmd->Sec; - writeHeader<ELFT>(OS, OSec->Addr, OSec->Size, OSec->Alignment); + for (OutputSection *OSec : OutputSections) { + writeHeader(OS, OSec->Addr, OSec->Size, OSec->Alignment); OS << OSec->Name << '\n'; // Dump symbols for each input section. - for (BaseCommand *Base : Cmd->Commands) { + for (BaseCommand *Base : OSec->SectionCommands) { auto *ISD = dyn_cast<InputSectionDescription>(Base); if (!ISD) continue; for (InputSection *IS : ISD->Sections) { - writeHeader<ELFT>(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), - IS->Alignment); + writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), + IS->Alignment); OS << indent(1) << toString(IS) << '\n'; - for (DefinedRegular *Sym : SectionSyms[IS]) + for (Symbol *Sym : SectionSyms[IS]) OS << SymStr[Sym] << '\n'; } } } } - -template void elf::writeMapFile<ELF32LE>(ArrayRef<OutputSectionCommand *>); -template void elf::writeMapFile<ELF32BE>(ArrayRef<OutputSectionCommand *>); -template void elf::writeMapFile<ELF64LE>(ArrayRef<OutputSectionCommand *>); -template void elf::writeMapFile<ELF64BE>(ArrayRef<OutputSectionCommand *>); |