[llvm] r301607 - [llvm-pdbdump] Allow printing only a portion of a stream.

Zachary Turner via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 27 17:43:38 PDT 2017


Author: zturner
Date: Thu Apr 27 19:43:38 2017
New Revision: 301607

URL: http://llvm.org/viewvc/llvm-project?rev=301607&view=rev
Log:
[llvm-pdbdump] Allow printing only a portion of a stream.

When dumping raw data from a stream, you might know the offset
of a certain record you're interested in, as well as how long
that record is.  Previously, you had to dump the entire stream
and wade through the bytes to find the interesting record.

This patch allows you to specify an offset and length on the
command line, and it will only dump the requested range.

Added:
    llvm/trunk/test/tools/llvm-pdbdump/raw-stream-data.test
Modified:
    llvm/trunk/include/llvm/Support/ScopedPrinter.h
    llvm/trunk/lib/Support/ScopedPrinter.cpp
    llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
    llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h

Modified: llvm/trunk/include/llvm/Support/ScopedPrinter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/ScopedPrinter.h?rev=301607&r1=301606&r2=301607&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Support/ScopedPrinter.h (original)
+++ llvm/trunk/include/llvm/Support/ScopedPrinter.h Thu Apr 27 19:43:38 2017
@@ -295,6 +295,11 @@ public:
     printBinaryImpl(Label, StringRef(), V, false);
   }
 
+  void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value,
+                        uint32_t StartOffset) {
+    printBinaryImpl(Label, StringRef(), Value, true, StartOffset);
+  }
+
   void printBinaryBlock(StringRef Label, ArrayRef<uint8_t> Value) {
     printBinaryImpl(Label, StringRef(), Value, true);
   }
@@ -333,7 +338,7 @@ private:
   }
 
   void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef<uint8_t> Value,
-                       bool Block);
+                       bool Block, uint32_t StartOffset = 0);
 
   raw_ostream &OS;
   int IndentLevel;

Modified: llvm/trunk/lib/Support/ScopedPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/ScopedPrinter.cpp?rev=301607&r1=301606&r2=301607&view=diff
==============================================================================
--- llvm/trunk/lib/Support/ScopedPrinter.cpp (original)
+++ llvm/trunk/lib/Support/ScopedPrinter.cpp Thu Apr 27 19:43:38 2017
@@ -21,7 +21,8 @@ const std::string to_hexString(uint64_t
 }
 
 void ScopedPrinter::printBinaryImpl(StringRef Label, StringRef Str,
-                                    ArrayRef<uint8_t> Data, bool Block) {
+                                    ArrayRef<uint8_t> Data, bool Block,
+                                    uint32_t StartOffset) {
   if (Data.size() > 16)
     Block = true;
 
@@ -31,7 +32,8 @@ void ScopedPrinter::printBinaryImpl(Stri
       OS << ": " << Str;
     OS << " (\n";
     if (!Data.empty())
-      OS << format_bytes_with_ascii(Data, 0, 16, 4, (IndentLevel + 1) * 2, true)
+      OS << format_bytes_with_ascii(Data, StartOffset, 16, 4,
+                                    (IndentLevel + 1) * 2, true)
          << "\n";
     startLine() << ")\n";
   } else {

Added: llvm/trunk/test/tools/llvm-pdbdump/raw-stream-data.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/raw-stream-data.test?rev=301607&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/raw-stream-data.test (added)
+++ llvm/trunk/test/tools/llvm-pdbdump/raw-stream-data.test Thu Apr 27 19:43:38 2017
@@ -0,0 +1,47 @@
+; RUN: llvm-pdbdump raw -stream-data=8 %p/Inputs/LoadAddressTest.pdb \
+; RUN:   | FileCheck %s -check-prefix=FULL_STREAM
+; RUN: llvm-pdbdump raw -stream-data=8:4 %p/Inputs/LoadAddressTest.pdb \
+; RUN:   | FileCheck %s -check-prefix=OFFSET_STREAM
+; RUN: llvm-pdbdump raw -stream-data=8:4 at 24 %p/Inputs/LoadAddressTest.pdb \
+; RUN:   | FileCheck %s -check-prefix=OFFSET_AND_LENGTH
+
+FULL_STREAM:      Stream Data {
+FULL_STREAM-NEXT:   Stream {
+FULL_STREAM-NEXT:     Index: 8
+FULL_STREAM-NEXT:     Type: Public Symbol Records
+FULL_STREAM-NEXT:     Size: 40
+FULL_STREAM-NEXT:     Blocks:
+FULL_STREAM-NEXT:     Data (
+FULL_STREAM-NEXT:       0000: 12000E11 02000000 10000000 01005F6D  |.............._m|
+FULL_STREAM-NEXT:       0010: 61696E00 12002511 00000000 88000000  |ain...%.........|
+FULL_STREAM-NEXT:       0020: 01006D61 696E0000                    |..main..|
+FULL_STREAM-NEXT:     )
+FULL_STREAM-NEXT:   }
+FULL_STREAM-NEXT: }
+
+OFFSET_STREAM:      Stream Data {
+OFFSET_STREAM-NEXT:   Stream {
+OFFSET_STREAM-NEXT:    Index: 8
+OFFSET_STREAM-NEXT:    Type: Public Symbol Records
+OFFSET_STREAM-NEXT:    Size: 40
+OFFSET_STREAM-NEXT:    Blocks: 
+OFFSET_STREAM-NEXT:    Data (
+OFFSET_STREAM-NEXT:      0004: 02000000 10000000 01005F6D 61696E00  |.........._main.|
+OFFSET_STREAM-NEXT:      0014: 12002511 00000000 88000000 01006D61  |..%...........ma|
+OFFSET_STREAM-NEXT:      0024: 696E0000                             |in..|
+OFFSET_STREAM-NEXT:    )
+OFFSET_STREAM-NEXT:  }
+OFFSET_STREAM-NEXT:}
+
+OFFSET_AND_LENGTH:      Stream Data {
+OFFSET_AND_LENGTH-NEXT:   Stream {
+OFFSET_AND_LENGTH-NEXT:    Index: 8
+OFFSET_AND_LENGTH-NEXT:    Type: Public Symbol Records
+OFFSET_AND_LENGTH-NEXT:    Size: 40
+OFFSET_AND_LENGTH-NEXT:    Blocks: 
+OFFSET_AND_LENGTH-NEXT:    Data (
+OFFSET_AND_LENGTH-NEXT:      0004: 02000000 10000000 01005F6D 61696E00  |.........._main.|
+OFFSET_AND_LENGTH-NEXT:      0014: 12002511 00000000                    |..%.....|
+OFFSET_AND_LENGTH-NEXT:    )
+OFFSET_AND_LENGTH-NEXT:  }
+OFFSET_AND_LENGTH-NEXT:}
\ No newline at end of file

Modified: llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp?rev=301607&r1=301606&r2=301607&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/LLVMOutputStyle.cpp Thu Apr 27 19:43:38 2017
@@ -319,6 +319,27 @@ Error LLVMOutputStyle::dumpBlockRanges()
   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 LLVMOutputStyle::dumpStreamBytes() {
   if (opts::raw::DumpStreamData.empty())
     return Error::success();
@@ -327,7 +348,15 @@ Error LLVMOutputStyle::dumpStreamBytes()
     discoverStreamPurposes(File, StreamPurposes);
 
   DictScope D(P, "Stream Data");
-  for (uint32_t SI : opts::raw::DumpStreamData) {
+  for (auto &Str : opts::raw::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;
+
     if (SI >= File.getNumStreams())
       return make_error<RawError>(raw_error_code::no_stream);
 
@@ -336,6 +365,14 @@ Error LLVMOutputStyle::dumpStreamBytes()
     if (!S)
       continue;
     DictScope DD(P, "Stream");
+    if (Size == 0)
+      End = S->getLength();
+    else {
+      End = Begin + Size;
+      if (End >= S->getLength())
+        return make_error<RawError>(raw_error_code::index_out_of_bounds,
+                                    "Stream is not long enough!");
+    }
 
     P.printNumber("Index", SI);
     P.printString("Type", StreamPurposes[SI]);
@@ -347,7 +384,9 @@ Error LLVMOutputStyle::dumpStreamBytes()
     ArrayRef<uint8_t> StreamData;
     if (auto EC = R.readBytes(StreamData, S->getLength()))
       return EC;
-    P.printBinaryBlock("Data", StreamData);
+    Size = End - Begin;
+    StreamData = StreamData.slice(Begin, Size);
+    P.printBinaryBlock("Data", StreamData, Begin);
   }
   return Error::success();
 }

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp?rev=301607&r1=301606&r2=301607&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.cpp Thu Apr 27 19:43:38 2017
@@ -261,9 +261,10 @@ cl::opt<std::string>
                       cl::cat(MsfOptions), cl::sub(RawSubcommand));
 llvm::Optional<BlockRange> DumpBlockRange;
 
-cl::list<uint32_t>
+cl::list<std::string>
     DumpStreamData("stream-data", cl::CommaSeparated, cl::ZeroOrMore,
-                   cl::desc("Dump binary data from specified streams."),
+                   cl::desc("Dump binary data from specified streams.  Format "
+                            "is SN[:Start][@Size]"),
                    cl::cat(MsfOptions), cl::sub(RawSubcommand));
 
 // TYPE OPTIONS

Modified: llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h?rev=301607&r1=301606&r2=301607&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h (original)
+++ llvm/trunk/tools/llvm-pdbdump/llvm-pdbdump.h Thu Apr 27 19:43:38 2017
@@ -60,7 +60,7 @@ struct BlockRange {
 };
 
 extern llvm::Optional<BlockRange> DumpBlockRange;
-extern llvm::cl::list<uint32_t> DumpStreamData;
+extern llvm::cl::list<std::string> DumpStreamData;
 
 extern llvm::cl::opt<bool> CompactRecords;
 extern llvm::cl::opt<bool> DumpGlobals;




More information about the llvm-commits mailing list