[llvm] r336782 - [llvm-readobj] Add -hex-dump (-x) option

Paul Semel via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 11 03:00:30 PDT 2018


Author: paulsemel
Date: Wed Jul 11 03:00:29 2018
New Revision: 336782

URL: http://llvm.org/viewvc/llvm-project?rev=336782&view=rev
Log:
[llvm-readobj] Add -hex-dump (-x) option

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

Added:
    llvm/trunk/test/tools/llvm-readobj/print-hex.test
Modified:
    llvm/trunk/include/llvm/Object/COFF.h
    llvm/trunk/include/llvm/Object/MachO.h
    llvm/trunk/lib/Object/COFFObjectFile.cpp
    llvm/trunk/lib/Object/MachOObjectFile.cpp
    llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
    llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
    llvm/trunk/tools/llvm-readobj/MachODumper.cpp
    llvm/trunk/tools/llvm-readobj/ObjDumper.cpp
    llvm/trunk/tools/llvm-readobj/ObjDumper.h
    llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp

Modified: llvm/trunk/include/llvm/Object/COFF.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/COFF.h?rev=336782&r1=336781&r2=336782&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/COFF.h (original)
+++ llvm/trunk/include/llvm/Object/COFF.h Wed Jul 11 03:00:29 2018
@@ -965,6 +965,8 @@ public:
   std::error_code getDataDirectory(uint32_t index,
                                    const data_directory *&Res) const;
   std::error_code getSection(int32_t index, const coff_section *&Res) const;
+  std::error_code getSection(StringRef SectionName,
+                             const coff_section *&Res) const;
 
   template <typename coff_symbol_type>
   std::error_code getSymbol(uint32_t Index,

Modified: llvm/trunk/include/llvm/Object/MachO.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/MachO.h?rev=336782&r1=336781&r2=336782&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/MachO.h (original)
+++ llvm/trunk/include/llvm/Object/MachO.h Wed Jul 11 03:00:29 2018
@@ -304,6 +304,8 @@ public:
   std::error_code getSectionContents(DataRefImpl Sec,
                                      StringRef &Res) const override;
   uint64_t getSectionAlignment(DataRefImpl Sec) const override;
+  Expected<SectionRef> getSection(unsigned SectionIndex) const;
+  Expected<SectionRef> getSection(StringRef SectionName) const;
   bool isSectionCompressed(DataRefImpl Sec) const override;
   bool isSectionText(DataRefImpl Sec) const override;
   bool isSectionData(DataRefImpl Sec) const override;

Modified: llvm/trunk/lib/Object/COFFObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/COFFObjectFile.cpp?rev=336782&r1=336781&r2=336782&view=diff
==============================================================================
--- llvm/trunk/lib/Object/COFFObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/COFFObjectFile.cpp Wed Jul 11 03:00:29 2018
@@ -979,6 +979,21 @@ std::error_code COFFObjectFile::getSecti
   return object_error::parse_failed;
 }
 
+std::error_code COFFObjectFile::getSection(StringRef SectionName,
+                                           const coff_section *&Result) const {
+  Result = nullptr;
+  StringRef SecName;
+  for (const SectionRef &Section : sections()) {
+    if (std::error_code E = Section.getName(SecName))
+      return E;
+    if (SecName == SectionName) {
+      Result = getCOFFSection(Section);
+      return std::error_code();
+    }
+  }
+  return object_error::parse_failed;
+}
+
 std::error_code COFFObjectFile::getString(uint32_t Offset,
                                           StringRef &Result) const {
   if (StringTableSize <= 4)

Modified: llvm/trunk/lib/Object/MachOObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/MachOObjectFile.cpp?rev=336782&r1=336781&r2=336782&view=diff
==============================================================================
--- llvm/trunk/lib/Object/MachOObjectFile.cpp (original)
+++ llvm/trunk/lib/Object/MachOObjectFile.cpp Wed Jul 11 03:00:29 2018
@@ -1939,6 +1939,27 @@ uint64_t MachOObjectFile::getSectionAlig
   return uint64_t(1) << Align;
 }
 
+Expected<SectionRef> MachOObjectFile::getSection(unsigned SectionIndex) const {
+  if (SectionIndex < 1 || SectionIndex > Sections.size())
+    return malformedError("bad section index: " + Twine((int)SectionIndex));
+
+  DataRefImpl DRI;
+  DRI.d.a = SectionIndex - 1;
+  return SectionRef(DRI, this);
+}
+
+Expected<SectionRef> MachOObjectFile::getSection(StringRef SectionName) const {
+  StringRef SecName;
+  for (const SectionRef &Section : sections()) {
+    if (std::error_code E = Section.getName(SecName))
+      return errorCodeToError(E);
+    if (SecName == SectionName) {
+      return Section;
+    }
+  }
+  return errorCodeToError(object_error::parse_failed);
+}
+
 bool MachOObjectFile::isSectionCompressed(DataRefImpl Sec) const {
   return false;
 }

Added: llvm/trunk/test/tools/llvm-readobj/print-hex.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/print-hex.test?rev=336782&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/print-hex.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/print-hex.test Wed Jul 11 03:00:29 2018
@@ -0,0 +1,20 @@
+RUN: llvm-readobj -x .strtab %p/Inputs/trivial.obj.elf-x86-64 \
+RUN:     | FileCheck %s --check-prefix ELF
+
+ELF: 0x00000000 00747269 7669616c 2e6c6c00 6d61696e .trivial.ll.main
+ELF: 0x00000010 002e4c2e 73747200 70757473 00536f6d ..L.str.puts.Som
+ELF: 0x00000020 654f7468 65724675 6e637469 6f6e005f eOtherFunction._
+ELF: 0x00000030 474c4f42 414c5f4f 46465345 545f5441 GLOBAL_OFFSET_TA
+ELF: 0x00000040 424c455f 00                         BLE_.
+
+RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.coff-x86-64 \
+RUN:     | FileCheck %s --check-prefix COFF
+
+COFF: 0x00000000 4883ec28 488d0d00 000000e8 00000000 H..(H...........
+COFF: 0x00000010 e8000000 0031c048 83c428c3          .....1.H..(.
+
+RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.macho-x86-64 \
+RUN:     | FileCheck %s --check-prefix MACHO
+
+MACHO: 0x00000000 50488d3d 00000000 e8000000 00e80000 PH.=............
+MACHO: 0x00000010 000031c0 5ac3                       ..1.Z.

Modified: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/COFFDumper.cpp?rev=336782&r1=336781&r2=336782&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp Wed Jul 11 03:00:29 2018
@@ -83,6 +83,7 @@ public:
   void printSymbols() override;
   void printDynamicSymbols() override;
   void printUnwindInfo() override;
+  void printSectionAsHex(StringRef StringName) override;
 
   void printNeededLibraries() override;
 
@@ -654,6 +655,28 @@ void COFFDumper::printFileHeaders() {
     printDOSHeader(DH);
 }
 
+void COFFDumper::printSectionAsHex(StringRef SectionName) {
+  char *StrPtr;
+  long SectionIndex = strtol(SectionName.data(), &StrPtr, 10);
+  const coff_section *Sec;
+  if (*StrPtr)
+    error(Obj->getSection(SectionName, Sec));
+  else {
+    error(Obj->getSection((int)SectionIndex, Sec));
+    if (!Sec)
+      return error(object_error::parse_failed);
+  }
+
+  StringRef SecName;
+  error(Obj->getSectionName(Sec, SecName));
+
+  ArrayRef<uint8_t> Content;
+  error(Obj->getSectionContents(Sec, Content));
+  const uint8_t *SecContent = Content.data();
+
+  SectionHexDump(SecName, SecContent, Content.size());
+}
+
 void COFFDumper::printDOSHeader(const dos_header *DH) {
   DictScope D(W, "DOSHeader");
   W.printString("Magic", StringRef(DH->Magic, sizeof(DH->Magic)));

Modified: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ELFDumper.cpp?rev=336782&r1=336781&r2=336782&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp Wed Jul 11 03:00:29 2018
@@ -152,6 +152,7 @@ public:
   void printNeededLibraries() override;
   void printProgramHeaders() override;
   void printSectionAsString(StringRef StringName) override;
+  void printSectionAsHex(StringRef StringName) override;
   void printHashTable() override;
   void printGnuHashTable() override;
   void printLoadName() override;
@@ -282,6 +283,23 @@ public:
 };
 
 template <class ELFT>
+void ELFDumper<ELFT>::printSectionAsHex(StringRef SectionName) {
+  char *StrPtr;
+  long SectionIndex = strtol(SectionName.data(), &StrPtr, 10);
+  const Elf_Shdr *Sec;
+  if (*StrPtr)
+    Sec = unwrapOrError(Obj->getSection(SectionName));
+  else
+    Sec = unwrapOrError(Obj->getSection((unsigned int)SectionIndex));
+
+  StringRef SecName = unwrapOrError(Obj->getSectionName(Sec));
+  const uint8_t *SecContent =
+      reinterpret_cast<const uint8_t *>(Obj->base() + Sec->sh_offset);
+
+  SectionHexDump(SecName, SecContent, Sec->sh_size);
+}
+
+template <class ELFT>
 void ELFDumper<ELFT>::printSymbolsHelper(bool IsDynamic) const {
   StringRef StrTable, SymtabName;
   size_t Entries = 0;

Modified: llvm/trunk/tools/llvm-readobj/MachODumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/MachODumper.cpp?rev=336782&r1=336781&r2=336782&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/MachODumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/MachODumper.cpp Wed Jul 11 03:00:29 2018
@@ -38,6 +38,7 @@ public:
   void printDynamicSymbols() override;
   void printUnwindInfo() override;
   void printStackMap() const override;
+  void printSectionAsHex(StringRef SectionName) override;
 
   void printNeededLibraries() override;
 
@@ -676,6 +677,26 @@ void MachODumper::printStackMap() const
                         StackMapV2Parser<support::big>(StackMapContentsArray));
 }
 
+void MachODumper::printSectionAsHex(StringRef SectionName) {
+  char *StrPtr;
+  long SectionIndex = strtol(SectionName.data(), &StrPtr, 10);
+  SectionRef SecTmp;
+  const SectionRef *Sec = &SecTmp;
+  if (*StrPtr)
+    SecTmp = unwrapOrError(Obj->getSection(SectionName));
+  else
+    SecTmp = unwrapOrError(Obj->getSection((unsigned int)SectionIndex));
+
+  StringRef SecName;
+  error(Sec->getName(SecName));
+
+  StringRef Data;
+  error(Sec->getContents(Data));
+  const uint8_t *SecContent = reinterpret_cast<const uint8_t *>(Data.data());
+
+  SectionHexDump(SecName, SecContent, Data.size());
+}
+
 void MachODumper::printNeededLibraries() {
   ListScope D(W, "NeededLibraries");
 

Modified: llvm/trunk/tools/llvm-readobj/ObjDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.cpp?rev=336782&r1=336781&r2=336782&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ObjDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ObjDumper.cpp Wed Jul 11 03:00:29 2018
@@ -25,4 +25,46 @@ ObjDumper::ObjDumper(ScopedPrinter &Writ
 ObjDumper::~ObjDumper() {
 }
 
+void ObjDumper::SectionHexDump(StringRef SecName, const uint8_t *Section,
+                               size_t Size) {
+  const uint8_t *SecContent = Section;
+  const uint8_t *SecEnd = Section + Size;
+  W.startLine() << "Hex dump of section '" << SecName << "':\n";
+
+  for (const uint8_t *SecPtr = SecContent; SecPtr < SecEnd; SecPtr += 16) {
+    const uint8_t *TmpSecPtr = SecPtr;
+    uint8_t i;
+    uint8_t k;
+
+    W.startLine() << format_hex(SecPtr - SecContent, 10);
+    W.startLine() << ' ';
+    for (i = 0; TmpSecPtr < SecEnd && i < 4; ++i) {
+      for (k = 0; TmpSecPtr < SecEnd && k < 4; k++, TmpSecPtr++) {
+        uint8_t Val = *(reinterpret_cast<const uint8_t *>(TmpSecPtr));
+        W.startLine() << format_hex_no_prefix(Val, 2);
+      }
+      W.startLine() << ' ';
+    }
+
+    // We need to print the correct amount of spaces to match the format.
+    // We are adding the (4 - i) last rows that are 8 characters each.
+    // Then, the (4 - i) spaces that are in between the rows.
+    // Least, if we cut in a middle of a row, we add the remaining characters,
+    // which is (8 - (k * 2))
+    if (i < 4)
+      W.startLine() << format("%*c", (4 - i) * 8 + (4 - i) + (8 - (k * 2)),
+                              ' ');
+
+    TmpSecPtr = SecPtr;
+    for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i) {
+      if (isprint(TmpSecPtr[i]))
+        W.startLine() << TmpSecPtr[i];
+      else
+        W.startLine() << '.';
+    }
+
+    W.startLine() << '\n';
+  }
+}
+
 } // namespace llvm

Modified: llvm/trunk/tools/llvm-readobj/ObjDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.h?rev=336782&r1=336781&r2=336782&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ObjDumper.h (original)
+++ llvm/trunk/tools/llvm-readobj/ObjDumper.h Wed Jul 11 03:00:29 2018
@@ -44,6 +44,7 @@ public:
   virtual void printNeededLibraries() { }
   virtual void printProgramHeaders() { }
   virtual void printSectionAsString(StringRef SectionName) {}
+  virtual void printSectionAsHex(StringRef SectionName) {}
   virtual void printHashTable() { }
   virtual void printGnuHashTable() { }
   virtual void printLoadName() {}
@@ -88,6 +89,7 @@ public:
 
 protected:
   ScopedPrinter &W;
+  void SectionHexDump(StringRef SecName, const uint8_t *Section, size_t Size);
 };
 
 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=336782&r1=336781&r2=336782&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Wed Jul 11 03:00:29 2018
@@ -152,6 +152,12 @@ namespace opts {
   cl::alias StringDumpShort("p", cl::desc("Alias for --string-dump"),
                             cl::aliasopt(StringDump));
 
+  // -hex-dump
+  cl::list<std::string> HexDump("hex-dump", cl::desc("<number|name>"),
+                                cl::ZeroOrMore);
+  cl::alias HexDumpShort("x", cl::desc("Alias for --hex-dump"),
+                         cl::aliasopt(HexDump));
+
   // -hash-table
   cl::opt<bool> HashTable("hash-table",
     cl::desc("Display ELF hash table"));
@@ -431,6 +437,10 @@ static void dumpObject(const ObjectFile
     llvm::for_each(opts::StringDump, [&Dumper](StringRef SectionName) {
       Dumper->printSectionAsString(SectionName);
     });
+  if (!opts::HexDump.empty())
+    llvm::for_each(opts::HexDump, [&Dumper](StringRef SectionName) {
+      Dumper->printSectionAsHex(SectionName);
+    });
   if (opts::HashTable)
     Dumper->printHashTable();
   if (opts::GnuHashTable)




More information about the llvm-commits mailing list