[llvm-readobj] Generic hex-dump option

Helpers are available to make this option file format independant. This
patch adds the feature for Wasm file format. It doesn't change the
behavior of the other file format handling.

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

llvm-svn: 337896
diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp
index c840d7e..0ed4ccd 100644
--- a/llvm/tools/llvm-readobj/COFFDumper.cpp
+++ b/llvm/tools/llvm-readobj/COFFDumper.cpp
@@ -83,7 +83,6 @@
   void printSymbols() override;
   void printDynamicSymbols() override;
   void printUnwindInfo() override;
-  void printSectionAsHex(StringRef StringName) override;
 
   void printNeededLibraries() override;
 
@@ -655,28 +654,6 @@
     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)));
diff --git a/llvm/tools/llvm-readobj/ELFDumper.cpp b/llvm/tools/llvm-readobj/ELFDumper.cpp
index 5da66c4..645ec2d 100644
--- a/llvm/tools/llvm-readobj/ELFDumper.cpp
+++ b/llvm/tools/llvm-readobj/ELFDumper.cpp
@@ -152,7 +152,6 @@
   void printDynamicTable() override;
   void printNeededLibraries() override;
   void printProgramHeaders() override;
-  void printSectionAsHex(StringRef StringName) override;
   void printHashTable() override;
   void printGnuHashTable() override;
   void printLoadName() override;
@@ -286,23 +285,6 @@
 };
 
 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;
diff --git a/llvm/tools/llvm-readobj/MachODumper.cpp b/llvm/tools/llvm-readobj/MachODumper.cpp
index c97f598..69ef155 100644
--- a/llvm/tools/llvm-readobj/MachODumper.cpp
+++ b/llvm/tools/llvm-readobj/MachODumper.cpp
@@ -38,7 +38,6 @@
   void printDynamicSymbols() override;
   void printUnwindInfo() override;
   void printStackMap() const override;
-  void printSectionAsHex(StringRef SectionName) override;
 
   void printNeededLibraries() override;
 
@@ -677,26 +676,6 @@
                         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");
 
diff --git a/llvm/tools/llvm-readobj/ObjDumper.cpp b/llvm/tools/llvm-readobj/ObjDumper.cpp
index 4677a37..17675fd 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.cpp
+++ b/llvm/tools/llvm-readobj/ObjDumper.cpp
@@ -37,7 +37,11 @@
   char *StrPtr;
   long SectionIndex = strtol(SecName.data(), &StrPtr, 10);
   object::SectionRef Section;
-  long SecIndex = 0;
+  long SecIndex;
+  if (Obj->isELF())
+    SecIndex = 0;
+  else
+    SecIndex = 1;
   for (object::SectionRef SecRef : Obj->sections()) {
     if (*StrPtr) {
       StringRef SectionName;
@@ -90,11 +94,23 @@
   }
 }
 
-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";
+void ObjDumper::printSectionAsHex(const object::ObjectFile *Obj,
+                                  StringRef SecName) {
+  Expected<object::SectionRef> SectionRefOrError =
+      getSecNameOrIndexAsSecRef(Obj, SecName);
+  if (!SectionRefOrError)
+    error(std::move(SectionRefOrError));
+  object::SectionRef Section = *SectionRefOrError;
+  StringRef SectionName;
+
+  if (std::error_code E = Section.getName(SectionName))
+    error(E);
+  W.startLine() << "Hex dump of section '" << SectionName << "':\n";
+
+  StringRef SectionContent;
+  Section.getContents(SectionContent);
+  const uint8_t *SecContent = SectionContent.bytes_begin();
+  const uint8_t *SecEnd = SecContent + SectionContent.size();
 
   for (const uint8_t *SecPtr = SecContent; SecPtr < SecEnd; SecPtr += 16) {
     const uint8_t *TmpSecPtr = SecPtr;
@@ -121,12 +137,9 @@
                               ' ');
 
     TmpSecPtr = SecPtr;
-    for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i) {
-      if (isprint(TmpSecPtr[i]))
-        W.startLine() << TmpSecPtr[i];
-      else
-        W.startLine() << '.';
-    }
+    for (i = 0; TmpSecPtr + i < SecEnd && i < 16; ++i)
+      W.startLine() << (isprint(TmpSecPtr[i]) ? static_cast<char>(TmpSecPtr[i])
+                                              : '.');
 
     W.startLine() << '\n';
   }
diff --git a/llvm/tools/llvm-readobj/ObjDumper.h b/llvm/tools/llvm-readobj/ObjDumper.h
index 786e1d4..8c3a7be 100644
--- a/llvm/tools/llvm-readobj/ObjDumper.h
+++ b/llvm/tools/llvm-readobj/ObjDumper.h
@@ -89,10 +89,10 @@
   virtual void printStackMap() const = 0;
 
   void printSectionAsString(const object::ObjectFile *Obj, StringRef SecName);
+  void printSectionAsHex(const object::ObjectFile *Obj, StringRef SecName);
 
 protected:
   ScopedPrinter &W;
-  void SectionHexDump(StringRef SecName, const uint8_t *Section, size_t Size);
 };
 
 std::error_code createCOFFDumper(const object::ObjectFile *Obj,
diff --git a/llvm/tools/llvm-readobj/llvm-readobj.cpp b/llvm/tools/llvm-readobj/llvm-readobj.cpp
index 389053d..a7236c0 100644
--- a/llvm/tools/llvm-readobj/llvm-readobj.cpp
+++ b/llvm/tools/llvm-readobj/llvm-readobj.cpp
@@ -441,8 +441,8 @@
       Dumper->printSectionAsString(Obj, SectionName);
     });
   if (!opts::HexDump.empty())
-    llvm::for_each(opts::HexDump, [&Dumper](StringRef SectionName) {
-      Dumper->printSectionAsHex(SectionName);
+    llvm::for_each(opts::HexDump, [&Dumper, Obj](StringRef SectionName) {
+      Dumper->printSectionAsHex(Obj, SectionName);
     });
   if (opts::HashTable)
     Dumper->printHashTable();