summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Support/ScopedPrinter.h7
-rw-r--r--llvm/lib/Support/ScopedPrinter.cpp6
-rw-r--r--llvm/test/tools/llvm-pdbdump/raw-stream-data.test47
-rw-r--r--llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp43
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp5
-rw-r--r--llvm/tools/llvm-pdbdump/llvm-pdbdump.h2
6 files changed, 102 insertions, 8 deletions
diff --git a/llvm/include/llvm/Support/ScopedPrinter.h b/llvm/include/llvm/Support/ScopedPrinter.h
index a2f2e098543..1b665193221 100644
--- a/llvm/include/llvm/Support/ScopedPrinter.h
+++ b/llvm/include/llvm/Support/ScopedPrinter.h
@@ -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;
diff --git a/llvm/lib/Support/ScopedPrinter.cpp b/llvm/lib/Support/ScopedPrinter.cpp
index d8ee1efd8f3..537ff62c7b0 100644
--- a/llvm/lib/Support/ScopedPrinter.cpp
+++ b/llvm/lib/Support/ScopedPrinter.cpp
@@ -21,7 +21,8 @@ const std::string to_hexString(uint64_t Value, bool UpperCase) {
}
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(StringRef Label, StringRef Str,
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 {
diff --git a/llvm/test/tools/llvm-pdbdump/raw-stream-data.test b/llvm/test/tools/llvm-pdbdump/raw-stream-data.test
new file mode 100644
index 00000000000..d55980632d4
--- /dev/null
+++ b/llvm/test/tools/llvm-pdbdump/raw-stream-data.test
@@ -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@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
diff --git a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
index 20223ac60f4..705728e27d0 100644
--- a/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbdump/LLVMOutputStyle.cpp
@@ -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();
}
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
index 3d7dbffb0d5..e6d363e1626 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp
@@ -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
diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
index f080d6d5525..8b1dde9399b 100644
--- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
+++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.h
@@ -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;
OpenPOWER on IntegriCloud