Index: ELF/SyntheticSections.h =================================================================== --- ELF/SyntheticSections.h +++ ELF/SyntheticSections.h @@ -501,15 +501,15 @@ const unsigned SymTabEntrySize = 2 * OffsetTypeSize; public: + typedef std::pair CuEntry; + typedef std::pair NameEntry; + GdbIndexSection(); void finalizeContents() override; void writeTo(uint8_t *Buf) override; size_t getSize() const override; bool empty() const override; - // Pairs of [CU Offset, CU length]. - std::vector> CompilationUnits; - llvm::StringTableBuilder StringPool; GdbHashTab SymbolTable; @@ -517,10 +517,16 @@ // The CU vector portion of the constant pool. std::vector>> CuVectors; - std::vector AddressArea; + std::vector> AddressArea; + + std::vector> NamesAndTypes; + + // Pairs of [CU Offset, CU length] for each object. + std::vector> CompilationUnits; private: - void readDwarf(InputSection *Sec); + void readDwarf(InputSection *Sec, size_t ObjNdx); + void buildIndex(); uint32_t CuTypesOffset; uint32_t SymTabOffset; Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -1695,8 +1695,8 @@ return R; } -static std::vector> -readCuList(DWARFContext &Dwarf, InputSection *Sec) { +static std::vector readCuList(DWARFContext &Dwarf, + InputSection *Sec) { std::vector> Ret; for (std::unique_ptr &CU : Dwarf.compile_units()) Ret.push_back({Sec->OutSecOff + CU->getOffset(), CU->getLength() + 4}); @@ -1713,10 +1713,11 @@ return nullptr; } -static std::vector -readAddressArea(DWARFContext &Dwarf, InputSection *Sec, size_t CurrentCU) { +static std::vector readAddressArea(DWARFContext &Dwarf, + InputSection *Sec) { std::vector Ret; + size_t CurrentCU = 0; for (std::unique_ptr &CU : Dwarf.compile_units()) { DWARFAddressRangesVector Ranges; CU->collectAddressRanges(Ranges); @@ -1757,7 +1758,54 @@ std::unique_ptr clone() const override { return {}; } }; -void GdbIndexSection::readDwarf(InputSection *Sec) { +void GdbIndexSection::buildIndex() { + std::vector InfoV; + for (InputSectionBase *S : InputSections) + if (InputSection *IS = dyn_cast(S)) + if (IS->OutSec && IS->Name == ".debug_info") + InfoV.push_back(IS); + + if (InfoV.empty()) + return; + + size_t Size = InfoV.size(); + CompilationUnits.resize(Size); + AddressArea.resize(Size); + NamesAndTypes.resize(Size); + + parallelForEachN(0, Size, [&](size_t I) { + readDwarf(InfoV[I], I); + }); + + size_t CuId = 0; + for (size_t I = 0; I < Size; ++I) { + // Now when we know amount of compilation units for each object, we fixup + // the compilation units ID's in address area section. + for (AddressEntry &E : AddressArea[I]) + E.CuIndex += CuId; + + // Populate constant pool area. + for (std::pair &Pair : NamesAndTypes[I]) { + uint32_t Hash = hash(Pair.first); + size_t Offset = StringPool.add(Pair.first); + + bool IsNew; + GdbSymbol *Sym; + std::tie(IsNew, Sym) = SymbolTable.add(Hash, Offset); + if (IsNew) { + Sym->CuVectorIndex = CuVectors.size(); + CuVectors.push_back({{CuId, Pair.second}}); + continue; + } + + CuVectors[Sym->CuVectorIndex].push_back({CuId, Pair.second}); + } + + CuId += CompilationUnits[I].size(); + } +} + +void GdbIndexSection::readDwarf(InputSection *Sec, size_t ObjNdx) { Expected> Obj = object::ObjectFile::createObjectFile(Sec->File->MB); if (!Obj) { @@ -1767,32 +1815,16 @@ ObjInfoTy ObjInfo; DWARFContextInMemory Dwarf(*Obj.get(), &ObjInfo); + CompilationUnits[ObjNdx] = readCuList(Dwarf, Sec); + AddressArea[ObjNdx] = readAddressArea(Dwarf, Sec); + NamesAndTypes[ObjNdx] = readPubNamesAndTypes(Dwarf, Config->IsLE); +} - size_t CuId = CompilationUnits.size(); - for (std::pair &P : readCuList(Dwarf, Sec)) - CompilationUnits.push_back(P); - - for (AddressEntry &Ent : readAddressArea(Dwarf, Sec, CuId)) - AddressArea.push_back(Ent); - - std::vector> NamesAndTypes = - readPubNamesAndTypes(Dwarf, Config->IsLE); - - for (std::pair &Pair : NamesAndTypes) { - uint32_t Hash = hash(Pair.first); - size_t Offset = StringPool.add(Pair.first); - - bool IsNew; - GdbSymbol *Sym; - std::tie(IsNew, Sym) = SymbolTable.add(Hash, Offset); - if (IsNew) { - Sym->CuVectorIndex = CuVectors.size(); - CuVectors.push_back({{CuId, Pair.second}}); - continue; - } - - CuVectors[Sym->CuVectorIndex].push_back({CuId, Pair.second}); - } +template static size_t findSize(std::vector> &C) { + size_t Ret = 0; + for (std::vector &V : C) + Ret += V.size(); + return Ret; } void GdbIndexSection::finalizeContents() { @@ -1800,17 +1832,14 @@ return; Finalized = true; - for (InputSectionBase *S : InputSections) - if (InputSection *IS = dyn_cast(S)) - if (IS->OutSec && IS->Name == ".debug_info") - readDwarf(IS); + buildIndex(); SymbolTable.finalizeContents(); // GdbIndex header consist from version fields // and 5 more fields with different kinds of offsets. - CuTypesOffset = CuListOffset + CompilationUnits.size() * CompilationUnitSize; - SymTabOffset = CuTypesOffset + AddressArea.size() * AddressEntrySize; + CuTypesOffset = CuListOffset + findSize(CompilationUnits) * CompilationUnitSize; + SymTabOffset = CuTypesOffset + findSize(AddressArea) * AddressEntrySize; ConstantPoolOffset = SymTabOffset + SymbolTable.getCapacity() * SymTabEntrySize; @@ -1839,19 +1868,23 @@ Buf += 24; // Write the CU list. - for (std::pair CU : CompilationUnits) { - write64le(Buf, CU.first); - write64le(Buf + 8, CU.second); - Buf += 16; + for (std::vector &V : CompilationUnits) { + for (std::pair CU : V) { + write64le(Buf, CU.first); + write64le(Buf + 8, CU.second); + Buf += 16; + } } // Write the address area. - for (AddressEntry &E : AddressArea) { - uint64_t BaseAddr = E.Section->OutSec->Addr + E.Section->getOffset(0); - write64le(Buf, BaseAddr + E.LowAddress); - write64le(Buf + 8, BaseAddr + E.HighAddress); - write32le(Buf + 16, E.CuIndex); - Buf += 20; + for (std::vector &V : AddressArea) { + for (AddressEntry &E : V) { + uint64_t BaseAddr = E.Section->OutSec->Addr + E.Section->getOffset(0); + write64le(Buf, BaseAddr + E.LowAddress); + write64le(Buf + 8, BaseAddr + E.HighAddress); + write32le(Buf + 16, E.CuIndex); + Buf += 20; + } } // Write the symbol table.