Index: DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- DebugInfo/DWARF/DWARFContext.cpp +++ DebugInfo/DWARF/DWARFContext.cpp @@ -616,6 +616,74 @@ return InliningInfo; } +static void reportError(StringRef Msg, llvm::Error E) { + std::string Buf; + raw_string_ostream OS(Buf); + logAllUnhandledErrors(std::move(E), OS, ""); + OS.flush(); + errs() << Msg << Buf << '\n'; +} + +static uint64_t getSymbolAddress(const object::ObjectFile &Obj, + const LoadedObjectInfo *L, + const RelocationRef &Reloc) { + uint64_t Ret = 0; + object::section_iterator RSec = Obj.section_end(); + object::symbol_iterator Sym = Reloc.getSymbol(); + + // First calculate the address of the symbol or section as it appears + // in the object file + if (Sym != Obj.symbol_end()) { + Expected SymAddrOrErr = Sym->getAddress(); + if (!SymAddrOrErr) { + reportError("error: failed to compute symbol address: ", + SymAddrOrErr.takeError()); + return (uint64_t)-1; + } + Ret = *SymAddrOrErr; + + // Also remember what section this symbol is in for later + auto SectOrErr = Sym->getSection(); + if (!SectOrErr) { + reportError("error: failed to get symbol section: ", + SectOrErr.takeError()); + return (uint64_t)-1; + } + RSec = *SectOrErr; + } else if (auto *MObj = dyn_cast(&Obj)) { + RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl()); + Ret = RSec->getAddress(); + } + + // If we are given load addresses for the sections, we need to adjust: + // SymAddr = (Address of Symbol Or Section in File) - + // (Address of Section in File) + + // (Load Address of Section) + if (L != nullptr && RSec != Obj.section_end()) { + // RSec is now either the section being targeted or the section + // containing the symbol being targeted. In either case, + // we need to perform the same computation. + StringRef SecName; + RSec->getName(SecName); + uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec); + if (SectionLoadAddress != 0) + Ret += SectionLoadAddress - RSec->getAddress(); + } + + return Ret; +} + +static bool isRelocScattered(const object::ObjectFile &Obj, + const RelocationRef &Reloc) { + if (!isa(&Obj)) + return false; + // MachO also has relocations that point to sections and + // scattered relocations. + const MachOObjectFile *MachObj = dyn_cast(&Obj); + auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl()); + return MachObj->isRelocationScattered(RelocInfo); +} + DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L) : IsLittleEndian(Obj.isLittleEndian()), @@ -720,74 +788,25 @@ if (Section.relocation_begin() != Section.relocation_end()) { uint64_t SectionSize = RelocatedSection->getSize(); + + uint64_t SymAddr = 0; + object::symbol_iterator Sym = Obj.symbol_end(); for (const RelocationRef &Reloc : Section.relocations()) { - uint64_t Address = Reloc.getOffset(); - uint64_t Type = Reloc.getType(); - uint64_t SymAddr = 0; - uint64_t SectionLoadAddress = 0; - object::symbol_iterator Sym = Reloc.getSymbol(); - object::section_iterator RSec = Obj.section_end(); - - // First calculate the address of the symbol or section as it appears - // in the objct file - if (Sym != Obj.symbol_end()) { - Expected SymAddrOrErr = Sym->getAddress(); - if (!SymAddrOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SymAddrOrErr.takeError(), OS, ""); - OS.flush(); - errs() << "error: failed to compute symbol address: " - << Buf << '\n'; - continue; - } - SymAddr = *SymAddrOrErr; - // Also remember what section this symbol is in for later - auto SectOrErr = Sym->getSection(); - if (!SectOrErr) { - std::string Buf; - raw_string_ostream OS(Buf); - logAllUnhandledErrors(SectOrErr.takeError(), OS, ""); - OS.flush(); - errs() << "error: failed to get symbol section: " - << Buf << '\n'; - continue; - } - RSec = *SectOrErr; - } else if (auto *MObj = dyn_cast(&Obj)) { - // MachO also has relocations that point to sections and - // scattered relocations. - auto RelocInfo = MObj->getRelocation(Reloc.getRawDataRefImpl()); - if (MObj->isRelocationScattered(RelocInfo)) { - // FIXME: it's not clear how to correctly handle scattered - // relocations. - continue; - } else { - RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl()); - SymAddr = RSec->getAddress(); - } - } + // FIXME: it's not clear how to correctly handle scattered + // relocations. + if (isRelocScattered(Obj, Reloc)) + continue; - // If we are given load addresses for the sections, we need to adjust: - // SymAddr = (Address of Symbol Or Section in File) - - // (Address of Section in File) + - // (Load Address of Section) - if (L != nullptr && RSec != Obj.section_end()) { - // RSec is now either the section being targeted or the section - // containing the symbol being targeted. In either case, - // we need to perform the same computation. - StringRef SecName; - RSec->getName(SecName); -// dbgs() << "Name: '" << SecName -// << "', RSec: " << RSec->getRawDataRefImpl() -// << ", Section: " << Section.getRawDataRefImpl() << "\n"; - SectionLoadAddress = L->getSectionLoadAddress(*RSec); - if (SectionLoadAddress != 0) - SymAddr += SectionLoadAddress - RSec->getAddress(); + // This is simple cache used to avoid calculation of symbol address + // if symbol did not change from previous relocation loop iteration. + object::symbol_iterator RelSym = Reloc.getSymbol(); + if (Sym == Obj.symbol_end() || Sym != RelSym) { + SymAddr = getSymbolAddress(Obj, L, Reloc); + Sym = RelSym; } object::RelocVisitor V(Obj); - object::RelocToApply R(V.visit(Type, Reloc, SymAddr)); + object::RelocToApply R(V.visit(Reloc.getType(), Reloc, SymAddr)); if (V.error()) { SmallString<32> Name; Reloc.getTypeName(Name); @@ -796,6 +815,7 @@ continue; } + uint64_t Address = Reloc.getOffset(); if (Address + R.Width > SectionSize) { errs() << "error: " << R.Width << "-byte relocation starting " << Address << " bytes into section " << name << " which is "