Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -2413,17 +2413,26 @@ } static std::vector -readPubNamesAndTypes(DWARFContext &Dwarf, uint32_t Idx) { +readPubNamesAndTypes(DWARFContext &Dwarf, + const std::vector &CUs) { StringRef Sec1 = Dwarf.getDWARFObj().getGnuPubNamesSection(); StringRef Sec2 = Dwarf.getDWARFObj().getGnuPubTypesSection(); std::vector Ret; for (StringRef Sec : {Sec1, Sec2}) { DWARFDebugPubTable Table(Sec, Config->IsLE, true); - for (const DWARFDebugPubTable::Set &Set : Table.getData()) + for (const DWARFDebugPubTable::Set &Set : Table.getData()) { + // The CU offset should be added to I when the entry is written into the + // constant pool. + uint32_t I = + std::lower_bound(CUs.begin(), CUs.end(), Set.Offset, + [](const GdbIndexSection::CuEntry &CU, + uint32_t Off) { return CU.CuOffset < Off; }) - + CUs.begin(); for (const DWARFDebugPubTable::Entry &Ent : Set.Entries) Ret.push_back({{Ent.Name, computeGdbHash(Ent.Name)}, - (Ent.Descriptor.toBits() << 24) | Idx}); + (Ent.Descriptor.toBits() << 24) | I}); + } } return Ret; } @@ -2431,10 +2440,18 @@ // Create a list of symbols from a given list of symbol names and types // by uniquifying them by name. static std::vector -createSymbols(ArrayRef> NameTypes) { +createSymbols(ArrayRef> NameTypes, + const std::vector &Chunks) { typedef GdbIndexSection::GdbSymbol GdbSymbol; typedef GdbIndexSection::NameTypeEntry NameTypeEntry; + uint32_t CuOff = 0; + std::vector CuOffs(Chunks.size()); + for (uint32_t I = 0, E = Chunks.size(); I != E; ++I) { + CuOffs[I] = CuOff; + CuOff += Chunks[I].CompilationUnits.size(); + } + // The number of symbols we will handle in this function is of the order // of millions for very large executables, so we use multi-threading to // speed it up. @@ -2451,21 +2468,24 @@ // Instantiate GdbSymbols while uniqufying them by name. std::vector> Symbols(NumShards); parallelForEachN(0, Concurrency, [&](size_t ThreadId) { + uint32_t I = 0; for (ArrayRef Entries : NameTypes) { for (const NameTypeEntry &Ent : Entries) { size_t ShardId = Ent.Name.hash() >> Shift; if ((ShardId & (Concurrency - 1)) != ThreadId) continue; + uint32_t V = Ent.Type + CuOffs[I]; size_t &Idx = Map[ShardId][Ent.Name]; if (Idx) { - Symbols[ShardId][Idx - 1].CuVector.push_back(Ent.Type); + Symbols[ShardId][Idx - 1].CuVector.push_back(V); continue; } Idx = Symbols[ShardId].size() + 1; - Symbols[ShardId].push_back({Ent.Name, {Ent.Type}, 0, 0}); + Symbols[ShardId].push_back({Ent.Name, {V}, 0, 0}); } + ++I; } }); @@ -2517,12 +2537,12 @@ Chunks[I].Sec = Sections[I]; Chunks[I].CompilationUnits = readCuList(Dwarf); Chunks[I].AddressAreas = readAddressAreas(Dwarf, Sections[I]); - NameTypes[I] = readPubNamesAndTypes(Dwarf, I); + NameTypes[I] = readPubNamesAndTypes(Dwarf, Chunks[I].CompilationUnits); }); auto *Ret = make(); Ret->Chunks = std::move(Chunks); - Ret->Symbols = createSymbols(NameTypes); + Ret->Symbols = createSymbols(NameTypes, Ret->Chunks); Ret->initOutputSize(); return Ret; }