[llvm] r352896 - [llvm-readobj] Add a flag to dump just the section-to-segment mapping.

Matt Davis via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 1 10:51:10 PST 2019


Author: mattd
Date: Fri Feb  1 10:51:10 2019
New Revision: 352896

URL: http://llvm.org/viewvc/llvm-project?rev=352896&view=rev
Log:
[llvm-readobj] Add a flag to dump just the section-to-segment mapping.

Summary:
The following patch introduces a new function `printSectionMapping` which is responsible for dumping just the section-to-segment mapping.
This patch also introduces a n option `-section-mapping` that outputs that mapping without the program headers.

Previously, this functionality was controlled by `printProgramHeaders`, and the output from `-program-headers` has not been changed.  I am happy to change the option name, I copied  the name that was displayed when outputting the mapping table.

Reviewers: khemant, jhenderson, grimar, rupprecht

Reviewed By: jhenderson, grimar, rupprecht

Subscribers: rupprecht, jhenderson, llvm-commits

Differential Revision: https://reviews.llvm.org/D57365

Modified:
    llvm/trunk/test/tools/llvm-readobj/gnu-phdrs.test
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
    llvm/trunk/tools/llvm-readobj/ObjDumper.h
    llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp

Modified: llvm/trunk/test/tools/llvm-readobj/gnu-phdrs.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/gnu-phdrs.test?rev=352896&r1=352895&r2=352896&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/gnu-phdrs.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/gnu-phdrs.test Fri Feb  1 10:51:10 2019
@@ -12,8 +12,22 @@
 
 RUN: llvm-readobj -program-headers %p/Inputs/phdrs-elf.exe-i386 --elf-output-style=GNU \
 RUN:   | FileCheck %s -check-prefix ELF32
-RUN: llvm-readobj -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \
-RUN:  --elf-output-style=GNU | FileCheck %s -check-prefix ELF64
+RUN: llvm-readobj -program-headers %p/Inputs/phdrs-elf.exe-x86_64 --elf-output-style=GNU \
+RUN:   | FileCheck %s -check-prefixes ELF64-PHDRS,ELF64-MAPPING
+RUN: llvm-readelf -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \
+RUN:   | FileCheck %s -check-prefixes ELF64-PHDRS,ELF64-MAPPING
+
+# Check that -section-mapping produces a mapping and not the program headers.
+RUN: llvm-readelf -section-mapping %p/Inputs/phdrs-elf.exe-x86_64 \
+RUN:   | FileCheck %s -check-prefix ELF64-MAPPING -implicit-check-not="Program Headers:"
+
+# Check that -section-mapping=false -program-headers produces just program headers.
+RUN: llvm-readelf -section-mapping=false -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \
+RUN:   | FileCheck %s -check-prefix ELF64-PHDRS -implicit-check-not="Section to Segment mapping:"
+
+# Check that only one copy of the section/segment mapping table is produced.
+RUN: llvm-readelf -section-mapping -program-headers %p/Inputs/phdrs-elf.exe-x86_64 \
+RUN:   | FileCheck %s -check-prefix ELF64-ONEMAPPING
 
 ELF32: Elf file type is EXEC (Executable file)
 ELF32-NEXT: Entry point 0x8048460
@@ -46,33 +60,36 @@ ELF32-NEXT:    07     .eh_frame_hdr
 ELF32-NEXT:    08
 ELF32-NEXT:    09     .tdata .ctors .dtors .jcr .dynamic .got
 
-ELF64: Elf file type is EXEC (Executable file)
-ELF64-NEXT: Entry point 0x400610
-ELF64-NEXT: There are 10 program headers, starting at offset 64
-
-ELF64: Program Headers:
-ELF64-NEXT:   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
-ELF64-NEXT:   PHDR           0x000040 0x0000000000400040 0x0000000000400040 0x000230 0x000230 R E 0x8
-ELF64-NEXT:   INTERP         0x000270 0x0000000000400270 0x0000000000400270 0x00001c 0x00001c R   0x1
-ELF64-NEXT:       [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
-ELF64-NEXT:   LOAD           0x000000 0x0000000000400000 0x0000000000400000 0x000924 0x000924 R E 0x200000
-ELF64-NEXT:   LOAD           0x000db4 0x0000000000600db4 0x0000000000600db4 0x000274 0x0002a4 RW  0x200000
-ELF64-NEXT:   DYNAMIC        0x000dd0 0x0000000000600dd0 0x0000000000600dd0 0x000210 0x000210 RW  0x8
-ELF64-NEXT:   NOTE           0x00028c 0x000000000040028c 0x000000000040028c 0x000044 0x000044 R   0x4
-ELF64-NEXT:   TLS            0x000db4 0x0000000000600db4 0x0000000000600db4 0x000004 0x000008 R   0x4
-ELF64-NEXT:   GNU_EH_FRAME   0x00083c 0x000000000040083c 0x000000000040083c 0x00002c 0x00002c R   0x4
-ELF64-NEXT:   GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x8
-ELF64-NEXT:   GNU_RELRO      0x000db4 0x0000000000600db4 0x0000000000600db4 0x00024c 0x00024c R   0x1
-
-ELF64:  Section to Segment mapping:
-ELF64-NEXT:   Segment Sections...
-ELF64-NEXT:    00
-ELF64-NEXT:    01     .interp
-ELF64-NEXT:    02     .interp .note.ABI-tag .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
-ELF64-NEXT:    03     .tdata .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
-ELF64-NEXT:    04     .dynamic
-ELF64-NEXT:    05     .note.ABI-tag .note.gnu.build-id
-ELF64-NEXT:    06     .tdata .tbss
-ELF64-NEXT:    07     .eh_frame_hdr
-ELF64-NEXT:    08
-ELF64-NEXT:    09     .tdata .init_array .fini_array .jcr .dynamic .got
+ELF64-PHDRS: Elf file type is EXEC (Executable file)
+ELF64-PHDRS-NEXT: Entry point 0x400610
+ELF64-PHDRS-NEXT: There are 10 program headers, starting at offset 64
+
+ELF64-PHDRS: Program Headers:
+ELF64-PHDRS-NEXT:   Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
+ELF64-PHDRS-NEXT:   PHDR           0x000040 0x0000000000400040 0x0000000000400040 0x000230 0x000230 R E 0x8
+ELF64-PHDRS-NEXT:   INTERP         0x000270 0x0000000000400270 0x0000000000400270 0x00001c 0x00001c R   0x1
+ELF64-PHDRS-NEXT:       [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
+ELF64-PHDRS-NEXT:   LOAD           0x000000 0x0000000000400000 0x0000000000400000 0x000924 0x000924 R E 0x200000
+ELF64-PHDRS-NEXT:   LOAD           0x000db4 0x0000000000600db4 0x0000000000600db4 0x000274 0x0002a4 RW  0x200000
+ELF64-PHDRS-NEXT:   DYNAMIC        0x000dd0 0x0000000000600dd0 0x0000000000600dd0 0x000210 0x000210 RW  0x8
+ELF64-PHDRS-NEXT:   NOTE           0x00028c 0x000000000040028c 0x000000000040028c 0x000044 0x000044 R   0x4
+ELF64-PHDRS-NEXT:   TLS            0x000db4 0x0000000000600db4 0x0000000000600db4 0x000004 0x000008 R   0x4
+ELF64-PHDRS-NEXT:   GNU_EH_FRAME   0x00083c 0x000000000040083c 0x000000000040083c 0x00002c 0x00002c R   0x4
+ELF64-PHDRS-NEXT:   GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x8
+ELF64-PHDRS-NEXT:   GNU_RELRO      0x000db4 0x0000000000600db4 0x0000000000600db4 0x00024c 0x00024c R   0x1
+
+ELF64-MAPPING:  Section to Segment mapping:
+ELF64-MAPPING-NEXT:   Segment Sections...
+ELF64-MAPPING-NEXT:    00
+ELF64-MAPPING-NEXT:    01     .interp
+ELF64-MAPPING-NEXT:    02     .interp .note.ABI-tag .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
+ELF64-MAPPING-NEXT:    03     .tdata .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
+ELF64-MAPPING-NEXT:    04     .dynamic
+ELF64-MAPPING-NEXT:    05     .note.ABI-tag .note.gnu.build-id
+ELF64-MAPPING-NEXT:    06     .tdata .tbss
+ELF64-MAPPING-NEXT:    07     .eh_frame_hdr
+ELF64-MAPPING-NEXT:    08
+ELF64-MAPPING-NEXT:    09     .tdata .init_array .fini_array .jcr .dynamic .got
+
+ELF64-ONEMAPPING: Section to Segment mapping:
+ELF64-ONEMAPPING-NOT: Section to Segment mapping:

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=352896&r1=352895&r2=352896&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Fri Feb  1 10:51:10 2019
@@ -153,7 +153,8 @@ public:
 
   void printDynamicTable() override;
   void printNeededLibraries() override;
-  void printProgramHeaders() override;
+  void printProgramHeaders(bool PrintProgramHeaders,
+                           cl::boolOrDefault PrintSectionMapping) override;
   void printHashTable() override;
   void printGnuHashTable() override;
   void printLoadName() override;
@@ -337,7 +338,9 @@ public:
   virtual void printSymbol(const ELFFile<ELFT> *Obj, const Elf_Sym *Symbol,
                            const Elf_Sym *FirstSym, StringRef StrTable,
                            bool IsDynamic) = 0;
-  virtual void printProgramHeaders(const ELFFile<ELFT> *Obj) = 0;
+  virtual void printProgramHeaders(const ELFFile<ELFT> *Obj,
+                                   bool PrintProgramHeaders,
+                                   cl::boolOrDefault PrintSectionMapping) = 0;
   virtual void printHashHistogram(const ELFFile<ELFT> *Obj) = 0;
   virtual void printCGProfile(const ELFFile<ELFT> *Obj) = 0;
   virtual void printAddrsig(const ELFFile<ELFT> *Obj) = 0;
@@ -370,7 +373,8 @@ public:
   void printDynamicRelocations(const ELFO *Obj) override;
   void printSymtabMessage(const ELFO *Obj, StringRef Name,
                           size_t Offset) override;
-  void printProgramHeaders(const ELFO *Obj) override;
+  void printProgramHeaders(const ELFO *Obj, bool PrintProgramHeaders,
+                           cl::boolOrDefault PrintSectionMapping) override;
   void printHashHistogram(const ELFFile<ELFT> *Obj) override;
   void printCGProfile(const ELFFile<ELFT> *Obj) override;
   void printAddrsig(const ELFFile<ELFT> *Obj) override;
@@ -444,6 +448,8 @@ private:
   bool checkoffsets(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
   bool checkVMA(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
   bool checkPTDynamic(const Elf_Phdr &Phdr, const Elf_Shdr &Sec);
+  void printProgramHeaders(const ELFO *Obj);
+  void printSectionMapping(const ELFO *Obj);
 };
 
 template <typename ELFT> class LLVMStyle : public DumpStyle<ELFT> {
@@ -461,7 +467,8 @@ public:
   void printSymbols(const ELFO *Obj, bool PrintSymbols,
                     bool PrintDynamicSymbols) override;
   void printDynamicRelocations(const ELFO *Obj) override;
-  void printProgramHeaders(const ELFO *Obj) override;
+  void printProgramHeaders(const ELFO *Obj, bool PrintProgramHeaders,
+                           cl::boolOrDefault PrintSectionMapping) override;
   void printHashHistogram(const ELFFile<ELFT> *Obj) override;
   void printCGProfile(const ELFFile<ELFT> *Obj) override;
   void printAddrsig(const ELFFile<ELFT> *Obj) override;
@@ -477,6 +484,8 @@ private:
   void printDynamicSymbols(const ELFO *Obj);
   void printSymbol(const ELFO *Obj, const Elf_Sym *Symbol, const Elf_Sym *First,
                    StringRef StrTable, bool IsDynamic) override;
+  void printProgramHeaders(const ELFO *Obj);
+  void printSectionMapping(const ELFO *Obj) {}
 
   ScopedPrinter &W;
 };
@@ -1615,8 +1624,11 @@ void ELFDumper<ELFT>::printRelocations()
   ELFDumperStyle->printRelocations(ObjF->getELFFile());
 }
 
-template <class ELFT> void ELFDumper<ELFT>::printProgramHeaders() {
-  ELFDumperStyle->printProgramHeaders(ObjF->getELFFile());
+template <class ELFT>
+void ELFDumper<ELFT>::printProgramHeaders(
+    bool PrintProgramHeaders, cl::boolOrDefault PrintSectionMapping) {
+  ELFDumperStyle->printProgramHeaders(ObjF->getELFFile(), PrintProgramHeaders,
+                                      PrintSectionMapping);
 }
 
 template <class ELFT> void ELFDumper<ELFT>::printDynamicRelocations() {
@@ -3249,6 +3261,19 @@ bool GNUStyle<ELFT>::checkPTDynamic(cons
 }
 
 template <class ELFT>
+void GNUStyle<ELFT>::printProgramHeaders(
+    const ELFO *Obj, bool PrintProgramHeaders,
+    cl::boolOrDefault PrintSectionMapping) {
+  if (PrintProgramHeaders)
+    printProgramHeaders(Obj);
+
+  // Display the section mapping along with the program headers, unless
+  // -section-mapping is explicitly set to false.
+  if (PrintSectionMapping != cl::BOU_FALSE)
+    printSectionMapping(Obj);
+}
+
+template <class ELFT>
 void GNUStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
   unsigned Bias = ELFT::Is64Bits ? 8 : 0;
   const Elf_Ehdr *Header = Obj->getHeader();
@@ -3286,6 +3311,10 @@ void GNUStyle<ELFT>::printProgramHeaders
     }
     OS << "\n";
   }
+}
+
+template <class ELFT>
+void GNUStyle<ELFT>::printSectionMapping(const ELFO *Obj) {
   OS << "\n Section to Segment mapping:\n  Segment Sections...\n";
   int Phnum = 0;
   for (const Elf_Phdr &Phdr : unwrapOrError(Obj->program_headers())) {
@@ -4415,6 +4444,16 @@ void LLVMStyle<ELFT>::printDynamicReloca
 }
 
 template <class ELFT>
+void LLVMStyle<ELFT>::printProgramHeaders(
+    const ELFO *Obj, bool PrintProgramHeaders,
+    cl::boolOrDefault PrintSectionMapping) {
+  if (PrintProgramHeaders)
+    printProgramHeaders(Obj);
+  if (PrintSectionMapping == cl::BOU_TRUE)
+    printSectionMapping(Obj);
+}
+
+template <class ELFT>
 void LLVMStyle<ELFT>::printProgramHeaders(const ELFO *Obj) {
   ListScope L(W, "ProgramHeaders");
 

Modified: llvm/trunk/tools/llvm-readobj/ObjDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.h?rev=352896&r1=352895&r2=352896&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ObjDumper.h (original)
+++ llvm/trunk/tools/llvm-readobj/ObjDumper.h Fri Feb  1 10:51:10 2019
@@ -14,6 +14,7 @@
 
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/CommandLine.h"
 
 namespace llvm {
 namespace object {
@@ -40,13 +41,20 @@ public:
     if (PrintDynamicSymbols)
       printDynamicSymbols();
   }
+  virtual void printProgramHeaders(bool PrintProgramHeaders,
+                                   cl::boolOrDefault PrintSectionMapping) {
+    if (PrintProgramHeaders)
+      printProgramHeaders();
+    if (PrintSectionMapping == cl::BOU_TRUE)
+      printSectionMapping();
+  }
+
   virtual void printUnwindInfo() = 0;
 
   // Only implemented for ELF at this time.
   virtual void printDynamicRelocations() { }
   virtual void printDynamicTable() { }
   virtual void printNeededLibraries() { }
-  virtual void printProgramHeaders() { }
   virtual void printSectionAsHex(StringRef SectionName) {}
   virtual void printHashTable() { }
   virtual void printGnuHashTable() { }
@@ -99,8 +107,10 @@ protected:
   ScopedPrinter &W;
 
 private:
-  virtual void printSymbols() {};
-  virtual void printDynamicSymbols() {};
+  virtual void printSymbols() {}
+  virtual void printDynamicSymbols() {}
+  virtual void printProgramHeaders() {}
+  virtual void printSectionMapping() {}
 };
 
 std::error_code createCOFFDumper(const object::ObjectFile *Obj,

Modified: llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp?rev=352896&r1=352895&r2=352896&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Fri Feb  1 10:51:10 2019
@@ -106,6 +106,11 @@ namespace opts {
   cl::opt<bool> SectionData("section-data",
     cl::desc("Display section data for each section shown."));
 
+  // -section-mapping
+  cl::opt<cl::boolOrDefault>
+      SectionMapping("section-mapping",
+                     cl::desc("Display the section to segment mapping."));
+
   // -relocations, -relocs, -r
   cl::opt<bool> Relocations("relocations",
     cl::desc("Display the relocation entries in the file"));
@@ -474,8 +479,8 @@ static void dumpObject(const ObjectFile
     Dumper->printDynamicTable();
   if (opts::NeededLibraries)
     Dumper->printNeededLibraries();
-  if (opts::ProgramHeaders)
-    Dumper->printProgramHeaders();
+  if (opts::ProgramHeaders || opts::SectionMapping == cl::BOU_TRUE)
+    Dumper->printProgramHeaders(opts::ProgramHeaders, opts::SectionMapping);
   if (!opts::StringDump.empty())
     llvm::for_each(opts::StringDump, [&Dumper, Obj](StringRef SectionName) {
       Dumper->printSectionAsString(Obj, SectionName);




More information about the llvm-commits mailing list