Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -205,6 +205,22 @@ } // namespace +template class Relocation { +public: + using Elf_Rel = typename ELFT::Rel; + using Elf_Rela = typename ELFT::Rela; + + Relocation(const Elf_Rel &R) : Reloc(R) {} + Relocation(const Elf_Rela &R) : Reloc(R), Addend(R.r_addend) {} + + Optional getAddend() const { return Addend; } + const Elf_Rel &getRel() const { return Reloc; } + +private: + const Elf_Rel &Reloc; + Optional Addend; +}; + template class ELFDumper : public ObjDumper { public: ELFDumper(const object::ELFObjectFile *ObjF, ScopedPrinter &Writer); @@ -370,9 +386,8 @@ Expected> getVersionDependencies(const Elf_Shdr *Sec) const; - template - Expected> getRelocationTarget(const Elf_Shdr *SymTab, - const RelTy &R) const; + Expected> getRelocationTarget(const Relocation &R, + const Elf_Shdr *SymTab) const; std::function WarningHandler; void reportUniqueWarning(Error Err) const; @@ -754,10 +769,8 @@ function_ref OnSectionStart, function_ref OnSectionEntry); - virtual void printRelReloc(const Elf_Rel &R, unsigned RelIndex, - const Elf_Shdr *Sec, const Elf_Shdr *SymTab) = 0; - virtual void printRelaReloc(const Elf_Rela &R, unsigned RelIndex, - const Elf_Shdr *Sec, const Elf_Shdr *SymTab) = 0; + virtual void printReloc(const Relocation &R, unsigned RelIndex, + const Elf_Shdr &Sec, const Elf_Shdr *SymTab) = 0; virtual void printRelrReloc(const Elf_Relr &R) = 0; void printRelocationsHelper(const Elf_Shdr &Sec); @@ -870,23 +883,18 @@ } void printHashedSymbol(const Elf_Sym *FirstSym, uint32_t Sym, StringRef StrTable, uint32_t Bucket); - void printRelReloc(const Elf_Rel &R, unsigned RelIndex, const Elf_Shdr *Sec, - const Elf_Shdr *SymTab) override; - void printRelaReloc(const Elf_Rela &R, unsigned RelIndex, const Elf_Shdr *Sec, - const Elf_Shdr *SymTab) override; + void printReloc(const Relocation &R, unsigned RelIndex, + const Elf_Shdr &Sec, const Elf_Shdr *SymTab) override; void printRelrReloc(const Elf_Relr &R) override; - template - void printRelRelaReloc(const RelTy &R, unsigned RelIndex, const Elf_Shdr &Sec, - const Elf_Shdr *SymTab); - template - void printRelRelaReloc(const RelTy &R, const RelSymbol &RelSym); + void printRelRelaReloc(const Relocation &R, + const RelSymbol &RelSym); void printSymbol(const Elf_Sym *Symbol, const Elf_Sym *First, Optional StrTable, bool IsDynamic, bool NonVisibilityBitsUsed) override; std::string getSymbolSectionNdx(const Elf_Sym *Symbol, const Elf_Sym *FirstSym); - template void printDynamicRelocation(const RelTy &R); + void printDynamicRelocation(const Relocation &R); void printProgramHeaders(); void printSectionMapping(); void printGNUVersionSectionProlog(const typename ELFT::Shdr *Sec, @@ -938,15 +946,11 @@ void printMipsABIFlags(const ELFObjectFile *Obj) override; private: - void printRelReloc(const Elf_Rel &R, unsigned RelIndex, const Elf_Shdr *Sec, - const Elf_Shdr *SymTab) override; - void printRelaReloc(const Elf_Rela &R, unsigned RelIndex, const Elf_Shdr *Sec, - const Elf_Shdr *SymTab) override; + void printReloc(const Relocation &R, unsigned RelIndex, + const Elf_Shdr &Sec, const Elf_Shdr *SymTab) override; void printRelrReloc(const Elf_Relr &R) override; - template - void printRelRelaReloc(const RelTy &R, unsigned RelIndex, const Elf_Shdr &Sec, - const Elf_Shdr *SymTab); - template void printDynamicRelocation(const RelTy &Rel); + + void printDynamicRelocation(const Relocation &R); void printSymbols(); void printDynamicSymbols(); @@ -1058,12 +1062,12 @@ } template -template Expected> -ELFDumper::getRelocationTarget(const Elf_Shdr *SymTab, - const RelTy &R) const { +ELFDumper::getRelocationTarget(const Relocation &R, + const Elf_Shdr *SymTab) const { const ELFFile *Obj = ObjF->getELFFile(); - Expected SymOrErr = Obj->getRelocationSymbol(&R, SymTab); + Expected SymOrErr = + Obj->getRelocationSymbol(&R.getRel(), SymTab); if (!SymOrErr) return SymOrErr.takeError(); const Elf_Sym *Sym = *SymOrErr; @@ -3607,30 +3611,10 @@ } template -void GNUStyle::printRelReloc(const Elf_Rel &R, unsigned RelIndex, - const Elf_Shdr *Sec, - const Elf_Shdr *SymTab) { - printRelRelaReloc(R, RelIndex, *Sec, SymTab); -} - -template -void GNUStyle::printRelaReloc(const Elf_Rela &R, unsigned RelIndex, - const Elf_Shdr *Sec, - const Elf_Shdr *SymTab) { - printRelRelaReloc(R, RelIndex, *Sec, SymTab); -} - -template void GNUStyle::printRelrReloc(const Elf_Relr &R) { - OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8)) << "\n"; -} - -template -template -void GNUStyle::printRelRelaReloc(const RelTy &R, unsigned RelIndex, - const Elf_Shdr &Sec, - const Elf_Shdr *SymTab) { +void GNUStyle::printReloc(const Relocation &R, unsigned RelIndex, + const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { Expected> Target = - this->dumper()->getRelocationTarget(SymTab, R); + this->dumper()->getRelocationTarget(R, SymTab); if (!Target) this->reportUniqueWarning(createError( "unable to print relocation " + Twine(RelIndex) + " in " + @@ -3639,30 +3623,25 @@ printRelRelaReloc(R, *Target); } -template -static Optional getAddend(const typename ELFT::Rela &R) { - return (int64_t)R.r_addend; -} - -template -static Optional getAddend(const typename ELFT::Rel &) { - return None; +template void GNUStyle::printRelrReloc(const Elf_Relr &R) { + OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8)) << "\n"; } template -template -void GNUStyle::printRelRelaReloc(const RelTy &R, +void GNUStyle::printRelRelaReloc(const Relocation &R, const RelSymbol &RelSym) { // First two fields are bit width dependent. The rest of them are fixed width. unsigned Bias = ELFT::Is64Bits ? 8 : 0; Field Fields[5] = {0, 10 + Bias, 19 + 2 * Bias, 42 + 2 * Bias, 53 + 2 * Bias}; unsigned Width = ELFT::Is64Bits ? 16 : 8; - Fields[0].Str = to_string(format_hex_no_prefix(R.r_offset, Width)); - Fields[1].Str = to_string(format_hex_no_prefix(R.r_info, Width)); + const Elf_Rel &Rel = R.getRel(); + Fields[0].Str = to_string(format_hex_no_prefix(Rel.r_offset, Width)); + Fields[1].Str = to_string(format_hex_no_prefix(Rel.r_info, Width)); SmallString<32> RelocName; - this->Obj.getRelocationTypeName(R.getType(this->Obj.isMips64EL()), RelocName); + this->Obj.getRelocationTypeName(Rel.getType(this->Obj.isMips64EL()), + RelocName); Fields[2].Str = RelocName.c_str(); if (RelSym.Sym) @@ -3674,7 +3653,7 @@ printField(F); std::string Addend; - if (Optional A = getAddend(R)) { + if (Optional A = R.getAddend()) { int64_t RelAddend = *A; if (!RelSym.Name.empty()) { if (RelAddend < 0) { @@ -4357,11 +4336,11 @@ namespace { -template +template RelSymbol getSymbolForReloc(const ELFFile &Obj, StringRef FileName, const ELFDumper *Dumper, - const RelTy &Reloc) { - uint32_t SymIndex = Reloc.getSymbol(Obj.isMips64EL()); + const Relocation &Reloc) { + uint32_t SymIndex = Reloc.getRel().getSymbol(Obj.isMips64EL()); auto WarnAndReturn = [&](const typename ELFT::Sym *Sym, const Twine &Reason) -> RelSymbol { reportWarning( @@ -4395,8 +4374,7 @@ } // namespace template -template -void GNUStyle::printDynamicRelocation(const RelTy &R) { +void GNUStyle::printDynamicRelocation(const Relocation &R) { printRelRelaReloc( R, getSymbolForReloc(this->Obj, this->FileName, this->dumper(), R)); } @@ -4452,30 +4430,30 @@ printDynamicRelocHeader(this->Obj, OS, ELF::SHT_RELA, "RELA", DynRelaRegion); for (const Elf_Rela &Rela : this->dumper()->dyn_relas()) - printDynamicRelocation(Rela); + printDynamicRelocation(Relocation(Rela)); } if (DynRelRegion.Size > 0) { printDynamicRelocHeader(this->Obj, OS, ELF::SHT_REL, "REL", DynRelRegion); for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) - printDynamicRelocation(Rel); + printDynamicRelocation(Relocation(Rel)); } if (DynRelrRegion.Size > 0) { printDynamicRelocHeader(this->Obj, OS, ELF::SHT_REL, "RELR", DynRelrRegion); Elf_Relr_Range Relrs = this->dumper()->dyn_relrs(); for (const Elf_Rel &R : this->Obj.decode_relrs(Relrs)) - printDynamicRelocation(R); + printDynamicRelocation(Relocation(R)); } if (DynPLTRelRegion.Size) { if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) { printDynamicRelocHeader(this->Obj, OS, ELF::SHT_RELA, "PLT", DynPLTRelRegion); for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef()) - printDynamicRelocation(Rela); + printDynamicRelocation(Relocation(Rela)); } else { printDynamicRelocHeader(this->Obj, OS, ELF::SHT_REL, "PLT", DynPLTRelRegion); for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef()) - printDynamicRelocation(Rel); + printDynamicRelocation(Relocation(Rel)); } } } @@ -5475,7 +5453,7 @@ case ELF::SHT_REL: if (Expected RangeOrErr = Obj.rels(&Sec)) { for (const Elf_Rel &R : *RangeOrErr) - printRelReloc(R, ++RelNdx, &Sec, SymTab); + printReloc(Relocation(R), ++RelNdx, Sec, SymTab); } else { Warn(RangeOrErr.takeError()); } @@ -5483,7 +5461,7 @@ case ELF::SHT_RELA: if (Expected RangeOrErr = Obj.relas(&Sec)) { for (const Elf_Rela &R : *RangeOrErr) - printRelaReloc(R, ++RelNdx, &Sec, SymTab); + printReloc(Relocation(R), ++RelNdx, Sec, SymTab); } else { Warn(RangeOrErr.takeError()); } @@ -5502,14 +5480,14 @@ } for (const Elf_Rel &R : Obj.decode_relrs(*RangeOrErr)) - printRelReloc(R, ++RelNdx, &Sec, /*SymTab=*/nullptr); + printReloc(Relocation(R), ++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) - printRelaReloc(R, ++RelNdx, &Sec, SymTab); + printReloc(Relocation(R), ++RelNdx, Sec, SymTab); } else { Warn(RelasOrErr.takeError()); } @@ -6148,31 +6126,15 @@ } } -template -void LLVMStyle::printRelReloc(const Elf_Rel &R, unsigned RelIndex, - const Elf_Shdr *Sec, - const Elf_Shdr *SymTab) { - printRelRelaReloc(R, RelIndex, *Sec, SymTab); -} - -template -void LLVMStyle::printRelaReloc(const Elf_Rela &R, unsigned RelIndex, - const Elf_Shdr *Sec, - const Elf_Shdr *SymTab) { - printRelRelaReloc(R, RelIndex, *Sec, SymTab); -} - template void LLVMStyle::printRelrReloc(const Elf_Relr &R) { W.startLine() << W.hex(R) << "\n"; } template -template -void LLVMStyle::printRelRelaReloc(const RelTy &Rel, unsigned RelIndex, - const Elf_Shdr &Sec, - const Elf_Shdr *SymTab) { +void LLVMStyle::printReloc(const Relocation &R, unsigned RelIndex, + const Elf_Shdr &Sec, const Elf_Shdr *SymTab) { Expected> Target = - this->dumper()->getRelocationTarget(SymTab, Rel); + this->dumper()->getRelocationTarget(R, SymTab); if (!Target) { this->reportUniqueWarning(createError( "unable to print relocation " + Twine(RelIndex) + " in " + @@ -6180,12 +6142,13 @@ return; } + const Elf_Rel& Rel = R.getRel(); std::string TargetName = Target->Name; SmallString<32> RelocName; this->Obj.getRelocationTypeName(Rel.getType(this->Obj.isMips64EL()), RelocName); - uintX_t Addend = getAddend(Rel).getValueOr(0); + uintX_t Addend = R.getAddend().getValueOr(0); if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); W.printHex("Offset", Rel.r_offset); @@ -6388,39 +6351,39 @@ W.indent(); if (DynRelaRegion.Size > 0) { for (const Elf_Rela &Rela : this->dumper()->dyn_relas()) - printDynamicRelocation(Rela); + printDynamicRelocation(Relocation(Rela)); } if (DynRelRegion.Size > 0) { for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) - printDynamicRelocation(Rel); + printDynamicRelocation(Relocation(Rel)); } if (DynRelrRegion.Size > 0) { Elf_Relr_Range Relrs = this->dumper()->dyn_relrs(); - for (const Elf_Rel &R : this->Obj.decode_relrs(Relrs)) - printDynamicRelocation(R); + for (const Elf_Rel &Rel : this->Obj.decode_relrs(Relrs)) + printDynamicRelocation(Relocation(Rel)); } if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef()) - printDynamicRelocation(Rela); + printDynamicRelocation(Relocation(Rela)); else for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef()) - printDynamicRelocation(Rel); + printDynamicRelocation(Relocation(Rel)); W.unindent(); W.startLine() << "}\n"; } template -template -void LLVMStyle::printDynamicRelocation(const RelTy &Rel) { +void LLVMStyle::printDynamicRelocation(const Relocation &R) { + const Elf_Rel& Rel = R.getRel(); SmallString<32> RelocName; this->Obj.getRelocationTypeName(Rel.getType(this->Obj.isMips64EL()), RelocName); std::string SymbolName = - getSymbolForReloc(this->Obj, this->FileName, this->dumper(), Rel).Name; + getSymbolForReloc(this->Obj, this->FileName, this->dumper(), R).Name; - uintX_t Addend = getAddend(Rel).getValueOr(0); + uintX_t Addend = R.getAddend().getValueOr(0); if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); W.printHex("Offset", Rel.r_offset);