[lld] r307867 - Refactor gdb index creation.

Rafael Espindola via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 12 16:56:53 PDT 2017


Author: rafael
Date: Wed Jul 12 16:56:53 2017
New Revision: 307867

URL: http://llvm.org/viewvc/llvm-project?rev=307867&view=rev
Log:
Refactor gdb index creation.

I have a patch to let DwarfContext defer to lld for getting section
contents and relocations.

That is a pretty big performance improvement.

This is just a refactoring to make that easier to do.

This change makes the *creation* of gdb index a dedicated step and
makes that templated. That is so that we can uses Elf_Rel in the code.

Modified:
    lld/trunk/ELF/GdbIndex.h
    lld/trunk/ELF/SyntheticSections.cpp
    lld/trunk/ELF/SyntheticSections.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/GdbIndex.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/GdbIndex.h?rev=307867&r1=307866&r2=307867&view=diff
==============================================================================
--- lld/trunk/ELF/GdbIndex.h (original)
+++ lld/trunk/ELF/GdbIndex.h Wed Jul 12 16:56:53 2017
@@ -45,6 +45,7 @@ struct NameTypeEntry {
 // debug information performed. That information futher used
 // for filling gdb index section areas.
 struct GdbIndexChunk {
+  InputSection *DebugInfoSec;
   std::vector<AddressEntry> AddressArea;
   std::vector<CompilationUnitEntry> CompilationUnits;
   std::vector<NameTypeEntry> NamesAndTypes;

Modified: lld/trunk/ELF/SyntheticSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.cpp?rev=307867&r1=307866&r2=307867&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.cpp (original)
+++ lld/trunk/ELF/SyntheticSections.cpp Wed Jul 12 16:56:53 2017
@@ -1700,9 +1700,9 @@ unsigned PltSection::getPltRelocOff() co
   return (HeaderSize == 0) ? InX::Plt->getSize() : 0;
 }
 
-GdbIndexSection::GdbIndexSection()
+GdbIndexSection::GdbIndexSection(std::vector<GdbIndexChunk> &&Chunks)
     : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index"),
-      StringPool(llvm::StringTableBuilder::ELF) {}
+      StringPool(llvm::StringTableBuilder::ELF), Chunks(std::move(Chunks)) {}
 
 // Iterative hash function for symbol's name is described in .gdb_index format
 // specification. Note that we use one for version 5 to 7 here, it is different
@@ -1714,11 +1714,10 @@ static uint32_t hash(StringRef Str) {
   return R;
 }
 
-static std::vector<CompilationUnitEntry> readCuList(DWARFContext &Dwarf,
-                                                    InputSection *Sec) {
+static std::vector<CompilationUnitEntry> readCuList(DWARFContext &Dwarf) {
   std::vector<CompilationUnitEntry> Ret;
   for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf.compile_units())
-    Ret.push_back({Sec->OutSecOff + CU->getOffset(), CU->getLength() + 4});
+    Ret.push_back({CU->getOffset(), CU->getLength() + 4});
   return Ret;
 }
 
@@ -1765,19 +1764,15 @@ static std::vector<InputSection *> getDe
   std::vector<InputSection *> Ret;
   for (InputSectionBase *S : InputSections)
     if (InputSection *IS = dyn_cast<InputSection>(S))
-      if (IS->getParent() && IS->Name == ".debug_info")
+      if (IS->Name == ".debug_info")
         Ret.push_back(IS);
   return Ret;
 }
 
 void GdbIndexSection::buildIndex() {
-  std::vector<InputSection *> V = getDebugInfoSections();
-  if (V.empty())
+  if (Chunks.empty())
     return;
 
-  for (InputSection *Sec : V)
-    Chunks.push_back(readDwarf(Sec));
-
   uint32_t CuId = 0;
   for (GdbIndexChunk &D : Chunks) {
     for (AddressEntry &E : D.AddressArea)
@@ -1803,27 +1798,33 @@ void GdbIndexSection::buildIndex() {
   }
 }
 
-GdbIndexChunk GdbIndexSection::readDwarf(InputSection *Sec) {
-  Expected<std::unique_ptr<object::ObjectFile>> Obj =
-      object::ObjectFile::createObjectFile(Sec->File->MB);
-  if (!Obj) {
-    error(toString(Sec->File) + ": error creating DWARF context");
-    return {};
-  }
-
-  DWARFContextInMemory Dwarf(*Obj.get(), nullptr, [&](Error E) {
-    error(toString(Sec->File) + ": error parsing DWARF data:\n>>> " +
-          toString(std::move(E)));
-    return ErrorPolicy::Continue;
-  });
-
+static GdbIndexChunk readDwarf(DWARFContextInMemory &Dwarf, InputSection *Sec) {
   GdbIndexChunk Ret;
-  Ret.CompilationUnits = readCuList(Dwarf, Sec);
+  Ret.DebugInfoSec = Sec;
+  Ret.CompilationUnits = readCuList(Dwarf);
   Ret.AddressArea = readAddressArea(Dwarf, Sec);
   Ret.NamesAndTypes = readPubNamesAndTypes(Dwarf, Config->IsLE);
   return Ret;
 }
 
+template <class ELFT> GdbIndexSection *elf::createGdbIndex() {
+  std::vector<GdbIndexChunk> Chunks;
+  for (InputSection *Sec : getDebugInfoSections()) {
+    InputFile *F = Sec->File;
+    std::error_code EC;
+    ELFObjectFile<ELFT> Obj(F->MB, EC);
+    if (EC)
+      fatal(EC.message());
+    DWARFContextInMemory Dwarf(Obj, nullptr, [&](Error E) {
+      error(toString(F) + ": error parsing DWARF data:\n>>> " +
+            toString(std::move(E)));
+      return ErrorPolicy::Continue;
+    });
+    Chunks.push_back(readDwarf(Dwarf, Sec));
+  }
+  return make<GdbIndexSection>(std::move(Chunks));
+}
+
 static size_t getCuSize(std::vector<GdbIndexChunk> &C) {
   size_t Ret = 0;
   for (GdbIndexChunk &D : C)
@@ -1881,7 +1882,7 @@ void GdbIndexSection::writeTo(uint8_t *B
   // Write the CU list.
   for (GdbIndexChunk &D : Chunks) {
     for (CompilationUnitEntry &Cu : D.CompilationUnits) {
-      write64le(Buf, Cu.CuOffset);
+      write64le(Buf, D.DebugInfoSec->OutSecOff + Cu.CuOffset);
       write64le(Buf + 8, Cu.CuLength);
       Buf += 16;
     }
@@ -2350,6 +2351,11 @@ StringTableSection *InX::ShStrTab;
 StringTableSection *InX::StrTab;
 SymbolTableBaseSection *InX::SymTab;
 
+template GdbIndexSection *elf::createGdbIndex<ELF32LE>();
+template GdbIndexSection *elf::createGdbIndex<ELF32BE>();
+template GdbIndexSection *elf::createGdbIndex<ELF64LE>();
+template GdbIndexSection *elf::createGdbIndex<ELF64BE>();
+
 template void PltSection::addEntry<ELF32LE>(SymbolBody &Sym);
 template void PltSection::addEntry<ELF32BE>(SymbolBody &Sym);
 template void PltSection::addEntry<ELF64LE>(SymbolBody &Sym);

Modified: lld/trunk/ELF/SyntheticSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SyntheticSections.h?rev=307867&r1=307866&r2=307867&view=diff
==============================================================================
--- lld/trunk/ELF/SyntheticSections.h (original)
+++ lld/trunk/ELF/SyntheticSections.h Wed Jul 12 16:56:53 2017
@@ -503,7 +503,7 @@ class GdbIndexSection final : public Syn
   const unsigned SymTabEntrySize = 2 * OffsetTypeSize;
 
 public:
-  GdbIndexSection();
+  GdbIndexSection(std::vector<GdbIndexChunk> &&Chunks);
   void finalizeContents() override;
   void writeTo(uint8_t *Buf) override;
   size_t getSize() const override;
@@ -524,7 +524,6 @@ public:
   std::vector<GdbIndexChunk> Chunks;
 
 private:
-  GdbIndexChunk readDwarf(InputSection *Sec);
   void buildIndex();
 
   uint32_t CuTypesOffset;
@@ -538,6 +537,8 @@ private:
   bool Finalized = false;
 };
 
+template <class ELFT> GdbIndexSection *createGdbIndex();
+
 // --eh-frame-hdr option tells linker to construct a header for all the
 // .eh_frame sections. This header is placed to a section named .eh_frame_hdr
 // and also to a PT_GNU_EH_FRAME segment.

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=307867&r1=307866&r2=307867&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Jul 12 16:56:53 2017
@@ -380,7 +380,7 @@ template <class ELFT> void Writer<ELFT>:
   Add(InX::IgotPlt);
 
   if (Config->GdbIndex) {
-    InX::GdbIndex = make<GdbIndexSection>();
+    InX::GdbIndex = createGdbIndex<ELFT>();
     Add(InX::GdbIndex);
   }
 




More information about the llvm-commits mailing list