Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -205,6 +205,24 @@ } // namespace +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::Rela &R, bool IsMips64EL) + : Relocation((const typename ELFT::Rel &)R, IsMips64EL) { + Addend = R.r_addend; + } + + uint32_t Type; + uint32_t Symbol; + typename ELFT::uint Offset; + typename ELFT::uint Info; + Optional Addend; +}; + template class ELFDumper : public ObjDumper { public: ELFDumper(const object::ELFObjectFile *ObjF, ScopedPrinter &Writer); @@ -370,9 +388,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 +771,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 +885,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 +948,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 +1064,15 @@ } template -template Expected> -ELFDumper::getRelocationTarget(const Elf_Shdr *SymTab, - const RelTy &R) const { - const ELFFile *Obj = ObjF->getELFFile(); - Expected SymOrErr = Obj->getRelocationSymbol(&R, SymTab); +ELFDumper::getRelocationTarget(const Relocation &R, + const Elf_Shdr *SymTab) const { + if (R.Symbol == 0) + return RelSymbol(nullptr, ""); + + const ELFFile &Obj = *ObjF->getELFFile(); + Expected SymOrErr = + Obj.template getEntry(SymTab, R.Symbol); if (!SymOrErr) return SymOrErr.takeError(); const Elf_Sym *Sym = *SymOrErr; @@ -1074,20 +1083,20 @@ // This code block returns the section name. if (Sym->getType() == ELF::STT_SECTION) { Expected SecOrErr = - Obj->getSection(Sym, SymTab, ShndxTable); + Obj.getSection(Sym, SymTab, ShndxTable); if (!SecOrErr) return SecOrErr.takeError(); // A section symbol describes the section at index 0. if (*SecOrErr == nullptr) return RelSymbol(Sym, ""); - Expected NameOrErr = Obj->getSectionName(*SecOrErr); + Expected NameOrErr = Obj.getSectionName(*SecOrErr); if (!NameOrErr) return NameOrErr.takeError(); return RelSymbol(Sym, NameOrErr->str()); } - Expected StrTableOrErr = Obj->getStringTableForSymtab(*SymTab); + Expected StrTableOrErr = Obj.getStringTableForSymtab(*SymTab); if (!StrTableOrErr) return StrTableOrErr.takeError(); @@ -3607,30 +3616,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 +3628,23 @@ 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)); + Fields[0].Str = to_string(format_hex_no_prefix(R.Offset, Width)); + Fields[1].Str = to_string(format_hex_no_prefix(R.Info, Width)); SmallString<32> RelocName; - this->Obj.getRelocationTypeName(R.getType(this->Obj.isMips64EL()), RelocName); + this->Obj.getRelocationTypeName(R.Type, RelocName); Fields[2].Str = RelocName.c_str(); if (RelSym.Sym) @@ -3674,7 +3656,7 @@ printField(F); std::string Addend; - if (Optional A = getAddend(R)) { + if (Optional A = R.Addend) { int64_t RelAddend = *A; if (!RelSym.Name.empty()) { if (RelAddend < 0) { @@ -4357,16 +4339,15 @@ 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) { auto WarnAndReturn = [&](const typename ELFT::Sym *Sym, const Twine &Reason) -> RelSymbol { reportWarning( createError("unable to get name of the dynamic symbol with index " + - Twine(SymIndex) + ": " + Reason), + Twine(Reloc.Symbol) + ": " + Reason), FileName); return {Sym, ""}; }; @@ -4379,13 +4360,13 @@ // We might have an object without a section header. In this case the size of // Symbols is zero, because there is no way to know the size of the dynamic // table. We should allow this case and not print a warning. - if (!Symbols.empty() && SymIndex >= Symbols.size()) + if (!Symbols.empty() && Reloc.Symbol >= Symbols.size()) return WarnAndReturn( nullptr, "index is greater than or equal to the number of dynamic symbols (" + Twine(Symbols.size()) + ")"); - const typename ELFT::Sym *Sym = FirstSym + SymIndex; + const typename ELFT::Sym *Sym = FirstSym + Reloc.Symbol; Expected ErrOrName = Sym->getName(Dumper->getDynamicStringTable()); if (!ErrOrName) return WarnAndReturn(Sym, toString(ErrOrName.takeError())); @@ -4395,8 +4376,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)); } @@ -4448,34 +4428,35 @@ const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion(); const DynRegionInfo &DynRelrRegion = this->dumper()->getDynRelrRegion(); const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion(); + const bool IsMips64EL = this->Obj.isMips64EL(); if (DynRelaRegion.Size > 0) { printDynamicRelocHeader(this->Obj, OS, ELF::SHT_RELA, "RELA", DynRelaRegion); for (const Elf_Rela &Rela : this->dumper()->dyn_relas()) - printDynamicRelocation(Rela); + printDynamicRelocation(Relocation(Rela, IsMips64EL)); } 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, IsMips64EL)); } 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, IsMips64EL)); } 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, IsMips64EL)); } else { printDynamicRelocHeader(this->Obj, OS, ELF::SHT_REL, "PLT", DynPLTRelRegion); for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef()) - printDynamicRelocation(Rel); + printDynamicRelocation(Relocation(Rel, IsMips64EL)); } } } @@ -5471,11 +5452,12 @@ } unsigned RelNdx = 0; + const bool IsMips64EL = this->Obj.isMips64EL(); switch (Sec.sh_type) { case ELF::SHT_REL: if (Expected RangeOrErr = Obj.rels(&Sec)) { for (const Elf_Rel &R : *RangeOrErr) - printRelReloc(R, ++RelNdx, &Sec, SymTab); + printReloc(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); } else { Warn(RangeOrErr.takeError()); } @@ -5483,7 +5465,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, IsMips64EL), ++RelNdx, Sec, SymTab); } else { Warn(RangeOrErr.takeError()); } @@ -5502,14 +5484,15 @@ } for (const Elf_Rel &R : Obj.decode_relrs(*RangeOrErr)) - printRelReloc(R, ++RelNdx, &Sec, /*SymTab=*/nullptr); + printReloc(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) - printRelaReloc(R, ++RelNdx, &Sec, SymTab); + printReloc(Relocation(R, IsMips64EL), ++RelNdx, Sec, SymTab); } else { Warn(RelasOrErr.takeError()); } @@ -6148,31 +6131,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 " + @@ -6182,20 +6149,18 @@ std::string TargetName = Target->Name; SmallString<32> RelocName; - this->Obj.getRelocationTypeName(Rel.getType(this->Obj.isMips64EL()), - RelocName); + this->Obj.getRelocationTypeName(R.Type, RelocName); - uintX_t Addend = getAddend(Rel).getValueOr(0); + uintX_t Addend = R.Addend.getValueOr(0); if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); - W.printHex("Offset", Rel.r_offset); - W.printNumber("Type", RelocName, (int)Rel.getType(this->Obj.isMips64EL())); - W.printNumber("Symbol", !TargetName.empty() ? TargetName : "-", - Rel.getSymbol(this->Obj.isMips64EL())); + W.printHex("Offset", R.Offset); + W.printNumber("Type", RelocName, R.Type); + W.printNumber("Symbol", !TargetName.empty() ? TargetName : "-", R.Symbol); W.printHex("Addend", Addend); } else { raw_ostream &OS = W.startLine(); - OS << W.hex(Rel.r_offset) << " " << RelocName << " " + OS << W.hex(R.Offset) << " " << RelocName << " " << (!TargetName.empty() ? TargetName : "-") << " " << W.hex(Addend) << "\n"; } @@ -6383,53 +6348,52 @@ const DynRegionInfo &DynRelaRegion = this->dumper()->getDynRelaRegion(); const DynRegionInfo &DynRelrRegion = this->dumper()->getDynRelrRegion(); const DynRegionInfo &DynPLTRelRegion = this->dumper()->getDynPLTRelRegion(); + const bool IsMips64EL = this->Obj.isMips64EL(); W.startLine() << "Dynamic Relocations {\n"; W.indent(); if (DynRelaRegion.Size > 0) { for (const Elf_Rela &Rela : this->dumper()->dyn_relas()) - printDynamicRelocation(Rela); + printDynamicRelocation(Relocation(Rela, IsMips64EL)); } if (DynRelRegion.Size > 0) { for (const Elf_Rel &Rel : this->dumper()->dyn_rels()) - printDynamicRelocation(Rel); + printDynamicRelocation(Relocation(Rel, IsMips64EL)); } 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, IsMips64EL)); } if (DynPLTRelRegion.EntSize == sizeof(Elf_Rela)) for (const Elf_Rela &Rela : DynPLTRelRegion.getAsArrayRef()) - printDynamicRelocation(Rela); + printDynamicRelocation(Relocation(Rela, IsMips64EL)); else for (const Elf_Rel &Rel : DynPLTRelRegion.getAsArrayRef()) - printDynamicRelocation(Rel); + printDynamicRelocation(Relocation(Rel, IsMips64EL)); W.unindent(); W.startLine() << "}\n"; } template -template -void LLVMStyle::printDynamicRelocation(const RelTy &Rel) { +void LLVMStyle::printDynamicRelocation(const Relocation &R) { SmallString<32> RelocName; - this->Obj.getRelocationTypeName(Rel.getType(this->Obj.isMips64EL()), - RelocName); + this->Obj.getRelocationTypeName(R.Type, 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.Addend.getValueOr(0); if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); - W.printHex("Offset", Rel.r_offset); - W.printNumber("Type", RelocName, (int)Rel.getType(this->Obj.isMips64EL())); + W.printHex("Offset", R.Offset); + W.printNumber("Type", RelocName, R.Type); W.printString("Symbol", !SymbolName.empty() ? SymbolName : "-"); W.printHex("Addend", Addend); } else { raw_ostream &OS = W.startLine(); - OS << W.hex(Rel.r_offset) << " " << RelocName << " " + OS << W.hex(R.Offset) << " " << RelocName << " " << (!SymbolName.empty() ? SymbolName : "-") << " " << W.hex(Addend) << "\n"; }