[llvm] r363683 - [llvm-readobj] Allow --hex-dump/--string-dump to dump multiple sections

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 18 07:01:04 PDT 2019


Author: maskray
Date: Tue Jun 18 07:01:03 2019
New Revision: 363683

URL: http://llvm.org/viewvc/llvm-project?rev=363683&view=rev
Log:
[llvm-readobj] Allow --hex-dump/--string-dump to dump multiple sections

1) `-x foo` currently dumps one `foo`. This change makes it dump all `foo`.
2) `-x foo -x foo` currently dumps `foo` twice. This change makes it dump `foo` once.
   In addition, if foo has section index 9, `-x foo -x 9` dumps `foo` once.
3) Give a warning instead of an error if `foo` does not exist.

The new behaviors match GNU readelf.

Also, print a new line as a separator between two section dumps.
GNU readelf uses two lines, but one seems good enough.

Reviewed By: grimar, jhenderson

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

Added:
    llvm/trunk/test/tools/llvm-readobj/hex-dump-multi.s
    llvm/trunk/test/tools/llvm-readobj/hex-dump.test
    llvm/trunk/test/tools/llvm-readobj/string-dump-multi.s
Removed:
    llvm/trunk/test/tools/llvm-readobj/hexdump.test
    llvm/trunk/test/tools/llvm-readobj/print-hex.test
Modified:
    llvm/trunk/test/tools/llvm-objcopy/ELF/overlapping-sections-in-segments.test
    llvm/trunk/test/tools/llvm-objcopy/ELF/overlapping-sections.test
    llvm/trunk/test/tools/llvm-readobj/string-dump.test
    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/test/tools/llvm-objcopy/ELF/overlapping-sections-in-segments.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/overlapping-sections-in-segments.test?rev=363683&r1=363682&r2=363683&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/overlapping-sections-in-segments.test (original)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/overlapping-sections-in-segments.test Tue Jun 18 07:01:03 2019
@@ -32,6 +32,7 @@
 
 # CONTENTS:      Hex dump of section '.first':
 # CONTENTS-NEXT: 0x00000000 01234567
+# CONTENTS-EMPTY:
 # CONTENTS-NEXT: Hex dump of section '.second':
 # CONTENTS-NEXT: 0x00000000 23456789
 

Modified: llvm/trunk/test/tools/llvm-objcopy/ELF/overlapping-sections.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/ELF/overlapping-sections.test?rev=363683&r1=363682&r2=363683&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/ELF/overlapping-sections.test (original)
+++ llvm/trunk/test/tools/llvm-objcopy/ELF/overlapping-sections.test Tue Jun 18 07:01:03 2019
@@ -37,6 +37,7 @@
 
 # CONTENTS:      Hex dump of section '.first':
 # CONTENTS-NEXT: 0x00000000 01234567
+# CONTENTS-EMPTY:
 # CONTENTS-NEXT: Hex dump of section '.second':
 # CONTENTS-NEXT: 0x00000000 23456789
 

Added: llvm/trunk/test/tools/llvm-readobj/hex-dump-multi.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/hex-dump-multi.s?rev=363683&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/hex-dump-multi.s (added)
+++ llvm/trunk/test/tools/llvm-readobj/hex-dump-multi.s Tue Jun 18 07:01:03 2019
@@ -0,0 +1,21 @@
+# REQUIRES: x86-registered-target
+
+# RUN: llvm-mc -filetype=obj -triple x86_64 %s -o %t.o
+# RUN: llvm-readobj -x .a -x .b %t.o | FileCheck %s
+# RUN: llvm-readelf -x .a -x .b %t.o | FileCheck %s
+
+# CHECK:      Hex dump of section '.a':
+# CHECK-NEXT: 0x00000000 00
+# CHECK-EMPTY:
+# CHECK-NEXT: Hex dump of section '.b':
+# CHECK-NEXT: 0x00000000 01
+# CHECK-EMPTY:
+# CHECK-NEXT: Hex dump of section '.a':
+# CHECK-NEXT: 0x00000000 02
+
+.section .a,"a", at progbits,unique,0
+.byte 0
+.section .b,"a", at progbits
+.byte 1
+.section .a,"a", at progbits,unique,1
+.byte 2

Added: llvm/trunk/test/tools/llvm-readobj/hex-dump.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/hex-dump.test?rev=363683&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/hex-dump.test (added)
+++ llvm/trunk/test/tools/llvm-readobj/hex-dump.test Tue Jun 18 07:01:03 2019
@@ -0,0 +1,59 @@
+## Test that the -x alias can be used flexibly. Create a baseline and ensure
+## all other combinations are identical.
+# RUN: llvm-readelf --file-header --hex-dump=.text \
+# RUN:   %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.out
+# RUN: llvm-readelf -h --hex-dump .text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.1
+# RUN: llvm-readelf -h -x .text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.2
+# RUN: llvm-readelf -h -x=.text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.3
+# RUN: llvm-readelf -h -x.text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.4
+# RUN: llvm-readelf -hx .text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.5
+# RUN: llvm-readelf -hx=.text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.6
+# RUN: llvm-readelf -hx.text %p/Inputs/trivial.obj.elf-x86-64 > %t.hexdump.7
+
+# RUN: cmp %t.hexdump.out %t.hexdump.1
+# RUN: cmp %t.hexdump.out %t.hexdump.2
+# RUN: cmp %t.hexdump.out %t.hexdump.3
+# RUN: cmp %t.hexdump.out %t.hexdump.4
+# RUN: cmp %t.hexdump.out %t.hexdump.5
+# RUN: cmp %t.hexdump.out %t.hexdump.6
+# RUN: cmp %t.hexdump.out %t.hexdump.7
+
+# RUN: llvm-readelf -S %p/Inputs/trivial.obj.elf-x86-64 | FileCheck %s --check-prefix=ELF-SEC
+
+## Both 9 and .strtab refer to .strtab. Test we dump the section only once.
+# RUN: llvm-readobj -x 9 -x 9 -x .strtab -x .strtab %p/Inputs/trivial.obj.elf-x86-64 2>&1 | \
+# RUN:   FileCheck %s --check-prefix=ELF
+# RUN: llvm-readobj -x 9 -x .strtab -x 10 -x not_exist \
+# RUN:   %p/Inputs/trivial.obj.elf-x86-64 2>&1 | FileCheck %s --check-prefixes=ELF-WARN,ELF
+
+# ELF-SEC: [ 9] .strtab
+
+# ELF-WARN: warning: could not find section 'not_exist'
+# ELF-WARN: warning: could not find section 10
+# ELF:      Hex dump of section '.strtab':
+# ELF-NEXT: 0x00000000 00747269 7669616c 2e6c6c00 6d61696e .trivial.ll.main
+# ELF-NEXT: 0x00000010 002e4c2e 73747200 70757473 00536f6d ..L.str.puts.Som
+# ELF-NEXT: 0x00000020 654f7468 65724675 6e637469 6f6e005f eOtherFunction._
+# ELF-NEXT: 0x00000030 474c4f42 414c5f4f 46465345 545f5441 GLOBAL_OFFSET_TA
+# ELF-NEXT: 0x00000040 424c455f 00                         BLE_.
+# ELF-NOT:  {{.}}
+
+## Below we test -x can be used for other binary formats.
+
+# 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.
+
+# RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.wasm \
+# RUN:     | FileCheck %s --check-prefix WASM
+
+# WASM: 0x00000000 04600001 7f60017f 017f6000 0060017f .`...`....`..`..
+# WASM: 0x00000010 00                                  .

Removed: llvm/trunk/test/tools/llvm-readobj/hexdump.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/hexdump.test?rev=363682&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/hexdump.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/hexdump.test (removed)
@@ -1,32 +0,0 @@
-// Check dumping of the hexadecimal bytes of a section.
-RUN: llvm-readobj -x .text %p/../../Object/Inputs/hello-world.elf-x86-64 | FileCheck %s
-
-CHECK: Hex dump of section '.text':
-CHECK-NEXT: {{^}}0x00400460
-
-// Test that the -x alias can be used flexibly. Create a baseline and ensure
-// all other combinations are identical.
-RUN: llvm-readelf --file-header --hex-dump=.text \
-RUN:   %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.out
-RUN: llvm-readelf -h --hex-dump .text \
-RUN:   %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.1
-RUN: llvm-readelf -h -x .text \
-RUN:   %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.2
-RUN: llvm-readelf -h -x=.text \
-RUN:   %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.3
-RUN: llvm-readelf -h -x.text \
-RUN:   %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.4
-RUN: llvm-readelf -hx .text \
-RUN:   %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.5
-RUN: llvm-readelf -hx=.text \
-RUN:   %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.6
-RUN: llvm-readelf -hx.text \
-RUN:   %p/../../Object/Inputs/hello-world.elf-x86-64 > %t.hexdump.7
-
-RUN: cmp %t.hexdump.out %t.hexdump.1
-RUN: cmp %t.hexdump.out %t.hexdump.2
-RUN: cmp %t.hexdump.out %t.hexdump.3
-RUN: cmp %t.hexdump.out %t.hexdump.4
-RUN: cmp %t.hexdump.out %t.hexdump.5
-RUN: cmp %t.hexdump.out %t.hexdump.6
-RUN: cmp %t.hexdump.out %t.hexdump.7

Removed: 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=363682&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/print-hex.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/print-hex.test (removed)
@@ -1,26 +0,0 @@
-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.
-
-RUN: llvm-readobj -x 1 %p/Inputs/trivial.obj.wasm \
-RUN:     | FileCheck %s --check-prefix WASM
-
-WASM: 0x00000000 04600001 7f60017f 017f6000 0060017f .`...`....`..`..
-WASM: 0x00000010 00                                  .

Added: llvm/trunk/test/tools/llvm-readobj/string-dump-multi.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/string-dump-multi.s?rev=363683&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/string-dump-multi.s (added)
+++ llvm/trunk/test/tools/llvm-readobj/string-dump-multi.s Tue Jun 18 07:01:03 2019
@@ -0,0 +1,21 @@
+# REQUIRES: x86-registered-target
+
+# RUN: llvm-mc -filetype=obj -triple x86_64 %s -o %t.o
+# RUN: llvm-readobj -p .a -p .b %t.o | FileCheck %s
+# RUN: llvm-readelf -p .a -p .b %t.o | FileCheck %s
+
+# CHECK:      String dump of section '.a':
+# CHECK-NEXT: [     0] 0
+# CHECK-EMPTY:
+# CHECK-NEXT: String dump of section '.b':
+# CHECK-NEXT: [     0] 1
+# CHECK-EMPTY:
+# CHECK-NEXT: String dump of section '.a':
+# CHECK-NEXT: [     0] 2
+
+.section .a,"a", at progbits,unique,0
+.asciz "0"
+.section .b,"a", at progbits
+.asciz "1"
+.section .a,"a", at progbits,unique,1
+.asciz "2"

Modified: llvm/trunk/test/tools/llvm-readobj/string-dump.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-readobj/string-dump.test?rev=363683&r1=363682&r2=363683&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-readobj/string-dump.test (original)
+++ llvm/trunk/test/tools/llvm-readobj/string-dump.test Tue Jun 18 07:01:03 2019
@@ -9,9 +9,9 @@
 # flag (-p), with different prefix modes (-p .foo, -p=.foo, -p.foo), and with
 # the value being a index section number instead of a section name.
 # RUN: llvm-readobj -p=.strings -p=.not_null_terminated %t > %t.readobj.1
-# RUN: llvm-readobj -p.strings -p.not_null_terminated %t > %t.readobj.2
+# RUN: llvm-readobj -p.strings -p.strings -p.not_null_terminated %t > %t.readobj.2
 # RUN: llvm-readobj --string-dump=1 --string-dump=2 %t > %t.readobj.3
-# RUN: llvm-readobj -p1 -p2 %t > %t.readobj.4
+# RUN: llvm-readobj -p1 -p1 -p2 %t > %t.readobj.4
 # RUN: llvm-readobj -p=1 -p=2 %t > %t.readobj.5
 
 # RUN: cmp %t.readobj.out %t.readobj.1
@@ -45,19 +45,20 @@
 # CHECK-NEXT: [ 5] are
 # CHECK-NEXT: [ 9] some
 # CHECK-NEXT: [ e] strings
+# CHECK-EMPTY:
 # CHECK-NEXT: String dump of section '.not_null_terminated':
 # CHECK-NEXT: [ 0] no
 # CHECK-NEXT: [ 3] null{{$}}
 # CHECK-NOT:  {{.}}
 
-# RUN: not llvm-readobj --string-dump=does_not_exist %t 2>&1 | FileCheck %s --check-prefix=ERR1
-# RUN: not llvm-readobj --string-dump=42 %t 2>&1 | FileCheck %s --check-prefix=ERR2
+# RUN: llvm-readobj --string-dump=does_not_exist %t 2>&1 | FileCheck %s --check-prefix=WARN1
+# RUN: llvm-readobj --string-dump=42 %t 2>&1 | FileCheck %s --check-prefix=WARN2
 
-# RUN: not llvm-readelf --string-dump=does_not_exist %t 2>&1 | FileCheck %s --check-prefix=ERR1
-# RUN: not llvm-readelf --string-dump=42 %t 2>&1 | FileCheck %s --check-prefix=ERR2
+# RUN: llvm-readelf --string-dump=does_not_exist %t 2>&1 | FileCheck %s --check-prefix=WARN1
+# RUN: llvm-readelf --string-dump=42 %t 2>&1 | FileCheck %s --check-prefix=WARN2
 
-# ERR1: error: could not find section 'does_not_exist'
-# ERR2: error: could not find section '42'
+# WARN1: warning: could not find section 'does_not_exist'
+# WARN2: warning: could not find section 42
 
 --- !ELF
 FileHeader:

Modified: llvm/trunk/tools/llvm-readobj/ObjDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.cpp?rev=363683&r1=363682&r2=363683&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ObjDumper.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/ObjDumper.cpp Tue Jun 18 07:01:03 2019
@@ -19,6 +19,7 @@
 #include "llvm/Support/FormatVariadic.h"
 #include "llvm/Support/ScopedPrinter.h"
 #include "llvm/Support/raw_ostream.h"
+#include <map>
 
 namespace llvm {
 
@@ -32,115 +33,127 @@ static void printAsPrintable(raw_ostream
     W << (isPrint(Start[i]) ? static_cast<char>(Start[i]) : '.');
 }
 
-static Expected<object::SectionRef>
-getSecNameOrIndexAsSecRef(const object::ObjectFile *Obj, StringRef SecName) {
-  char *StrPtr;
-  long SectionIndex = strtol(SecName.data(), &StrPtr, 10);
-  long SecIndex;
-  if (Obj->isELF())
-    SecIndex = 0;
-  else
-    SecIndex = 1;
-  for (object::SectionRef SecRef : Obj->sections()) {
-    if (*StrPtr) {
-      StringRef SectionName;
-
-      if (std::error_code E = SecRef.getName(SectionName))
-        return errorCodeToError(E);
-
-      if (SectionName == SecName)
-        return SecRef;
-    } else if (SecIndex == SectionIndex)
-      return SecRef;
+static std::vector<object::SectionRef>
+getSectionRefsByNameOrIndex(const object::ObjectFile *Obj,
+                            ArrayRef<std::string> Sections) {
+  std::vector<object::SectionRef> Ret;
+  std::map<std::string, bool> SecNames;
+  std::map<unsigned, bool> SecIndices;
+  unsigned SecIndex;
+  for (StringRef Section : Sections) {
+    if (!Section.getAsInteger(0, SecIndex))
+      SecIndices.emplace(SecIndex, false);
+    else
+      SecNames.emplace(Section, false);
+  }
 
+  SecIndex = Obj->isELF() ? 0 : 1;
+  for (object::SectionRef SecRef : Obj->sections()) {
+    StringRef SecName;
+    error(SecRef.getName(SecName));
+    auto NameIt = SecNames.find(SecName);
+    if (NameIt != SecNames.end())
+      NameIt->second = true;
+    auto IndexIt = SecIndices.find(SecIndex);
+    if (IndexIt != SecIndices.end())
+      IndexIt->second = true;
+    if (NameIt != SecNames.end() || IndexIt != SecIndices.end())
+      Ret.push_back(SecRef);
     SecIndex++;
   }
-  return make_error<StringError>(
-      formatv("could not find section '{0}'", SecName),
-      object::object_error::parse_failed);
+
+  for (const std::pair<std::string, bool> &S : SecNames)
+    if (!S.second)
+      reportWarning(formatv("could not find section '{0}'", S.first).str());
+  for (std::pair<unsigned, bool> S : SecIndices)
+    if (!S.second)
+      reportWarning(formatv("could not find section {0}", S.first).str());
+
+  return Ret;
 }
 
-void ObjDumper::printSectionAsString(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() << "String dump of section '" << SectionName << "':\n";
-
-  StringRef SectionContent = unwrapOrError(Section.getContents());
-
-  const uint8_t *SecContent = SectionContent.bytes_begin();
-  const uint8_t *CurrentWord = SecContent;
-  const uint8_t *SecEnd = SectionContent.bytes_end();
-
-  while (CurrentWord <= SecEnd) {
-    size_t WordSize = strnlen(reinterpret_cast<const char *>(CurrentWord),
-                              SecEnd - CurrentWord);
-    if (!WordSize) {
-      CurrentWord++;
-      continue;
+void ObjDumper::printSectionsAsString(const object::ObjectFile *Obj,
+                                      ArrayRef<std::string> Sections) {
+  bool First = true;
+  for (object::SectionRef Section :
+       getSectionRefsByNameOrIndex(Obj, Sections)) {
+    StringRef SectionName;
+    error(Section.getName(SectionName));
+    if (!First)
+      W.startLine() << '\n';
+    First = false;
+    W.startLine() << "String dump of section '" << SectionName << "':\n";
+
+    StringRef SectionContent = unwrapOrError(Section.getContents());
+
+    const uint8_t *SecContent = SectionContent.bytes_begin();
+    const uint8_t *CurrentWord = SecContent;
+    const uint8_t *SecEnd = SectionContent.bytes_end();
+
+    while (CurrentWord <= SecEnd) {
+      size_t WordSize = strnlen(reinterpret_cast<const char *>(CurrentWord),
+                                SecEnd - CurrentWord);
+      if (!WordSize) {
+        CurrentWord++;
+        continue;
+      }
+      W.startLine() << format("[%6tx] ", CurrentWord - SecContent);
+      printAsPrintable(W.startLine(), CurrentWord, WordSize);
+      W.startLine() << '\n';
+      CurrentWord += WordSize + 1;
     }
-    W.startLine() << format("[%6tx] ", CurrentWord - SecContent);
-    printAsPrintable(W.startLine(), CurrentWord, WordSize);
-    W.startLine() << '\n';
-    CurrentWord += WordSize + 1;
   }
 }
 
-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 = unwrapOrError(Section.getContents());
-  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;
-    uint8_t i;
-    uint8_t k;
-
-    W.startLine() << format_hex(Section.getAddress() + (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);
-      }
+void ObjDumper::printSectionsAsHex(const object::ObjectFile *Obj,
+                                   ArrayRef<std::string> Sections) {
+  bool First = true;
+  for (object::SectionRef Section :
+       getSectionRefsByNameOrIndex(Obj, Sections)) {
+    StringRef SectionName;
+    error(Section.getName(SectionName));
+    if (!First)
+      W.startLine() << '\n';
+    First = false;
+    W.startLine() << "Hex dump of section '" << SectionName << "':\n";
+
+    StringRef SectionContent = unwrapOrError(Section.getContents());
+    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;
+      uint8_t i;
+      uint8_t k;
+
+      W.startLine() << format_hex(Section.getAddress() + (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)
-      W.startLine() << (isPrint(TmpSecPtr[i]) ? static_cast<char>(TmpSecPtr[i])
-                                              : '.');
+      // 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)
+        W.startLine() << (isPrint(TmpSecPtr[i])
+                              ? static_cast<char>(TmpSecPtr[i])
+                              : '.');
 
-    W.startLine() << '\n';
+      W.startLine() << '\n';
+    }
   }
 }
 

Modified: llvm/trunk/tools/llvm-readobj/ObjDumper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-readobj/ObjDumper.h?rev=363683&r1=363682&r2=363683&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/ObjDumper.h (original)
+++ llvm/trunk/tools/llvm-readobj/ObjDumper.h Tue Jun 18 07:01:03 2019
@@ -104,8 +104,10 @@ public:
 
   virtual void printStackMap() const = 0;
 
-  void printSectionAsString(const object::ObjectFile *Obj, StringRef SecName);
-  void printSectionAsHex(const object::ObjectFile *Obj, StringRef SecName);
+  void printSectionsAsString(const object::ObjectFile *Obj,
+                             ArrayRef<std::string> Sections);
+  void printSectionsAsHex(const object::ObjectFile *Obj,
+                          ArrayRef<std::string> Sections);
 
 protected:
   ScopedPrinter &W;

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=363683&r1=363682&r2=363683&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp (original)
+++ llvm/trunk/tools/llvm-readobj/llvm-readobj.cpp Tue Jun 18 07:01:03 2019
@@ -495,13 +495,9 @@ static void dumpObject(const ObjectFile
   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);
-    });
+    Dumper->printSectionsAsString(Obj, opts::StringDump);
   if (!opts::HexDump.empty())
-    llvm::for_each(opts::HexDump, [&Dumper, Obj](StringRef SectionName) {
-      Dumper->printSectionAsHex(Obj, SectionName);
-    });
+    Dumper->printSectionsAsHex(Obj, opts::HexDump);
   if (opts::HashTable)
     Dumper->printHashTable();
   if (opts::GnuHashTable)




More information about the llvm-commits mailing list