[llvm] r306056 - [llvm-pdbutil] Create a "bytes" subcommand.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 22 13:58:12 PDT 2017


Author: zturner
Date: Thu Jun 22 15:58:11 2017
New Revision: 306056

URL: http://llvm.org/viewvc/llvm-project?rev=306056&view=rev
Log:
[llvm-pdbutil] Create a "bytes" subcommand.

This idea originally came about when I was doing some deep
investigation of why certain bytes in a PDB that we round-tripped
differed from their original bytes in the source PDB.  I found
myself having to hack up the code in many places to dump the
bytes of this substream, or that record.  It would be nice if
we could just do this for every possible stream, substream,
debug chunk type, etc.

It doesn't make sense to put this under dump because there's just
so many options that would detract from the more common use case
of just dumping deserialized records.  So making a new subcommand
seems like the most logical course of action.  In doing so, we
already have two command line options that are suitable for this
new subcommand, so start out by moving them there.

Added:
    llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.h
Modified:
    llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
    llvm/trunk/test/DebugInfo/PDB/pdbdump-raw-blocks.test
    llvm/trunk/test/DebugInfo/PDB/pdbdump-raw-stream.test
    llvm/trunk/tools/llvm-pdbutil/CMakeLists.txt
    llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbutil/LinePrinter.cpp
    llvm/trunk/tools/llvm-pdbutil/LinePrinter.h
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
    llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h

Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test?rev=306056&r1=306055&r2=306056&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-headers.test Thu Jun 22 15:58:11 2017
@@ -1,7 +1,7 @@
-; RUN: llvm-pdbutil raw -all %p/Inputs/empty.pdb | FileCheck -check-prefix=ALL %s
-; RUN: llvm-pdbutil raw -summary -modules -files \
+; RUN: llvm-pdbutil dump -all %p/Inputs/empty.pdb | FileCheck -check-prefix=ALL %s
+; RUN: llvm-pdbutil dump -summary -modules -files \
 ; RUN:              %p/Inputs/big-read.pdb | FileCheck -check-prefix=BIG %s
-; RUN: not llvm-pdbutil raw -summary %p/Inputs/bad-block-size.pdb 2>&1 | FileCheck -check-prefix=BAD-BLOCK-SIZE %s
+; RUN: not llvm-pdbutil dump -summary %p/Inputs/bad-block-size.pdb 2>&1 | FileCheck -check-prefix=BAD-BLOCK-SIZE %s
 
 ALL:                                Summary
 ALL-NEXT: ============================================================

Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-raw-blocks.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-raw-blocks.test?rev=306056&r1=306055&r2=306056&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-raw-blocks.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-raw-blocks.test Thu Jun 22 15:58:11 2017
@@ -1,8 +1,9 @@
-; RUN: llvm-pdbutil dump -block-data=0 %p/Inputs/empty.pdb | FileCheck --check-prefix=BLOCK0 %s
-; RUN: llvm-pdbutil dump -block-data=0-1 %p/Inputs/empty.pdb | FileCheck --check-prefix=BLOCK01 %s
-; RUN: not llvm-pdbutil dump -block-data=0,1 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BADSYNTAX %s
-; RUN: not llvm-pdbutil dump -block-data=0a1 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BADSYNTAX %s
-; RUN: not llvm-pdbutil dump -block-data=0- %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BADSYNTAX %s
+; RUN: llvm-pdbutil bytes -block-data=0 %p/Inputs/empty.pdb | FileCheck --check-prefix=BLOCK0 %s
+; RUN: llvm-pdbutil bytes -block-data=0-1 %p/Inputs/empty.pdb | FileCheck --check-prefix=BLOCK01 %s
+; RUN: llvm-pdbutil bytes -block-data=0-0x1 %p/Inputs/empty.pdb | FileCheck --check-prefix=BLOCK01 %s
+; RUN: not llvm-pdbutil bytes -block-data=0,1 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BADSYNTAX %s
+; RUN: not llvm-pdbutil bytes -block-data=0a1 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BADSYNTAX %s
+; RUN: not llvm-pdbutil bytes -block-data=0- %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BADSYNTAX %s
 
 BLOCK0:                         MSF Blocks
 BLOCK0-NEXT: ============================================================
@@ -21,9 +22,9 @@ BLOCK01-NEXT:     0020: 00100000 0200000
 BLOCK01-NEXT:     0040: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
 BLOCK01-NEXT:     0060: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000  |................................|
 BLOCK01:       Block 1 (
-BLOCK01-NEXT:    0000: C0FCFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................................|
-BLOCK01-NEXT:    0020: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................................|
-BLOCK01-NEXT:    0040: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................................|
+BLOCK01-NEXT:    1000: C0FCFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................................|
+BLOCK01-NEXT:    1020: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................................|
+BLOCK01-NEXT:    1040: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF  |................................|
 BLOCK01-NOT:  Block 2 (
 
 BADSYNTAX: Argument '{{.*}}' invalid format.

Modified: llvm/trunk/test/DebugInfo/PDB/pdbdump-raw-stream.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/PDB/pdbdump-raw-stream.test?rev=306056&r1=306055&r2=306056&view=diff
==============================================================================
--- llvm/trunk/test/DebugInfo/PDB/pdbdump-raw-stream.test (original)
+++ llvm/trunk/test/DebugInfo/PDB/pdbdump-raw-stream.test Thu Jun 22 15:58:11 2017
@@ -1,6 +1,6 @@
-; RUN: llvm-pdbutil dump -stream-data=1 %p/Inputs/empty.pdb | FileCheck --check-prefix=STREAM %s
-; RUN: llvm-pdbutil dump -stream-data=100 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=INVALIDSTREAM %s
-; RUN: llvm-pdbutil dump -stream-data=1,100 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BOTH %s
+; RUN: llvm-pdbutil bytes -stream-data=1 %p/Inputs/empty.pdb | FileCheck --check-prefix=STREAM %s
+; RUN: llvm-pdbutil bytes -stream-data=100 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=INVALIDSTREAM %s
+; RUN: llvm-pdbutil bytes -stream-data=1,100 %p/Inputs/empty.pdb 2>&1 | FileCheck --check-prefix=BOTH %s
 
 STREAM:                             Stream Data
 STREAM-NEXT: ============================================================

Added: llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.cpp?rev=306056&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.cpp (added)
+++ llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.cpp Thu Jun 22 15:58:11 2017
@@ -0,0 +1,167 @@
+//===- BytesOutputStyle.cpp ----------------------------------- *- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "BytesOutputStyle.h"
+
+#include "StreamUtil.h"
+#include "llvm-pdbutil.h"
+
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+namespace {
+struct StreamSpec {
+  uint32_t SI = 0;
+  uint32_t Begin = 0;
+  uint32_t Size = 0;
+};
+} // namespace
+
+static Expected<StreamSpec> parseStreamSpec(StringRef Str) {
+  StreamSpec Result;
+  if (Str.consumeInteger(0, Result.SI))
+    return make_error<RawError>(raw_error_code::invalid_format,
+                                "Invalid Stream Specification");
+  if (Str.consume_front(":")) {
+    if (Str.consumeInteger(0, Result.Begin))
+      return make_error<RawError>(raw_error_code::invalid_format,
+                                  "Invalid Stream Specification");
+  }
+  if (Str.consume_front("@")) {
+    if (Str.consumeInteger(0, Result.Size))
+      return make_error<RawError>(raw_error_code::invalid_format,
+                                  "Invalid Stream Specification");
+  }
+
+  if (!Str.empty())
+    return make_error<RawError>(raw_error_code::invalid_format,
+                                "Invalid Stream Specification");
+  return Result;
+}
+
+static SmallVector<StreamSpec, 2> parseStreamSpecs(LinePrinter &P) {
+  SmallVector<StreamSpec, 2> Result;
+
+  for (auto &Str : opts::bytes::DumpStreamData) {
+    auto ESS = parseStreamSpec(Str);
+    if (!ESS) {
+      P.formatLine("Error parsing stream spec {0}: {1}", Str,
+                   toString(ESS.takeError()));
+      continue;
+    }
+    Result.push_back(*ESS);
+  }
+  return Result;
+}
+
+static void printHeader(LinePrinter &P, const Twine &S) {
+  P.NewLine();
+  P.formatLine("{0,=60}", S);
+  P.formatLine("{0}", fmt_repeat('=', 60));
+}
+
+BytesOutputStyle::BytesOutputStyle(PDBFile &File)
+    : File(File), P(2, false, outs()) {}
+
+Error BytesOutputStyle::dump() {
+
+  if (opts::bytes::DumpBlockRange.hasValue()) {
+    auto &R = *opts::bytes::DumpBlockRange;
+    uint32_t Max = R.Max.getValueOr(R.Min);
+
+    if (Max < R.Min)
+      return make_error<StringError>(
+          "Invalid block range specified.  Max < Min",
+          inconvertibleErrorCode());
+    if (Max >= File.getBlockCount())
+      return make_error<StringError>(
+          "Invalid block range specified.  Requested block out of bounds",
+          inconvertibleErrorCode());
+
+    dumpBlockRanges(R.Min, Max);
+    P.NewLine();
+  }
+
+  if (!opts::bytes::DumpStreamData.empty()) {
+    dumpStreamBytes();
+    P.NewLine();
+  }
+  return Error::success();
+}
+
+void BytesOutputStyle::dumpBlockRanges(uint32_t Min, uint32_t Max) {
+  printHeader(P, "MSF Blocks");
+
+  AutoIndent Indent(P);
+  for (uint32_t I = Min; I <= Max; ++I) {
+    uint64_t Base = I;
+    Base *= File.getBlockSize();
+
+    auto ExpectedData = File.getBlockData(I, File.getBlockSize());
+    if (!ExpectedData) {
+      P.formatLine("Could not get block {0}.  Reason = {1}", I,
+                   toString(ExpectedData.takeError()));
+      continue;
+    }
+    std::string Label = formatv("Block {0}", I).str();
+    P.formatBinary(Label, *ExpectedData, Base, 0);
+  }
+}
+
+void BytesOutputStyle::dumpStreamBytes() {
+  if (StreamPurposes.empty())
+    discoverStreamPurposes(File, StreamPurposes);
+
+  printHeader(P, "Stream Data");
+  ExitOnError Err("Unexpected error reading stream data");
+
+  auto Specs = parseStreamSpecs(P);
+
+  for (const auto &Spec : Specs) {
+    uint32_t End = 0;
+
+    AutoIndent Indent(P);
+    if (Spec.SI >= File.getNumStreams()) {
+      P.formatLine("Stream {0}: Not present", Spec.SI);
+      continue;
+    }
+
+    auto S = MappedBlockStream::createIndexedStream(
+        File.getMsfLayout(), File.getMsfBuffer(), Spec.SI, File.getAllocator());
+    if (!S) {
+      P.NewLine();
+      P.formatLine("Stream {0}: Not present", Spec.SI);
+      continue;
+    }
+
+    if (Spec.Size == 0)
+      End = S->getLength();
+    else
+      End = std::min(Spec.Begin + Spec.Size, S->getLength());
+    uint32_t Size = End - Spec.Begin;
+
+    P.formatLine("Stream {0} ({1:N} bytes): {2}", Spec.SI, S->getLength(),
+                 StreamPurposes[Spec.SI]);
+    AutoIndent Indent2(P);
+
+    BinaryStreamReader R(*S);
+    ArrayRef<uint8_t> StreamData;
+    Err(R.readBytes(StreamData, S->getLength()));
+    StreamData = StreamData.slice(Spec.Begin, Size);
+    P.formatBinary("Data", StreamData, Spec.Begin);
+  }
+}

Added: llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.h?rev=306056&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.h (added)
+++ llvm/trunk/tools/llvm-pdbutil/BytesOutputStyle.h Thu Jun 22 15:58:11 2017
@@ -0,0 +1,41 @@
+//===- BytesOutputStyle.h ------------------------------------- *- C++ --*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVMPDBDUMP_BYTESOUTPUTSTYLE_H
+#define LLVM_TOOLS_LLVMPDBDUMP_BYTESOUTPUTSTYLE_H
+
+#include "LinePrinter.h"
+#include "OutputStyle.h"
+
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+
+namespace pdb {
+
+class PDBFile;
+
+class BytesOutputStyle : public OutputStyle {
+public:
+  BytesOutputStyle(PDBFile &File);
+
+  Error dump() override;
+
+private:
+  void dumpBlockRanges(uint32_t Min, uint32_t Max);
+  void dumpStreamBytes();
+
+  PDBFile &File;
+  LinePrinter P;
+  SmallVector<std::string, 8> StreamPurposes;
+};
+} // namespace pdb
+} // namespace llvm
+
+#endif

Modified: llvm/trunk/tools/llvm-pdbutil/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/CMakeLists.txt?rev=306056&r1=306055&r2=306056&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-pdbutil/CMakeLists.txt Thu Jun 22 15:58:11 2017
@@ -9,6 +9,7 @@ set(LLVM_LINK_COMPONENTS
 
 add_llvm_tool(llvm-pdbutil
   Analyze.cpp
+  BytesOutputStyle.cpp
   Diff.cpp
   DumpOutputStyle.cpp
   llvm-pdbutil.cpp

Modified: llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp?rev=306056&r1=306055&r2=306056&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/DumpOutputStyle.cpp Thu Jun 22 15:58:11 2017
@@ -80,18 +80,6 @@ Error DumpOutputStyle::dump() {
     P.NewLine();
   }
 
-  if (opts::dump::DumpBlockRange.hasValue()) {
-    if (auto EC = dumpBlockRanges())
-      return EC;
-    P.NewLine();
-  }
-
-  if (!opts::dump::DumpStreamData.empty()) {
-    if (auto EC = dumpStreamBytes())
-      return EC;
-    P.NewLine();
-  }
-
   if (opts::dump::DumpStringTable) {
     if (auto EC = dumpStringTable())
       return EC;
@@ -216,103 +204,6 @@ Error DumpOutputStyle::dumpStreamSummary
   return Error::success();
 }
 
-Error DumpOutputStyle::dumpBlockRanges() {
-  printHeader(P, "MSF Blocks");
-
-  auto &R = *opts::dump::DumpBlockRange;
-  uint32_t Max = R.Max.getValueOr(R.Min);
-
-  AutoIndent Indent(P);
-  if (Max < R.Min)
-    return make_error<StringError>(
-        "Invalid block range specified.  Max < Min",
-        std::make_error_code(std::errc::bad_address));
-  if (Max >= File.getBlockCount())
-    return make_error<StringError>(
-        "Invalid block range specified.  Requested block out of bounds",
-        std::make_error_code(std::errc::bad_address));
-
-  for (uint32_t I = R.Min; I <= Max; ++I) {
-    auto ExpectedData = File.getBlockData(I, File.getBlockSize());
-    if (!ExpectedData)
-      return ExpectedData.takeError();
-    std::string Label = formatv("Block {0}", I).str();
-    P.formatBinary(Label, *ExpectedData, 0);
-  }
-
-  return Error::success();
-}
-
-static Error parseStreamSpec(StringRef Str, uint32_t &SI, uint32_t &Offset,
-                             uint32_t &Size) {
-  if (Str.consumeInteger(0, SI))
-    return make_error<RawError>(raw_error_code::invalid_format,
-                                "Invalid Stream Specification");
-  if (Str.consume_front(":")) {
-    if (Str.consumeInteger(0, Offset))
-      return make_error<RawError>(raw_error_code::invalid_format,
-                                  "Invalid Stream Specification");
-  }
-  if (Str.consume_front("@")) {
-    if (Str.consumeInteger(0, Size))
-      return make_error<RawError>(raw_error_code::invalid_format,
-                                  "Invalid Stream Specification");
-  }
-  if (!Str.empty())
-    return make_error<RawError>(raw_error_code::invalid_format,
-                                "Invalid Stream Specification");
-  return Error::success();
-}
-
-Error DumpOutputStyle::dumpStreamBytes() {
-  if (StreamPurposes.empty())
-    discoverStreamPurposes(File, StreamPurposes);
-
-  printHeader(P, "Stream Data");
-  ExitOnError Err("Unexpected error reading stream data");
-
-  for (auto &Str : opts::dump::DumpStreamData) {
-    uint32_t SI = 0;
-    uint32_t Begin = 0;
-    uint32_t Size = 0;
-    uint32_t End = 0;
-
-    if (auto EC = parseStreamSpec(Str, SI, Begin, Size))
-      return EC;
-
-    AutoIndent Indent(P);
-    if (SI >= File.getNumStreams()) {
-      P.formatLine("Stream {0}: Not present", SI);
-      continue;
-    }
-
-    auto S = MappedBlockStream::createIndexedStream(
-        File.getMsfLayout(), File.getMsfBuffer(), SI, File.getAllocator());
-    if (!S) {
-      P.NewLine();
-      P.formatLine("Stream {0}: Not present", SI);
-      continue;
-    }
-
-    if (Size == 0)
-      End = S->getLength();
-    else
-      End = std::min(Begin + Size, S->getLength());
-
-    P.formatLine("Stream {0} ({1:N} bytes): {2}", SI, S->getLength(),
-                 StreamPurposes[SI]);
-    AutoIndent Indent2(P);
-
-    BinaryStreamReader R(*S);
-    ArrayRef<uint8_t> StreamData;
-    Err(R.readBytes(StreamData, S->getLength()));
-    Size = End - Begin;
-    StreamData = StreamData.slice(Begin, Size);
-    P.formatBinary("Data", StreamData, Begin);
-  }
-  return Error::success();
-}
-
 static Expected<ModuleDebugStreamRef> getModuleDebugStream(PDBFile &File,
                                                            uint32_t Index) {
   ExitOnError Err("Unexpected error");

Modified: llvm/trunk/tools/llvm-pdbutil/LinePrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/LinePrinter.cpp?rev=306056&r1=306055&r2=306056&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/LinePrinter.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/LinePrinter.cpp Thu Jun 22 15:58:11 2017
@@ -106,6 +106,20 @@ void LinePrinter::formatBinary(StringRef
   OS << ")";
 }
 
+void LinePrinter::formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
+                               uint64_t Base, uint32_t StartOffset) {
+  NewLine();
+  OS << Label << " (";
+  if (!Data.empty()) {
+    OS << "\n";
+    Base += StartOffset;
+    OS << format_bytes_with_ascii(Data, Base, 32, 4,
+                                  CurrentIndent + IndentSpaces, true);
+    NewLine();
+  }
+  OS << ")";
+}
+
 bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName, uint32_t Size) {
   if (IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters))
     return true;

Modified: llvm/trunk/tools/llvm-pdbutil/LinePrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/LinePrinter.h?rev=306056&r1=306055&r2=306056&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/LinePrinter.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/LinePrinter.h Thu Jun 22 15:58:11 2017
@@ -45,6 +45,8 @@ public:
 
   void formatBinary(StringRef Label, ArrayRef<uint8_t> Data,
                     uint32_t StartOffset);
+  void formatBinary(StringRef Label, ArrayRef<uint8_t> Data, uint64_t BaseAddr,
+                    uint32_t StartOffset);
 
   bool hasColor() const { return UseColor; }
   raw_ostream &getStream() { return OS; }

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp?rev=306056&r1=306055&r2=306056&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Thu Jun 22 15:58:11 2017
@@ -14,6 +14,7 @@
 #include "llvm-pdbutil.h"
 
 #include "Analyze.h"
+#include "BytesOutputStyle.h"
 #include "Diff.h"
 #include "DumpOutputStyle.h"
 #include "LinePrinter.h"
@@ -87,6 +88,8 @@ using namespace llvm::pdb;
 namespace opts {
 
 cl::SubCommand DumpSubcommand("dump", "Dump MSF and CodeView debug info");
+cl::SubCommand BytesSubcommand("bytes", "Dump raw bytes from the PDB file");
+
 cl::SubCommand
     PrettySubcommand("pretty",
                      "Dump semantic information about types and symbols");
@@ -263,6 +266,26 @@ cl::list<std::string> InputFilenames(cl:
 
 cl::OptionCategory FileOptions("Module & File Options");
 
+namespace bytes {
+llvm::Optional<BlockRange> DumpBlockRange;
+
+cl::opt<std::string>
+    DumpBlockRangeOpt("block-data", cl::value_desc("start[-end]"),
+                      cl::desc("Dump binary data from specified range."),
+                      cl::sub(BytesSubcommand));
+
+cl::list<std::string>
+    DumpStreamData("stream-data", cl::CommaSeparated, cl::ZeroOrMore,
+                   cl::desc("Dump binary data from specified streams.  Format "
+                            "is SN[:Start][@Size]"),
+                   cl::sub(BytesSubcommand));
+
+cl::list<std::string> InputFilenames(cl::Positional,
+                                     cl::desc("<input PDB files>"),
+                                     cl::OneOrMore, cl::sub(BytesSubcommand));
+
+} // namespace bytes
+
 namespace dump {
 
 cl::OptionCategory MsfOptions("MSF Container Options");
@@ -276,17 +299,6 @@ cl::opt<bool> DumpSummary("summary", cl:
 cl::opt<bool> DumpStreams("streams",
                           cl::desc("dump summary of the PDB streams"),
                           cl::cat(MsfOptions), cl::sub(DumpSubcommand));
-cl::opt<std::string>
-    DumpBlockRangeOpt("block-data", cl::value_desc("start[-end]"),
-                      cl::desc("Dump binary data from specified range."),
-                      cl::cat(MsfOptions), cl::sub(DumpSubcommand));
-llvm::Optional<BlockRange> DumpBlockRange;
-
-cl::list<std::string>
-    DumpStreamData("stream-data", cl::CommaSeparated, cl::ZeroOrMore,
-                   cl::desc("Dump binary data from specified streams.  Format "
-                            "is SN[:Start][@Size]"),
-                   cl::cat(MsfOptions), cl::sub(DumpSubcommand));
 
 // TYPE OPTIONS
 cl::opt<bool> DumpTypes("types",
@@ -626,6 +638,15 @@ static void dumpRaw(StringRef Path) {
   ExitOnErr(O->dump());
 }
 
+static void dumpBytes(StringRef Path) {
+  std::unique_ptr<IPDBSession> Session;
+  auto &File = loadPDB(Path, Session);
+
+  auto O = llvm::make_unique<BytesOutputStyle>(File);
+
+  ExitOnErr(O->dump());
+}
+
 static void dumpAnalysis(StringRef Path) {
   std::unique_ptr<IPDBSession> Session;
   auto &File = loadPDB(Path, Session);
@@ -882,6 +903,27 @@ static void mergePdbs() {
   ExitOnErr(Builder.commit(OutFile));
 }
 
+static bool validateBlockRangeArgument() {
+  if (opts::bytes::DumpBlockRangeOpt.empty())
+    return true;
+
+  llvm::Regex R("^([^-]+)(-([^-]+))?$");
+  llvm::SmallVector<llvm::StringRef, 2> Matches;
+  if (!R.match(opts::bytes::DumpBlockRangeOpt, &Matches))
+    return false;
+
+  opts::bytes::DumpBlockRange.emplace();
+  if (!to_integer(Matches[1], opts::bytes::DumpBlockRange->Min))
+    return false;
+
+  if (!Matches[3].empty()) {
+    opts::bytes::DumpBlockRange->Max.emplace();
+    if (!to_integer(Matches[3], *opts::bytes::DumpBlockRange->Max))
+      return false;
+  }
+  return true;
+}
+
 int main(int argc_, const char *argv_[]) {
   // Print a stack trace if we signal out.
   sys::PrintStackTraceOnErrorSignal(argv_[0]);
@@ -897,21 +939,11 @@ int main(int argc_, const char *argv_[])
   llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
 
   cl::ParseCommandLineOptions(argv.size(), argv.data(), "LLVM PDB Dumper\n");
-  if (!opts::dump::DumpBlockRangeOpt.empty()) {
-    llvm::Regex R("^([0-9]+)(-([0-9]+))?$");
-    llvm::SmallVector<llvm::StringRef, 2> Matches;
-    if (!R.match(opts::dump::DumpBlockRangeOpt, &Matches)) {
-      errs() << "Argument '" << opts::dump::DumpBlockRangeOpt
-             << "' invalid format.\n";
-      errs().flush();
-      exit(1);
-    }
-    opts::dump::DumpBlockRange.emplace();
-    Matches[1].getAsInteger(10, opts::dump::DumpBlockRange->Min);
-    if (!Matches[3].empty()) {
-      opts::dump::DumpBlockRange->Max.emplace();
-      Matches[3].getAsInteger(10, *opts::dump::DumpBlockRange->Max);
-    }
+  if (!validateBlockRangeArgument()) {
+    errs() << "Argument '" << opts::bytes::DumpBlockRangeOpt
+           << "' invalid format.\n";
+    errs().flush();
+    exit(1);
   }
 
   if (opts::DumpSubcommand) {
@@ -1018,6 +1050,9 @@ int main(int argc_, const char *argv_[])
   } else if (opts::DumpSubcommand) {
     std::for_each(opts::dump::InputFilenames.begin(),
                   opts::dump::InputFilenames.end(), dumpRaw);
+  } else if (opts::BytesSubcommand) {
+    std::for_each(opts::bytes::InputFilenames.begin(),
+                  opts::bytes::InputFilenames.end(), dumpBytes);
   } else if (opts::DiffSubcommand) {
     if (opts::diff::InputFilenames.size() != 2) {
       errs() << "diff subcommand expects exactly 2 arguments.\n";

Modified: llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h?rev=306056&r1=306055&r2=306056&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h Thu Jun 22 15:58:11 2017
@@ -92,16 +92,19 @@ extern llvm::cl::opt<ClassDefinitionForm
 extern llvm::cl::opt<uint32_t> ClassRecursionDepth;
 }
 
-namespace dump {
+namespace bytes {
 struct BlockRange {
   uint32_t Min;
   llvm::Optional<uint32_t> Max;
 };
+extern llvm::Optional<BlockRange> DumpBlockRange;
+extern llvm::cl::list<std::string> DumpStreamData;
+} // namespace bytes
+
+namespace dump {
 
 extern llvm::cl::opt<bool> DumpSummary;
 extern llvm::cl::opt<bool> DumpStreams;
-extern llvm::Optional<BlockRange> DumpBlockRange;
-extern llvm::cl::list<std::string> DumpStreamData;
 
 extern llvm::cl::opt<bool> DumpLines;
 extern llvm::cl::opt<bool> DumpInlineeLines;




More information about the llvm-commits mailing list