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); + using PrintRelFn = function_ref; + using PrintRelaFn = function_ref; + using PrintRelrFn = function_ref; + void printRelocationsHelper(const ELFFile *Obj, const Elf_Shdr &Sec, + PrintRelFn PrintRel, PrintRelaFn PrintRela, + PrintRelrFn PrintRelr); + void reportUniqueWarning(Error Err) const; StringRef FileName; @@ -953,7 +960,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; @@ -3697,73 +3703,57 @@ OS << "\n"; } +template +static bool isRelocationSec(const typename ELFT::Shdr &Sec) { + 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) + return false; + return true; +} + 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))) + this->printRelocationsHelper( + Obj, Sec, + [&](const ELFO *Obj, unsigned SecIndex, unsigned RelIndex, + const Elf_Shdr *SymTab, const Elf_Rel &R) { + printRelocation(Obj, SecIndex, SymTab, R, RelIndex); + }, + [&](const ELFO *Obj, unsigned SecIndex, unsigned RelIndex, + const Elf_Shdr *SymTab, const Elf_Rela &R) { + printRelocation(Obj, SecIndex, SymTab, R, RelIndex); + }, + [&](const Elf_Relr &R) { 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; - } + }); } if (!HasRelocSections) OS << "\nThere are no relocations in this file.\n"; @@ -5596,6 +5586,49 @@ } } +template +void DumpStyle::printRelocationsHelper(const ELFFile *Obj, + const Elf_Shdr &Sec, + PrintRelFn PrintRel, + PrintRelaFn PrintRela, + PrintRelrFn PrintRelr) { + 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))) + PrintRel(Obj, SecNdx, ++RelNdx, SymTab, R); + break; + case ELF::SHT_RELA: + for (const Elf_Rela &R : unwrapOrError(this->FileName, Obj->relas(&Sec))) + PrintRela(Obj, SecNdx, ++RelNdx, SymTab, R); + 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) + PrintRelr(R); + break; + } + std::vector RelrRels = + unwrapOrError(this->FileName, Obj->decode_relrs(Relrs)); + for (const Elf_Rel &R : RelrRels) + PrintRel(Obj, SecNdx, ++RelNdx, SymTab, R); + break; + } + case ELF::SHT_ANDROID_REL: + case ELF::SHT_ANDROID_RELA: + for (const Elf_Rela &R : + unwrapOrError(this->FileName, Obj->android_relas(&Sec))) + PrintRela(Obj, SecNdx, ++RelNdx, SymTab, R); + break; + } +} + template void GNUStyle::printDependentLibs(const ELFFile *Obj) { bool SectionStarted = false; @@ -6192,67 +6225,30 @@ 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, + [&](const ELFO *Obj, unsigned SecIndex, unsigned RelIndex, + const Elf_Shdr *SymTab, const Elf_Rel &R) { + printRelocation(Obj, SecIndex, R, RelIndex, SymTab); + }, + [&](const ELFO *Obj, unsigned SecIndex, unsigned RelIndex, + const Elf_Shdr *SymTab, const Elf_Rela &R) { + printRelocation(Obj, SecIndex, R, RelIndex, SymTab); + }, + [&](const Elf_Relr &R) { W.startLine() << W.hex(R) << "\n"; }); 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; - - 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 template void LLVMStyle::printRelocation(const ELFO *Obj, unsigned SecIndex, @@ -6320,7 +6316,17 @@ if (opts::SectionRelocations) { ListScope D(W, "Relocations"); - printRelocations(&Sec, Obj); + this->printRelocationsHelper( + Obj, Sec, + [&](const ELFO *Obj, unsigned SecIndex, unsigned RelIndex, + const Elf_Shdr *SymTab, const Elf_Rel &R) { + printRelocation(Obj, SecIndex, R, RelIndex, SymTab); + }, + [&](const ELFO *Obj, unsigned SecIndex, unsigned RelIndex, + const Elf_Shdr *SymTab, const Elf_Rela &R) { + printRelocation(Obj, SecIndex, R, RelIndex, SymTab); + }, + [&](const Elf_Relr &R) { W.startLine() << W.hex(R) << "\n"; }); } if (opts::SectionSymbols) {