summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-readobj
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-readobj')
-rw-r--r--llvm/tools/llvm-readobj/ELFDumper.cpp46
-rw-r--r--llvm/tools/llvm-readobj/ObjDumper.h1
-rw-r--r--llvm/tools/llvm-readobj/llvm-readobj.cpp30
3 files changed, 67 insertions, 10 deletions
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index f6ec9770d80..fac6bf4296e 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -59,6 +59,7 @@ public:
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 *getElfSectionType(unsigned Arch, unsigned Type) {
}
}
+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 @@ template <class ELFT> void ELFDumper<ELFT>::printStackMap() const {
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";
+}
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index db26d698355..b83b8d49f22 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -42,6 +42,7 @@ public:
virtual void printGnuHashTable() { }
virtual void printLoadName() {}
virtual void printVersionInfo() {}
+ virtual void printGroupSections() {}
// Only implemented for ARM ELF at this time.
virtual void printAttributes() { }
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index fa8fee2b03a..790b1d59550 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -227,6 +227,12 @@ namespace opts {
cl::desc("Display ELF version sections (if present)"));
cl::alias VersionInfoShort("V", cl::desc("Alias for -version-info"),
cl::aliasopt(VersionInfo));
+
+ cl::opt<bool> SectionGroups("elf-section-groups",
+ cl::desc("Display ELF section group contents"));
+ cl::alias SectionGroupsShort("g", cl::desc("Alias for -elf-sections-groups"),
+ cl::aliasopt(SectionGroups));
+
} // namespace opts
namespace llvm {
@@ -334,16 +340,20 @@ static void dumpObject(const ObjectFile *Obj) {
Dumper->printGnuHashTable();
if (opts::VersionInfo)
Dumper->printVersionInfo();
- if (Obj->getArch() == llvm::Triple::arm && Obj->isELF())
- if (opts::ARMAttributes)
- Dumper->printAttributes();
- if (isMipsArch(Obj->getArch()) && Obj->isELF()) {
- if (opts::MipsPLTGOT)
- Dumper->printMipsPLTGOT();
- if (opts::MipsABIFlags)
- Dumper->printMipsABIFlags();
- if (opts::MipsReginfo)
- Dumper->printMipsReginfo();
+ if (Obj->isELF()) {
+ if (Obj->getArch() == llvm::Triple::arm)
+ if (opts::ARMAttributes)
+ Dumper->printAttributes();
+ if (isMipsArch(Obj->getArch())) {
+ if (opts::MipsPLTGOT)
+ Dumper->printMipsPLTGOT();
+ if (opts::MipsABIFlags)
+ Dumper->printMipsABIFlags();
+ if (opts::MipsReginfo)
+ Dumper->printMipsReginfo();
+ }
+ if (opts::SectionGroups)
+ Dumper->printGroupSections();
}
if (Obj->isCOFF()) {
if (opts::COFFImports)
OpenPOWER on IntegriCloud