Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -210,22 +210,30 @@ } // namespace +template struct RelRelaReloc { + uint32_t Type; + uint32_t Symbol; + typename ELFT::uint Offset; + typename ELFT::uint Info; + Optional Addend; +}; + template class Relocation { public: - Relocation(const typename ELFT::Rel &R, bool IsMips64EL) - : Type(R.getType(IsMips64EL)), Symbol(R.getSymbol(IsMips64EL)), - Offset(R.r_offset), Info(R.r_info) {} + Relocation(const typename ELFT::Rel &R, bool IsMips64EL) { + RelRela = {R.getType(IsMips64EL), R.getSymbol(IsMips64EL), R.r_offset, + R.r_info, None}; + } Relocation(const typename ELFT::Rela &R, bool IsMips64EL) : Relocation((const typename ELFT::Rel &)R, IsMips64EL) { - Addend = R.r_addend; + RelRela->Addend = R.r_addend; } - uint32_t Type; - uint32_t Symbol; - typename ELFT::uint Offset; - typename ELFT::uint Info; - Optional Addend; + Relocation(const typename ELFT::Relr &R) : Relr(R) {} + + Optional> RelRela; + Optional Relr; }; template class ELFDumper : public ObjDumper { @@ -402,7 +410,7 @@ Expected> getVersionDependencies(const Elf_Shdr &Sec) const; - Expected> getRelocationTarget(const Relocation &R, + Expected> getRelocationTarget(const RelRelaReloc &R, const Elf_Shdr *SymTab) const; std::function WarningHandler; @@ -727,6 +735,14 @@ : Obj(*Dumper.getElfObject().getELFFile()), ElfObj(Dumper.getElfObject()), Dumper(Dumper) { FileName = ElfObj.getFileName(); + + PrintRelocFn = [&](const Relocation &R, unsigned Ndx, + const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { + if (R.Relr) + printRelrReloc(*R.Relr); + else + printReloc(*R.RelRela, Ndx, Sec, SymTab); + }; } virtual ~DumpStyle() = default; @@ -777,11 +793,15 @@ function_ref OnSectionStart, function_ref OnSectionEntry); - virtual void printReloc(const Relocation &R, unsigned RelIndex, + virtual void printReloc(const RelRelaReloc &R, unsigned RelIndex, const Elf_Shdr &Sec, const Elf_Shdr *SymTab) = 0; virtual void printRelrReloc(const Elf_Relr &R) = 0; - virtual void printDynamicReloc(const Relocation &R) = 0; - void printRelocationsHelper(const Elf_Shdr &Sec); + virtual void printDynamicReloc(const RelRelaReloc &R) = 0; + void forEachRelocationDo( + const Elf_Shdr &Sec, bool RawRelr, + llvm::function_ref &, unsigned, + const Elf_Shdr &, const Elf_Shdr *)> + Fn); void printDynamicRelocationsHelper(); virtual void printDynamicRelocHeader(unsigned Type, StringRef Name, const DynRegionInfo &Reg){}; @@ -794,6 +814,10 @@ const ELFFile &Obj; const ELFObjectFile &ElfObj; + std::function &R, unsigned Ndx, + const Elf_Shdr &Sec, const Elf_Shdr *Symtab)> + PrintRelocFn; + private: const ELFDumper &Dumper; }; @@ -897,18 +921,18 @@ } void printHashedSymbol(const Elf_Sym *Sym, unsigned SymIndex, StringRef StrTable, uint32_t Bucket); - void printReloc(const Relocation &R, unsigned RelIndex, + void printReloc(const RelRelaReloc &R, unsigned RelIndex, const Elf_Shdr &Sec, const Elf_Shdr *SymTab) override; void printRelrReloc(const Elf_Relr &R) override; - void printRelRelaReloc(const Relocation &R, + void printRelRelaReloc(const RelRelaReloc &R, const RelSymbol &RelSym); void printSymbol(const Elf_Sym &Symbol, unsigned SymIndex, Optional StrTable, bool IsDynamic, bool NonVisibilityBitsUsed) override; void printDynamicRelocHeader(unsigned Type, StringRef Name, const DynRegionInfo &Reg) override; - void printDynamicReloc(const Relocation &R) override; + void printDynamicReloc(const RelRelaReloc &R) override; std::string getSymbolSectionNdx(const Elf_Sym &Symbol, unsigned SymIndex); void printProgramHeaders(); @@ -962,12 +986,12 @@ void printMipsABIFlags() override; private: - void printReloc(const Relocation &R, unsigned RelIndex, + void printReloc(const RelRelaReloc &R, unsigned RelIndex, const Elf_Shdr &Sec, const Elf_Shdr *SymTab) override; void printRelrReloc(const Elf_Relr &R) override; - void printDynamicReloc(const Relocation &R) override; + void printDynamicReloc(const RelRelaReloc &R) override; - void printRelRelaReloc(const Relocation &R, StringRef SymbolName); + void printRelRelaReloc(const RelRelaReloc &R, StringRef SymbolName); void printSymbols(); void printDynamicSymbols(); void printSymbolSection(const Elf_Sym &Symbol, unsigned SymIndex); @@ -1078,7 +1102,7 @@ template Expected> -ELFDumper::getRelocationTarget(const Relocation &R, +ELFDumper::getRelocationTarget(const RelRelaReloc &R, const Elf_Shdr *SymTab) const { if (R.Symbol == 0) return RelSymbol(nullptr, ""); @@ -3644,7 +3668,7 @@ } template -void GNUStyle::printReloc(const Relocation &R, unsigned RelIndex, +void GNUStyle::printReloc(const RelRelaReloc &R, unsigned RelIndex, const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { Expected> Target = this->dumper().getRelocationTarget(R, SymTab); @@ -3661,7 +3685,7 @@ } template -void GNUStyle::printRelRelaReloc(const Relocation &R, +void GNUStyle::printRelRelaReloc(const RelRelaReloc &R, const RelSymbol &RelSym) { // First two fields are bit width dependent. The rest of them are fixed width. unsigned Bias = ELFT::Is64Bits ? 8 : 0; @@ -3782,7 +3806,7 @@ << to_hexString(Offset, false) << " contains " << EntriesNum << " entries:\n"; printRelocHeaderFields(OS, Sec.sh_type); - this->printRelocationsHelper(Sec); + this->forEachRelocationDo(Sec, opts::RawRelr, this->PrintRelocFn); } if (!HasRelocSections) OS << "\nThere are no relocations in this file.\n"; @@ -4514,7 +4538,7 @@ template RelSymbol getSymbolForReloc(const ELFFile &Obj, StringRef FileName, const ELFDumper &Dumper, - const Relocation &Reloc) { + const RelRelaReloc &Reloc) { using Elf_Sym = typename ELFT::Sym; auto WarnAndReturn = [&](const Elf_Sym *Sym, const Twine &Reason) -> RelSymbol { @@ -4557,7 +4581,7 @@ } // namespace template -void GNUStyle::printDynamicReloc(const Relocation &R) { +void GNUStyle::printDynamicReloc(const RelRelaReloc &R) { printRelRelaReloc( R, getSymbolForReloc(this->Obj, this->FileName, this->dumper(), R)); } @@ -4612,14 +4636,14 @@ if (DynRelaRegion.Size > 0) { printDynamicRelocHeader(ELF::SHT_RELA, "RELA", DynRelaRegion); for (const Elf_Rela &Rela : this->dumper().dyn_relas()) - printDynamicReloc(Relocation(Rela, IsMips64EL)); + printDynamicReloc(*Relocation(Rela, IsMips64EL).RelRela); } const DynRegionInfo &DynRelRegion = this->dumper().getDynRelRegion(); if (DynRelRegion.Size > 0) { printDynamicRelocHeader(ELF::SHT_REL, "REL", DynRelRegion); for (const Elf_Rel &Rel : this->dumper().dyn_rels()) - printDynamicReloc(Relocation(Rel, IsMips64EL)); + printDynamicReloc(*Relocation(Rel, IsMips64EL).RelRela); } const DynRegionInfo &DynRelrRegion = this->dumper().getDynRelrRegion(); @@ -4627,7 +4651,7 @@ printDynamicRelocHeader(ELF::SHT_REL, "RELR", DynRelrRegion); Elf_Relr_Range Relrs = this->dumper().dyn_relrs(); for (const Elf_Rel &Rel : Obj.decode_relrs(Relrs)) - printDynamicReloc(Relocation(Rel, IsMips64EL)); + printDynamicReloc(*Relocation(Rel, IsMips64EL).RelRela); } const DynRegionInfo &DynPLTRelRegion = this->dumper().getDynPLTRelRegion(); @@ -4635,11 +4659,11 @@ if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) { printDynamicRelocHeader(ELF::SHT_RELA, "PLT", DynPLTRelRegion); for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef()) - printDynamicReloc(Relocation(Rela, IsMips64EL)); + printDynamicReloc(*Relocation(Rela, IsMips64EL).RelRela); } else { printDynamicRelocHeader(ELF::SHT_REL, "PLT", DynPLTRelRegion); for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef()) - printDynamicReloc(Relocation(Rel, IsMips64EL)); + printDynamicReloc(*Relocation(Rel, IsMips64EL).RelRela); } } } @@ -5610,7 +5634,11 @@ } template -void DumpStyle::printRelocationsHelper(const Elf_Shdr &Sec) { +void DumpStyle::forEachRelocationDo( + const Elf_Shdr &Sec, bool RawRelr, + llvm::function_ref &, unsigned, + const Elf_Shdr &, const Elf_Shdr *)> + Fn) { auto Warn = [&](Error &&E, const Twine &Prefix = "unable to read relocations from") { this->reportUniqueWarning(createError(Prefix + " " + describe(Obj, Sec) + @@ -5636,7 +5664,7 @@ case ELF::SHT_REL: if (Expected RangeOrErr = Obj.rels(Sec)) { for (const Elf_Rel &R : *RangeOrErr) - printReloc(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); + Fn(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); } else { Warn(RangeOrErr.takeError()); } @@ -5644,7 +5672,7 @@ case ELF::SHT_RELA: if (Expected RangeOrErr = Obj.relas(Sec)) { for (const Elf_Rela &R : *RangeOrErr) - printReloc(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); + Fn(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); } else { Warn(RangeOrErr.takeError()); } @@ -5656,22 +5684,22 @@ Warn(RangeOrErr.takeError()); break; } - if (opts::RawRelr) { + if (RawRelr) { for (const Elf_Relr &R : *RangeOrErr) - printRelrReloc(R); + Fn(R, ++RelNdx, Sec, /*SymTab=*/nullptr); break; } for (const Elf_Rel &R : Obj.decode_relrs(*RangeOrErr)) - printReloc(Relocation(R, IsMips64EL), ++RelNdx, Sec, - /*SymTab=*/nullptr); + Fn(Relocation(R, IsMips64EL), ++RelNdx, Sec, + /*SymTab=*/nullptr); break; } case ELF::SHT_ANDROID_REL: case ELF::SHT_ANDROID_RELA: if (Expected> RelasOrErr = Obj.android_relas(Sec)) { for (const Elf_Rela &R : *RelasOrErr) - printReloc(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); + Fn(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); } else { Warn(RelasOrErr.takeError()); } @@ -6275,7 +6303,7 @@ unsigned SecNdx = &Sec - &cantFail(this->Obj.sections()).front(); W.startLine() << "Section (" << SecNdx << ") " << Name << " {\n"; W.indent(); - this->printRelocationsHelper(Sec); + this->forEachRelocationDo(Sec, opts::RawRelr, this->PrintRelocFn); W.unindent(); W.startLine() << "}\n"; } @@ -6286,7 +6314,7 @@ } template -void LLVMStyle::printReloc(const Relocation &R, unsigned RelIndex, +void LLVMStyle::printReloc(const RelRelaReloc &R, unsigned RelIndex, const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { Expected> Target = this->dumper().getRelocationTarget(R, SymTab); @@ -6301,7 +6329,7 @@ } template -void LLVMStyle::printRelRelaReloc(const Relocation &R, +void LLVMStyle::printRelRelaReloc(const RelRelaReloc &R, StringRef SymbolName) { SmallString<32> RelocName; this->Obj.getRelocationTypeName(R.Type, RelocName); @@ -6346,7 +6374,7 @@ if (opts::SectionRelocations) { ListScope D(W, "Relocations"); - this->printRelocationsHelper(Sec); + this->forEachRelocationDo(Sec, opts::RawRelr, this->PrintRelocFn); } if (opts::SectionSymbols) { @@ -6525,7 +6553,7 @@ } template -void LLVMStyle::printDynamicReloc(const Relocation &R) { +void LLVMStyle::printDynamicReloc(const RelRelaReloc &R) { RelSymbol S = getSymbolForReloc(this->Obj, this->FileName, this->dumper(), R); printRelRelaReloc(R, S.Name);