Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -883,16 +883,23 @@ /// Returns the address of symbol relocation used against. Used for futher /// relocations computation. Symbol's section load address is taken in account if /// LoadedObjectInfo interface is provided. -static Expected getSymbolAddress(const object::ObjectFile &Obj, - const RelocationRef &Reloc, - const LoadedObjectInfo *L) { +static Expected +getSymbolAddress(const object::ObjectFile &Obj, const RelocationRef &Reloc, + const LoadedObjectInfo *L, + std::map &Cache) { uint64_t Ret = 0; object::section_iterator RSec = Obj.section_end(); object::symbol_iterator Sym = Reloc.getSymbol(); + std::map::iterator CacheIt = Cache.end(); // First calculate the address of the symbol or section as it appears // in the object file if (Sym != Obj.symbol_end()) { + bool New; + std::tie(CacheIt, New) = Cache.insert({*Sym, 0}); + if (!New) + return CacheIt->second; + Expected SymAddrOrErr = Sym->getAddress(); if (!SymAddrOrErr) return createError("error: failed to compute symbol address: ", @@ -921,6 +928,10 @@ if (L && RSec != Obj.section_end()) if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec)) Ret += SectionLoadAddress - RSec->getAddress(); + + if (CacheIt != Cache.end()) + CacheIt->second = Ret; + return Ret; } @@ -1038,6 +1049,7 @@ continue; } + std::map AddrCache; if (Section.relocation_begin() != Section.relocation_end()) { uint64_t SectionSize = RelocatedSection->getSize(); for (const RelocationRef &Reloc : Section.relocations()) { @@ -1046,7 +1058,8 @@ if (isRelocScattered(Obj, Reloc)) continue; - Expected SymAddrOrErr = getSymbolAddress(Obj, Reloc, L); + Expected SymAddrOrErr = + getSymbolAddress(Obj, Reloc, L, AddrCache); if (!SymAddrOrErr) { errs() << toString(SymAddrOrErr.takeError()) << '\n'; continue;