Index: ELF/GdbIndex.h =================================================================== --- ELF/GdbIndex.h +++ ELF/GdbIndex.h @@ -45,6 +45,7 @@ // debug information performed. That information futher used // for filling gdb index section areas. struct GdbIndexChunk { + InputSection *DebugInfoSec; std::vector AddressArea; std::vector CompilationUnits; std::vector NamesAndTypes; Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -503,7 +503,7 @@ const unsigned SymTabEntrySize = 2 * OffsetTypeSize; public: - GdbIndexSection(); + GdbIndexSection(std::vector &&Chunks); void finalizeContents() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override; @@ -524,7 +524,6 @@ std::vector Chunks; private: - GdbIndexChunk readDwarf(InputSection *Sec); void buildIndex(); uint32_t CuTypesOffset; @@ -537,6 +536,7 @@ bool Finalized = false; }; +template 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 Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1700,9 +1700,9 @@ return (HeaderSize == 0) ? InX::Plt->getSize() : 0; } -GdbIndexSection::GdbIndexSection() +GdbIndexSection::GdbIndexSection(std::vector &&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 @@ return R; } -static std::vector readCuList(DWARFContext &Dwarf, - InputSection *Sec) { +static std::vector readCuList(DWARFContext &Dwarf) { std::vector Ret; for (std::unique_ptr &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 @@ std::vector Ret; for (InputSectionBase *S : InputSections) if (InputSection *IS = dyn_cast(S)) - if (IS->getParent() && IS->Name == ".debug_info") + if (IS->Name == ".debug_info") Ret.push_back(IS); return Ret; } void GdbIndexSection::buildIndex() { - std::vector 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,34 @@ } } -GdbIndexChunk GdbIndexSection::readDwarf(InputSection *Sec) { - Expected> 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 GdbIndexSection *elf::createGdbIndex() { + std::vector V = getDebugInfoSections(); + std::vector Chunks; + for (InputSection *Sec : V) { + InputFile *F = Sec->File; + std::error_code EC; + ELFObjectFile 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(std::move(Chunks)); +} + static size_t getCuSize(std::vector &C) { size_t Ret = 0; for (GdbIndexChunk &D : C) @@ -1881,7 +1883,7 @@ // 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 +2352,11 @@ StringTableSection *InX::StrTab; SymbolTableBaseSection *InX::SymTab; +template GdbIndexSection *elf::createGdbIndex(); +template GdbIndexSection *elf::createGdbIndex(); +template GdbIndexSection *elf::createGdbIndex(); +template GdbIndexSection *elf::createGdbIndex(); + template void PltSection::addEntry(SymbolBody &Sym); template void PltSection::addEntry(SymbolBody &Sym); template void PltSection::addEntry(SymbolBody &Sym); Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -380,7 +380,7 @@ Add(InX::IgotPlt); if (Config->GdbIndex) { - InX::GdbIndex = make(); + InX::GdbIndex = createGdbIndex(); Add(InX::GdbIndex); }