mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[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
This commit is contained in:
parent
218caa8595
commit
e89fec8eee
@ -80,6 +80,10 @@ input. Otherwise, it will read from the specified ``filenames``.
|
||||
|
||||
Display the ELF program headers (only for ELF object files).
|
||||
|
||||
.. option:: -elf-section-groups, -g
|
||||
|
||||
Display section groups (only for ELF object files).
|
||||
|
||||
EXIT STATUS
|
||||
-----------
|
||||
|
||||
|
BIN
test/tools/llvm-readobj/Inputs/elf-groups.x86_64
Normal file
BIN
test/tools/llvm-readobj/Inputs/elf-groups.x86_64
Normal file
Binary file not shown.
39
test/tools/llvm-readobj/elf-groups.test
Normal file
39
test/tools/llvm-readobj/elf-groups.test
Normal file
@ -0,0 +1,39 @@
|
||||
# Source file compiled:
|
||||
##include <iostream>
|
||||
# #include <typeinfo>
|
||||
#template <class A>
|
||||
#void foo(A variable) {
|
||||
# std::cout << "foo is " << typeid(A).name() << "\n";
|
||||
#}
|
||||
#int main () {
|
||||
# char x = 'x';
|
||||
# int y = 1;
|
||||
# foo(x);
|
||||
# foo(y);
|
||||
# return 0;
|
||||
#}
|
||||
|
||||
RUN: llvm-readobj -g %p/Inputs/elf-groups.x86_64 \
|
||||
RUN: | FileCheck %s
|
||||
CHECK: Groups {
|
||||
CHECK-NEXT: Group {
|
||||
CHECK-NEXT: Name: .group (92)
|
||||
CHECK-NEXT: Index: 1
|
||||
CHECK-NEXT: Type: COMDAT (0x1)
|
||||
CHECK-NEXT: Signature: _Z3fooIcEvT_
|
||||
CHECK-NEXT: Section(s) in group [
|
||||
CHECK-NEXT: .text._Z3fooIcEvT_ (10)
|
||||
CHECK-NEXT: .rela.text._Z3fooIcEvT_ (11)
|
||||
CHECK-NEXT: ]
|
||||
CHECK-NEXT: }
|
||||
CHECK-NEXT: Group {
|
||||
CHECK-NEXT: Name: .group (92)
|
||||
CHECK-NEXT: Index: 2
|
||||
CHECK-NEXT: Type: COMDAT (0x1)
|
||||
CHECK-NEXT: Signature: _Z3fooIiEvT_
|
||||
CHECK-NEXT: Section(s) in group [
|
||||
CHECK-NEXT: .text._Z3fooIiEvT_ (12)
|
||||
CHECK-NEXT: .rela.text._Z3fooIiEvT_ (13)
|
||||
CHECK-NEXT: ]
|
||||
CHECK-NEXT: }
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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() { }
|
||||
|
@ -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,10 +340,11 @@ static void dumpObject(const ObjectFile *Obj) {
|
||||
Dumper->printGnuHashTable();
|
||||
if (opts::VersionInfo)
|
||||
Dumper->printVersionInfo();
|
||||
if (Obj->getArch() == llvm::Triple::arm && Obj->isELF())
|
||||
if (Obj->isELF()) {
|
||||
if (Obj->getArch() == llvm::Triple::arm)
|
||||
if (opts::ARMAttributes)
|
||||
Dumper->printAttributes();
|
||||
if (isMipsArch(Obj->getArch()) && Obj->isELF()) {
|
||||
if (isMipsArch(Obj->getArch())) {
|
||||
if (opts::MipsPLTGOT)
|
||||
Dumper->printMipsPLTGOT();
|
||||
if (opts::MipsABIFlags)
|
||||
@ -345,6 +352,9 @@ static void dumpObject(const ObjectFile *Obj) {
|
||||
if (opts::MipsReginfo)
|
||||
Dumper->printMipsReginfo();
|
||||
}
|
||||
if (opts::SectionGroups)
|
||||
Dumper->printGroupSections();
|
||||
}
|
||||
if (Obj->isCOFF()) {
|
||||
if (opts::COFFImports)
|
||||
Dumper->printCOFFImports();
|
||||
|
Loading…
Reference in New Issue
Block a user