llvm.org GIT mirror llvm / 8822b47
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@258845 91177308-0d34-0410-b5e6-96231b3b80d8 Hemant Kulkarni 3 years ago
6 changed file(s) with 110 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
7979
8080 Display the ELF program headers (only for ELF object files).
8181
82 .. option:: -elf-section-groups, -g
83
84 Display section groups (only for ELF object files).
85
8286 EXIT STATUS
8387 -----------
8488
0 # Source file compiled:
1 ##include
2 # #include
3 #template
4 #void foo(A variable) {
5 # std::cout << "foo is " << typeid(A).name() << "\n";
6 #}
7 #int main () {
8 # char x = 'x';
9 # int y = 1;
10 # foo(x);
11 # foo(y);
12 # return 0;
13 #}
14
15 RUN: llvm-readobj -g %p/Inputs/elf-groups.x86_64 \
16 RUN: | FileCheck %s
17 CHECK: Groups {
18 CHECK-NEXT: Group {
19 CHECK-NEXT: Name: .group (92)
20 CHECK-NEXT: Index: 1
21 CHECK-NEXT: Type: COMDAT (0x1)
22 CHECK-NEXT: Signature: _Z3fooIcEvT_
23 CHECK-NEXT: Section(s) in group [
24 CHECK-NEXT: .text._Z3fooIcEvT_ (10)
25 CHECK-NEXT: .rela.text._Z3fooIcEvT_ (11)
26 CHECK-NEXT: ]
27 CHECK-NEXT: }
28 CHECK-NEXT: Group {
29 CHECK-NEXT: Name: .group (92)
30 CHECK-NEXT: Index: 2
31 CHECK-NEXT: Type: COMDAT (0x1)
32 CHECK-NEXT: Signature: _Z3fooIiEvT_
33 CHECK-NEXT: Section(s) in group [
34 CHECK-NEXT: .text._Z3fooIiEvT_ (12)
35 CHECK-NEXT: .rela.text._Z3fooIiEvT_ (13)
36 CHECK-NEXT: ]
37 CHECK-NEXT: }
38
5858 void printGnuHashTable() override;
5959 void printLoadName() override;
6060 void printVersionInfo() override;
61 void printGroupSections() override;
6162
6263 void printAttributes() override;
6364 void printMipsPLTGOT() override;
791792 }
792793 }
793794
795 static const char *getGroupType(uint32_t Flag) {
796 if (Flag & ELF::GRP_COMDAT)
797 return "COMDAT";
798 else
799 return "(unknown)";
800 }
801
794802 static const EnumEntry ElfSectionFlags[] = {
795803 LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE ),
796804 LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC ),
22492257 llvm::outs(),
22502258 StackMapV1Parser(*StackMapContentsArray));
22512259 }
2260 template void ELFDumper::printGroupSections() {
2261 DictScope Lists(W, "Groups");
2262 uint32_t SectionIndex = 0;
2263 bool HasGroups = false;
2264 for (const Elf_Shdr &Sec : Obj->sections()) {
2265 if (Sec.sh_type == ELF::SHT_GROUP) {
2266 HasGroups = true;
2267 ErrorOr Symtab =
2268 errorOrDefault(Obj->getSection(Sec.sh_link));
2269 ErrorOr StrTableOrErr = Obj->getStringTableForSymtab(**Symtab);
2270 error(StrTableOrErr.getError());
2271 StringRef StrTable = *StrTableOrErr;
2272 const Elf_Sym *Sym =
2273 Obj->template getEntry(*Symtab, Sec.sh_info);
2274 auto Data = errorOrDefault(
2275 Obj->template getSectionContentsAsArray(&Sec));
2276 DictScope D(W, "Group");
2277 StringRef Name = errorOrDefault(Obj->getSectionName(&Sec));
2278 W.printNumber("Name", Name, Sec.sh_name);
2279 W.printNumber("Index", SectionIndex);
2280 W.printHex("Type", getGroupType(Data[0]), Data[0]);
2281 W.startLine() << "Signature: " << StrTable.data() + Sym->st_name << "\n";
2282 {
2283 ListScope L(W, "Section(s) in group");
2284 int Member = 1;
2285 while (Member < Data.size()) {
2286 auto Sec = errorOrDefault(Obj->getSection(Data[Member]));
2287 const StringRef Name = errorOrDefault(Obj->getSectionName(Sec));
2288 W.startLine() << Name << " (" << std::to_string(Data[Member++])
2289 << ")\n";
2290 }
2291 }
2292 }
2293 ++SectionIndex;
2294 }
2295 if (!HasGroups)
2296 W.startLine() << "There are no group sections in the file.\n";
2297 }
4141 virtual void printGnuHashTable() { }
4242 virtual void printLoadName() {}
4343 virtual void printVersionInfo() {}
44 virtual void printGroupSections() {}
4445
4546 // Only implemented for ARM ELF at this time.
4647 virtual void printAttributes() { }
226226 cl::desc("Display ELF version sections (if present)"));
227227 cl::alias VersionInfoShort("V", cl::desc("Alias for -version-info"),
228228 cl::aliasopt(VersionInfo));
229
230 cl::opt SectionGroups("elf-section-groups",
231 cl::desc("Display ELF section group contents"));
232 cl::alias SectionGroupsShort("g", cl::desc("Alias for -elf-sections-groups"),
233 cl::aliasopt(SectionGroups));
234
229235 } // namespace opts
230236
231237 namespace llvm {
333339 Dumper->printGnuHashTable();
334340 if (opts::VersionInfo)
335341 Dumper->printVersionInfo();
336 if (Obj->getArch() == llvm::Triple::arm && Obj->isELF())
337 if (opts::ARMAttributes)
338 Dumper->printAttributes();
339 if (isMipsArch(Obj->getArch()) && Obj->isELF()) {
340 if (opts::MipsPLTGOT)
341 Dumper->printMipsPLTGOT();
342 if (opts::MipsABIFlags)
343 Dumper->printMipsABIFlags();
344 if (opts::MipsReginfo)
345 Dumper->printMipsReginfo();
342 if (Obj->isELF()) {
343 if (Obj->getArch() == llvm::Triple::arm)
344 if (opts::ARMAttributes)
345 Dumper->printAttributes();
346 if (isMipsArch(Obj->getArch())) {
347 if (opts::MipsPLTGOT)
348 Dumper->printMipsPLTGOT();
349 if (opts::MipsABIFlags)
350 Dumper->printMipsABIFlags();
351 if (opts::MipsReginfo)
352 Dumper->printMipsReginfo();
353 }
354 if (opts::SectionGroups)
355 Dumper->printGroupSections();
346356 }
347357 if (Obj->isCOFF()) {
348358 if (opts::COFFImports)