Index: ELF/GdbIndex.h =================================================================== --- ELF/GdbIndex.h +++ ELF/GdbIndex.h @@ -23,6 +23,15 @@ InputSectionBase *Sec = nullptr; }; +struct RelocCache { + const void *FirstReloc; + uint64_t NumRelocs; + uint64_t NumProccessedRelocs; + llvm::DenseMap OffsetToIndex; + + template uint64_t getIndex(uint64_t Offset); +}; + template class LLDDwarfObj final : public llvm::DWARFObject { ObjFile *Obj; LLDDWARFSection InfoSection; @@ -31,11 +40,11 @@ StringRef AbbrevSection; StringRef GnuPubNamesSection; StringRef GnuPubTypesSection; + llvm::DenseMap RelocationsCache; template - llvm::Optional findAux(const InputSectionBase &Sec, - uint64_t Pos, - ArrayRef Rels) const; + llvm::Optional + findAux(const InputSectionBase &Sec, uint64_t Pos, ArrayRef Rels); public: explicit LLDDwarfObj(ObjFile *Obj); Index: ELF/GdbIndex.cpp =================================================================== --- ELF/GdbIndex.cpp +++ ELF/GdbIndex.cpp @@ -71,19 +71,48 @@ } } +template uint64_t RelocCache::getIndex(uint64_t Offset) { + auto It = OffsetToIndex.find(Offset); + if (It != OffsetToIndex.end()) + return It->second; + + ArrayRef V(static_cast(FirstReloc), NumRelocs); + V = V.drop_front(NumProccessedRelocs); + + while (!V.empty()) { + const RelTy &Rel = V.front(); + V = V.drop_front(); + uint64_t Index = NumProccessedRelocs++; + + OffsetToIndex[Rel.r_offset] = Index; + if (Rel.r_offset == Offset) + return Index; + } + + return (uint64_t)-1; +} + // Find if there is a relocation at Pos in Sec. The code is a bit // more complicated than usual because we need to pass a section index // to llvm since it has no idea about InputSection. template template -Optional -LLDDwarfObj::findAux(const InputSectionBase &Sec, uint64_t Pos, - ArrayRef Rels) const { - auto I = llvm::find_if(Rels, - [=](const RelTy &Rel) { return Rel.r_offset == Pos; }); - if (I == Rels.end()) - return None; - const RelTy &Rel = *I; +Optional LLDDwarfObj::findAux(const InputSectionBase &Sec, + uint64_t Pos, + ArrayRef Rels) { + auto P = RelocationsCache.insert({&Sec, {}}); + RelocCache &Cache = P.first->second; + if (P.second) { + Cache.FirstReloc = Rels.data(); + Cache.NumRelocs = Rels.size(); + Cache.NumProccessedRelocs = 0; + } + + uint64_t Index = Cache.getIndex(Pos); + if (Index == (uint64_t)-1) + return None; + + const RelTy &Rel = Rels[Index]; const ObjFile *File = Sec.getFile(); uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL); const typename ELFT::Sym &Sym = File->getELFSymbols()[SymIndex]; @@ -106,8 +135,10 @@ uint64_t Pos) const { auto &Sec = static_cast(S); if (Sec.Sec->AreRelocsRela) - return findAux(*Sec.Sec, Pos, Sec.Sec->template relas()); - return findAux(*Sec.Sec, Pos, Sec.Sec->template rels()); + return const_cast *>(this)->findAux( + *Sec.Sec, Pos, Sec.Sec->template relas()); + return const_cast *>(this)->findAux( + *Sec.Sec, Pos, Sec.Sec->template rels()); } template class elf::LLDDwarfObj;