[llvm-readobj] Add -elf-section-groups option
Adds a way to inspect SHT_GROUP sections in ELF objects.
Displays signature, member sections of these sections.
Differential revision: http://reviews.llvm.org/D16555
llvm-svn: 258845
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index f6ec977..fac6bf4 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -59,6 +59,7 @@
void printGnuHashTable() override;
void printLoadName() override;
void printVersionInfo() override;
+ void printGroupSections() override;
void printAttributes() override;
void printMipsPLTGOT() override;
@@ -792,6 +793,13 @@
}
}
+static const char *getGroupType(uint32_t Flag) {
+ if (Flag & ELF::GRP_COMDAT)
+ return "COMDAT";
+ else
+ return "(unknown)";
+}
+
static const EnumEntry<unsigned> ElfSectionFlags[] = {
LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE ),
LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC ),
@@ -2250,3 +2258,41 @@
llvm::outs(),
StackMapV1Parser<ELFT::TargetEndianness>(*StackMapContentsArray));
}
+template <class ELFT> void ELFDumper<ELFT>::printGroupSections() {
+ DictScope Lists(W, "Groups");
+ uint32_t SectionIndex = 0;
+ bool HasGroups = false;
+ for (const Elf_Shdr &Sec : Obj->sections()) {
+ if (Sec.sh_type == ELF::SHT_GROUP) {
+ HasGroups = true;
+ ErrorOr<const Elf_Shdr *> Symtab =
+ errorOrDefault(Obj->getSection(Sec.sh_link));
+ ErrorOr<StringRef> StrTableOrErr = Obj->getStringTableForSymtab(**Symtab);
+ error(StrTableOrErr.getError());
+ StringRef StrTable = *StrTableOrErr;
+ const Elf_Sym *Sym =
+ Obj->template getEntry<Elf_Sym>(*Symtab, Sec.sh_info);
+ auto Data = errorOrDefault(
+ Obj->template getSectionContentsAsArray<Elf32_Word>(&Sec));
+ DictScope D(W, "Group");
+ StringRef Name = errorOrDefault(Obj->getSectionName(&Sec));
+ W.printNumber("Name", Name, Sec.sh_name);
+ W.printNumber("Index", SectionIndex);
+ W.printHex("Type", getGroupType(Data[0]), Data[0]);
+ W.startLine() << "Signature: " << StrTable.data() + Sym->st_name << "\n";
+ {
+ ListScope L(W, "Section(s) in group");
+ int Member = 1;
+ while (Member < Data.size()) {
+ auto Sec = errorOrDefault(Obj->getSection(Data[Member]));
+ const StringRef Name = errorOrDefault(Obj->getSectionName(Sec));
+ W.startLine() << Name << " (" << std::to_string(Data[Member++])
+ << ")\n";
+ }
+ }
+ }
+ ++SectionIndex;
+ }
+ if (!HasGroups)
+ W.startLine() << "There are no group sections in the file.\n";
+}