Index: ELF/MapFile.cpp =================================================================== --- ELF/MapFile.cpp +++ ELF/MapFile.cpp @@ -25,6 +25,7 @@ #include "OutputSections.h" #include "Strings.h" #include "SymbolTable.h" +#include "SyntheticSections.h" #include "Threads.h" #include "llvm/Support/raw_ostream.h" @@ -35,8 +36,7 @@ using namespace lld; using namespace lld::elf; -typedef DenseMap> - SymbolMapTy; +typedef DenseMap> SymbolMapTy; // Print out the first three columns of a line. static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size, @@ -48,31 +48,40 @@ static std::string indent(int Depth) { return std::string(Depth * 8, ' '); } // Returns a list of all symbols that we want to print out. -template static std::vector getSymbols() { - std::vector V; - for (ObjFile *File : ObjFile::Instances) - for (SymbolBody *B : File->getSymbols()) - if (auto *DR = dyn_cast(B)) +template static std::vector getSymbols() { + std::vector V; + for (ObjFile *File : ObjFile::Instances) { + for (SymbolBody *B : File->getSymbols()) { + if (auto *DR = dyn_cast(B)) { if (DR->getFile() == File && !DR->isSection() && DR->Section && DR->Section->Live) V.push_back(DR); + } else if (auto *DC = dyn_cast(B)) { + if (InX::Common) + V.push_back(cast(B)); + } + } + } return V; } // Returns a map from sections to their symbols. -static SymbolMapTy getSectionSyms(ArrayRef Syms) { +static SymbolMapTy getSectionSyms(ArrayRef Syms) { SymbolMapTy Ret; - for (DefinedRegular *S : Syms) - Ret[S->Section].push_back(S); + for (Defined *S : Syms) { + if (auto *DR = dyn_cast(S)) + Ret[DR->Section].push_back(S); + else + Ret[InX::Common].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 &V = It.second; - std::sort(V.begin(), V.end(), [](DefinedRegular *A, DefinedRegular *B) { - return A->getVA() < B->getVA(); - }); + SmallVectorImpl &V = It.second; + std::sort(V.begin(), V.end(), + [](Defined *A, Defined *B) { return A->getVA() < B->getVA(); }); } return Ret; } @@ -81,8 +90,8 @@ // Demangling symbols (which is what toString() does) is slow, so // we do that in batch using parallel-for. template -static DenseMap -getSymbolStrings(ArrayRef Syms) { +static DenseMap +getSymbolStrings(ArrayRef Syms) { std::vector Str(Syms.size()); parallelForEachN(0, Syms.size(), [&](size_t I) { raw_string_ostream OS(Str[I]); @@ -90,7 +99,7 @@ OS << indent(2) << toString(*Syms[I]); }); - DenseMap Ret; + DenseMap Ret; for (size_t I = 0, E = Syms.size(); I < E; ++I) Ret[Syms[I]] = std::move(Str[I]); return Ret; @@ -109,9 +118,9 @@ } // Collect symbol info that we want to print out. - std::vector Syms = getSymbols(); + std::vector Syms = getSymbols(); SymbolMapTy SectionSyms = getSectionSyms(Syms); - DenseMap SymStr = getSymbolStrings(Syms); + DenseMap SymStr = getSymbolStrings(Syms); // Print out the header line. int W = ELFT::Is64Bits ? 16 : 8; @@ -132,7 +141,7 @@ writeHeader(OS, OSec->Addr + IS->OutSecOff, IS->getSize(), IS->Alignment); OS << indent(1) << toString(IS) << '\n'; - for (DefinedRegular *Sym : SectionSyms[IS]) + for (Defined *Sym : SectionSyms[IS]) OS << SymStr[Sym] << '\n'; } } Index: test/ELF/map-file.s =================================================================== --- test/ELF/map-file.s +++ test/ELF/map-file.s @@ -45,6 +45,7 @@ // CHECK-NEXT: 0000000000201014 0000000000000000 0 baz // CHECK-NEXT: 0000000000202000 0000000000000004 16 .bss // CHECK-NEXT: 0000000000202000 0000000000000004 16 :(COMMON) +// CHECK-NEXT: 0000000000202000 0000000000000004 0 common // CHECK-NEXT: 0000000000000000 0000000000000008 1 .comment // CHECK-NEXT: 0000000000000000 0000000000000008 1 :(.comment) // CHECK-NEXT: 0000000000000000 00000000000000f0 8 .symtab