From 702dac6d35f54c0e093e901a9b420b466ef315cd Mon Sep 17 00:00:00 2001 From: George Rimar Date: Wed, 12 Apr 2017 08:59:15 +0000 Subject: [PATCH] [DWARF] - Refactoring of DWARFContextInMemory implementation. This change is basically relative to D31136, where I initially wanted to implement some relocations handling optimization which shows it can give significant boost. Though even without any caching algorithm looks code can have some cleanup at first. Refactoring separates out code for taking symbol address, used in relocations computation. Differential revision: https://reviews.llvm.org/D31747 llvm-svn: 300039 --- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 135 ++++++++++++++++-------------- 1 file changed, 71 insertions(+), 64 deletions(-) diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index a9ab610..05dc5bd 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -616,6 +616,66 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address, return InliningInfo; } +static Error createError(const Twine &Reason, llvm::Error E) { + return make_error(Reason + toString(std::move(E)), + inconvertibleErrorCode()); +} + +/// 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) { + 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) + return createError("error: failed to compute symbol address: ", + SymAddrOrErr.takeError()); + + // Also remember what section this symbol is in for later + auto SectOrErr = Sym->getSection(); + if (!SectOrErr) + return createError("error: failed to get symbol section: ", + SectOrErr.takeError()); + + RSec = *SectOrErr; + Ret = *SymAddrOrErr; + } 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) + // 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. + if (L && RSec != Obj.section_end()) + if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec)) + 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 = cast(&Obj); + auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl()); + return MachObj->isRelocationScattered(RelocInfo); +} + DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L) : IsLittleEndian(Obj.isLittleEndian()), @@ -721,73 +781,20 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, if (Section.relocation_begin() != Section.relocation_end()) { uint64_t SectionSize = RelocatedSection->getSize(); 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(); + object::symbol_iterator RelSym = Reloc.getSymbol(); + Expected SymAddrOrErr = getSymbolAddress(Obj, Reloc, L); + if (!SymAddrOrErr) { + errs() << toString(std::move(SymAddrOrErr.takeError())) << '\n'; + continue; } object::RelocVisitor V(Obj); - object::RelocToApply R(V.visit(Type, Reloc, SymAddr)); + object::RelocToApply R(V.visit(Reloc.getType(), Reloc, *SymAddrOrErr)); if (V.error()) { SmallString<32> Name; Reloc.getTypeName(Name); @@ -795,7 +802,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj, << Name << "\n"; 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 " -- 2.7.4