Index: llvm/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/tools/llvm-readobj/ELFDumper.cpp +++ llvm/tools/llvm-readobj/ELFDumper.cpp @@ -733,9 +733,7 @@ template class DumpStyle { public: - using Elf_Shdr = typename ELFT::Shdr; - using Elf_Sym = typename ELFT::Sym; - using Elf_Addr = typename ELFT::Addr; + TYPEDEF_ELF_TYPES(ELFT) DumpStyle(ELFDumper *Dumper) : Dumper(Dumper) { FileName = this->Dumper->getElfObject()->getFileName(); @@ -798,6 +796,15 @@ function_ref OnSectionStart, function_ref OnSectionEntry); + virtual void printRelReloc(const ELFO *Obj, unsigned SecIndex, + const Elf_Shdr *SymTab, const Elf_Rel &R, + unsigned RelIndex) = 0; + virtual void printRelaReloc(const ELFO *Obj, unsigned SecIndex, + const Elf_Shdr *SymTab, const Elf_Rela &R, + unsigned RelIndex) = 0; + virtual void printRelrReloc(const Elf_Relr &R) = 0; + void printRelocationsHelper(const ELFFile *Obj, const Elf_Shdr &Sec); + void reportUniqueWarning(Error Err) const; StringRef FileName; @@ -909,13 +916,21 @@ void printHashedSymbol(const ELFO *Obj, const Elf_Sym *FirstSym, uint32_t Sym, StringRef StrTable, uint32_t Bucket); void printRelocHeader(unsigned SType); + + void printRelReloc(const ELFO *Obj, unsigned SecIndex, const Elf_Shdr *SymTab, + const Elf_Rel &R, unsigned RelIndex) override; + void printRelaReloc(const ELFO *Obj, unsigned SecIndex, + const Elf_Shdr *SymTab, const Elf_Rela &R, + unsigned RelIndex) override; + void printRelrReloc(const Elf_Relr &R) override; + template - void printRelocation(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const RelTy &R, - unsigned RelIndex); + void printRelRelaReloc(const ELFO *Obj, unsigned SecIndex, + const Elf_Shdr *SymTab, const RelTy &R, + unsigned RelIndex); template - void printRelocation(const ELFO *Obj, const Elf_Sym *Sym, - StringRef SymbolName, const RelTy &R); + void printRelRelaReloc(const ELFO *Obj, const Elf_Sym *Sym, + StringRef SymbolName, const RelTy &R); void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First, Optional StrTable, bool IsDynamic, bool NonVisibilityBitsUsed) override; @@ -953,7 +968,6 @@ void printFileHeaders(const ELFO *Obj) override; void printGroupSections(const ELFFile *Obj) override; void printRelocations(const ELFO *Obj) override; - void printRelocations(const Elf_Shdr *Sec, const ELFO *Obj); void printSectionHeaders(const ELFO *Obj) override; void printSymbols(const ELFO *Obj, bool PrintSymbols, bool PrintDynamicSymbols) override; @@ -980,9 +994,15 @@ void printMipsABIFlags(const ELFObjectFile *Obj) override; private: + void printRelReloc(const ELFO *Obj, unsigned SecIndex, const Elf_Shdr *SymTab, + const Elf_Rel &R, unsigned RelIndex) override; + void printRelaReloc(const ELFO *Obj, unsigned SecIndex, + const Elf_Shdr *SymTab, const Elf_Rela &R, + unsigned RelIndex) override; + void printRelrReloc(const Elf_Relr &R) override; template - void printRelocation(const ELFO *Obj, unsigned SecIndex, const RelTy &Rel, - unsigned RelIndex, const Elf_Shdr *SymTab); + void printRelRelaReloc(const ELFO *Obj, unsigned SecIndex, const RelTy &Rel, + unsigned RelIndex, const Elf_Shdr *SymTab); template void printDynamicRelocation(const ELFO *Obj, const RelTy& Rel); @@ -3612,11 +3632,29 @@ OS << "There are no section groups in this file.\n"; } +template +void GNUStyle::printRelReloc(const ELFO *Obj, unsigned SecIndex, + const Elf_Shdr *SymTab, const Elf_Rel &R, + unsigned RelIndex) { + printRelRelaReloc(Obj, SecIndex, SymTab, R, RelIndex); +} + +template +void GNUStyle::printRelaReloc(const ELFO *Obj, unsigned SecIndex, + const Elf_Shdr *SymTab, const Elf_Rela &R, + unsigned RelIndex) { + printRelRelaReloc(Obj, SecIndex, SymTab, R, RelIndex); +} + +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::printRelocation(const ELFO *Obj, unsigned SecIndex, - const Elf_Shdr *SymTab, const RelTy &R, - unsigned RelIndex) { +void GNUStyle::printRelRelaReloc(const ELFO *Obj, unsigned SecIndex, + const Elf_Shdr *SymTab, const RelTy &R, + unsigned RelIndex) { Expected> Target = this->dumper()->getRelocationTarget(SymTab, R); if (!Target) @@ -3624,7 +3662,7 @@ "unable to print relocation " + Twine(RelIndex) + " in section " + Twine(SecIndex) + ": " + toString(Target.takeError()))); else - printRelocation(Obj, /*Sym=*/Target->first, /*Name=*/Target->second, R); + printRelRelaReloc(Obj, /*Sym=*/Target->first, /*Name=*/Target->second, R); } template @@ -3639,8 +3677,8 @@ template template -void GNUStyle::printRelocation(const ELFO *Obj, const Elf_Sym *Sym, - StringRef SymbolName, const RelTy &R) { +void GNUStyle::printRelRelaReloc(const ELFO *Obj, const Elf_Sym *Sym, + StringRef SymbolName, const RelTy &R) { // 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}; @@ -3697,73 +3735,42 @@ OS << "\n"; } +template +static bool isRelocationSec(const typename ELFT::Shdr &Sec) { + return Sec.sh_type == ELF::SHT_REL || Sec.sh_type == ELF::SHT_RELA || + Sec.sh_type == ELF::SHT_RELR || Sec.sh_type == ELF::SHT_ANDROID_REL || + Sec.sh_type == ELF::SHT_ANDROID_RELA || + Sec.sh_type == ELF::SHT_ANDROID_RELR; +} + template void GNUStyle::printRelocations(const ELFO *Obj) { bool HasRelocSections = false; for (const Elf_Shdr &Sec : cantFail(Obj->sections())) { - if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA && - Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_REL && - Sec.sh_type != ELF::SHT_ANDROID_RELA && - Sec.sh_type != ELF::SHT_ANDROID_RELR) + if (!isRelocationSec(Sec)) continue; HasRelocSections = true; + StringRef Name = unwrapOrError(this->FileName, Obj->getSectionName(&Sec)); - unsigned Entries = Sec.getEntityCount(); - std::vector AndroidRelas; + unsigned Entries; + // Android's packed relocation section needs to be unpacked first + // to get the actual number of entries. if (Sec.sh_type == ELF::SHT_ANDROID_REL || Sec.sh_type == ELF::SHT_ANDROID_RELA) { - // Android's packed relocation section needs to be unpacked first - // to get the actual number of entries. - AndroidRelas = unwrapOrError(this->FileName, Obj->android_relas(&Sec)); - Entries = AndroidRelas.size(); - } - std::vector RelrRels; - if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR || - Sec.sh_type == ELF::SHT_ANDROID_RELR)) { - // .relr.dyn relative relocation section needs to be unpacked first - // to get the actual number of entries. + Entries = unwrapOrError(this->FileName, Obj->android_relas(&Sec)).size(); + } else if (!opts::RawRelr && (Sec.sh_type == ELF::SHT_RELR || + Sec.sh_type == ELF::SHT_ANDROID_RELR)) { Elf_Relr_Range Relrs = unwrapOrError(this->FileName, Obj->relrs(&Sec)); - RelrRels = unwrapOrError(this->FileName, Obj->decode_relrs(Relrs)); - Entries = RelrRels.size(); + Entries = unwrapOrError(this->FileName, Obj->decode_relrs(Relrs)).size(); + } else { + Entries = Sec.getEntityCount(); } + uintX_t Offset = Sec.sh_offset; OS << "\nRelocation section '" << Name << "' at offset 0x" << to_hexString(Offset, false) << " contains " << Entries << " entries:\n"; printRelocHeader(Sec.sh_type); - const Elf_Shdr *SymTab = - unwrapOrError(this->FileName, Obj->getSection(Sec.sh_link)); - unsigned SecNdx = &Sec - &cantFail(Obj->sections()).front(); - unsigned RelNdx = 0; - - switch (Sec.sh_type) { - case ELF::SHT_REL: - for (const Elf_Rel &R : unwrapOrError(this->FileName, Obj->rels(&Sec))) - printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx); - break; - case ELF::SHT_RELA: - for (const Elf_Rela &R : unwrapOrError(this->FileName, Obj->relas(&Sec))) - printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx); - break; - case ELF::SHT_RELR: - case ELF::SHT_ANDROID_RELR: - if (opts::RawRelr) - for (const Elf_Relr &R : - unwrapOrError(this->FileName, Obj->relrs(&Sec))) - OS << to_string(format_hex_no_prefix(R, ELFT::Is64Bits ? 16 : 8)) - << "\n"; - else - for (const Elf_Rel &R : RelrRels) - printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx); - break; - case ELF::SHT_ANDROID_REL: - for (const Elf_Rela &R : AndroidRelas) - printRelocation(Obj, SecNdx, SymTab, (const Elf_Rel &)R, ++RelNdx); - break; - case ELF::SHT_ANDROID_RELA: - for (const Elf_Rela &R : AndroidRelas) - printRelocation(Obj, SecNdx, SymTab, R, ++RelNdx); - break; - } + this->printRelocationsHelper(Obj, Sec); } if (!HasRelocSections) OS << "\nThere are no relocations in this file.\n"; @@ -4508,7 +4515,7 @@ template void GNUStyle::printDynamicRelocation(const ELFO *Obj, const RelTy &R) { RelSymbol S = getSymbolForReloc(Obj, this->FileName, this->dumper(), R); - printRelocation(Obj, S.Sym, S.Name, R); + printRelRelaReloc(Obj, S.Sym, S.Name, R); } template @@ -5596,6 +5603,46 @@ } } +template +void DumpStyle::printRelocationsHelper(const ELFFile *Obj, + const Elf_Shdr &Sec) { + const Elf_Shdr *SymTab = + unwrapOrError(this->FileName, Obj->getSection(Sec.sh_link)); + unsigned SecNdx = &Sec - &cantFail(Obj->sections()).front(); + unsigned RelNdx = 0; + + switch (Sec.sh_type) { + case ELF::SHT_REL: + for (const Elf_Rel &R : unwrapOrError(this->FileName, Obj->rels(&Sec))) + printRelReloc(Obj, SecNdx, SymTab, R, ++RelNdx); + break; + case ELF::SHT_RELA: + for (const Elf_Rela &R : unwrapOrError(this->FileName, Obj->relas(&Sec))) + printRelaReloc(Obj, SecNdx, SymTab, R, ++RelNdx); + break; + case ELF::SHT_RELR: + case ELF::SHT_ANDROID_RELR: { + Elf_Relr_Range Relrs = unwrapOrError(this->FileName, Obj->relrs(&Sec)); + if (opts::RawRelr) { + for (const Elf_Relr &R : Relrs) + printRelrReloc(R); + break; + } + std::vector RelrRels = + unwrapOrError(this->FileName, Obj->decode_relrs(Relrs)); + for (const Elf_Rel &R : RelrRels) + printRelReloc(Obj, SecNdx, SymTab, R, ++RelNdx); + break; + } + case ELF::SHT_ANDROID_REL: + case ELF::SHT_ANDROID_RELA: + for (const Elf_Rela &R : + unwrapOrError(this->FileName, Obj->android_relas(&Sec))) + printRelaReloc(Obj, SecNdx, SymTab, R, ++RelNdx); + break; + } +} + template void GNUStyle::printDependentLibs(const ELFFile *Obj) { bool SectionStarted = false; @@ -6207,72 +6254,43 @@ template void LLVMStyle::printRelocations(const ELFO *Obj) { ListScope D(W, "Relocations"); - int SectionNumber = -1; for (const Elf_Shdr &Sec : cantFail(Obj->sections())) { - ++SectionNumber; - - if (Sec.sh_type != ELF::SHT_REL && Sec.sh_type != ELF::SHT_RELA && - Sec.sh_type != ELF::SHT_RELR && Sec.sh_type != ELF::SHT_ANDROID_REL && - Sec.sh_type != ELF::SHT_ANDROID_RELA && - Sec.sh_type != ELF::SHT_ANDROID_RELR) + if (!isRelocationSec(Sec)) continue; StringRef Name = unwrapOrError(this->FileName, Obj->getSectionName(&Sec)); - - W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; + unsigned SecNdx = &Sec - &cantFail(Obj->sections()).front(); + W.startLine() << "Section (" << SecNdx << ") " << Name << " {\n"; W.indent(); - - printRelocations(&Sec, Obj); - + this->printRelocationsHelper(Obj, Sec); W.unindent(); W.startLine() << "}\n"; } } template -void LLVMStyle::printRelocations(const Elf_Shdr *Sec, const ELFO *Obj) { - const Elf_Shdr *SymTab = - unwrapOrError(this->FileName, Obj->getSection(Sec->sh_link)); - unsigned SecNdx = Sec - &cantFail(Obj->sections()).front(); - unsigned RelNdx = 0; +void LLVMStyle::printRelReloc(const ELFO *Obj, unsigned SecIndex, + const Elf_Shdr *SymTab, const Elf_Rel &R, + unsigned RelIndex) { + printRelRelaReloc(Obj, SecIndex, R, RelIndex, SymTab); +} - switch (Sec->sh_type) { - case ELF::SHT_REL: - for (const Elf_Rel &R : unwrapOrError(this->FileName, Obj->rels(Sec))) - printRelocation(Obj, SecNdx, R, ++RelNdx, SymTab); - break; - case ELF::SHT_RELA: - for (const Elf_Rela &R : unwrapOrError(this->FileName, Obj->relas(Sec))) - printRelocation(Obj, SecNdx, R, ++RelNdx, SymTab); - break; - case ELF::SHT_RELR: - case ELF::SHT_ANDROID_RELR: { - Elf_Relr_Range Relrs = unwrapOrError(this->FileName, Obj->relrs(Sec)); - if (opts::RawRelr) { - for (const Elf_Relr &R : Relrs) - W.startLine() << W.hex(R) << "\n"; - } else { - std::vector RelrRels = - unwrapOrError(this->FileName, Obj->decode_relrs(Relrs)); - for (const Elf_Rel &R : RelrRels) - printRelocation(Obj, SecNdx, R, ++RelNdx, SymTab); - } - break; - } - case ELF::SHT_ANDROID_REL: - case ELF::SHT_ANDROID_RELA: - for (const Elf_Rela &R : - unwrapOrError(this->FileName, Obj->android_relas(Sec))) - printRelocation(Obj, SecNdx, R, ++RelNdx, SymTab); - break; - } +template +void LLVMStyle::printRelaReloc(const ELFO *Obj, unsigned SecIndex, + const Elf_Shdr *SymTab, const Elf_Rela &R, + unsigned RelIndex) { + printRelRelaReloc(Obj, SecIndex, R, RelIndex, SymTab); +} + +template void LLVMStyle::printRelrReloc(const Elf_Relr &R) { + W.startLine() << W.hex(R) << "\n"; } template template -void LLVMStyle::printRelocation(const ELFO *Obj, unsigned SecIndex, - const RelTy &Rel, unsigned RelIndex, - const Elf_Shdr *SymTab) { +void LLVMStyle::printRelRelaReloc(const ELFO *Obj, unsigned SecIndex, + const RelTy &Rel, unsigned RelIndex, + const Elf_Shdr *SymTab) { Expected> Target = this->dumper()->getRelocationTarget(SymTab, Rel); if (!Target) { @@ -6335,7 +6353,7 @@ if (opts::SectionRelocations) { ListScope D(W, "Relocations"); - printRelocations(&Sec, Obj); + this->printRelocationsHelper(Obj, Sec); } if (opts::SectionSymbols) {