[llvm] r329002 - [llvm-pdbutil] Add an export subcommand.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 2 11:35:21 PDT 2018
Author: zturner
Date: Mon Apr 2 11:35:21 2018
New Revision: 329002
URL: http://llvm.org/viewvc/llvm-project?rev=329002&view=rev
Log:
[llvm-pdbutil] Add an export subcommand.
This command can dump the binary contents of a stream to a file.
This is useful when you want to do side-by-side comparisons of
a specific stream from two PDBs to examine the differences between
them. You can export both of them to a file, then open them up
side by side in a hex editor (for example), so as to eliminate any
differences that might arise from the contents being on different
blocks in the PDB.
In subsequent patches I plan to improve the "explain" subcommand
so that you can explain the contents of a binary file that isn't
necessarily a full PDB, but one of these dumped streams, by telling
the subcommand how to interpret the contents.
Added:
llvm/trunk/test/tools/llvm-pdbdump/Inputs/tpi.bin (with props)
llvm/trunk/test/tools/llvm-pdbdump/export-stream.test
Modified:
llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStream.h
llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp
llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp
llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStream.h?rev=329002&r1=329001&r2=329002&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStream.h Mon Apr 2 11:35:21 2018
@@ -52,7 +52,7 @@ public:
BinarySubstreamRef getNamedStreamsBuffer() const;
- uint32_t getNamedStreamIndex(llvm::StringRef Name) const;
+ Expected<uint32_t> getNamedStreamIndex(llvm::StringRef Name) const;
StringMap<uint32_t> named_streams() const;
private:
Modified: llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp?rev=329002&r1=329001&r2=329002&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp Mon Apr 2 11:35:21 2018
@@ -86,10 +86,10 @@ Error InfoStream::reload() {
uint32_t InfoStream::getStreamSize() const { return Stream->getLength(); }
-uint32_t InfoStream::getNamedStreamIndex(llvm::StringRef Name) const {
+Expected<uint32_t> InfoStream::getNamedStreamIndex(llvm::StringRef Name) const {
uint32_t Result;
if (!NamedStreams.get(Name, Result))
- return 0;
+ return make_error<RawError>(raw_error_code::no_stream);
return Result;
}
Modified: llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp?rev=329002&r1=329001&r2=329002&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp Mon Apr 2 11:35:21 2018
@@ -370,7 +370,10 @@ Expected<PDBStringTable &> PDBFile::getS
if (!IS)
return IS.takeError();
- uint32_t NameStreamIndex = IS->getNamedStreamIndex("/names");
+ Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/names");
+ if (!ExpectedNSI)
+ return ExpectedNSI.takeError();
+ uint32_t NameStreamIndex = *ExpectedNSI;
auto NS =
safelyCreateIndexedStream(ContainerLayout, *Buffer, NameStreamIndex);
@@ -445,7 +448,13 @@ bool PDBFile::hasPDBStringTable() {
auto IS = getPDBInfoStream();
if (!IS)
return false;
- return IS->getNamedStreamIndex("/names") < getNumStreams();
+ Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/names");
+ if (!ExpectedNSI) {
+ consumeError(ExpectedNSI.takeError());
+ return false;
+ }
+ assert(*ExpectedNSI < getNumStreams());
+ return true;
}
/// Wrapper around MappedBlockStream::createIndexedStream() that checks if a
Added: llvm/trunk/test/tools/llvm-pdbdump/Inputs/tpi.bin
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/Inputs/tpi.bin?rev=329002&view=auto
==============================================================================
Binary file - no diff available.
Propchange: llvm/trunk/test/tools/llvm-pdbdump/Inputs/tpi.bin
------------------------------------------------------------------------------
svn:mime-type = application/octet-stream
Added: llvm/trunk/test/tools/llvm-pdbdump/export-stream.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-pdbdump/export-stream.test?rev=329002&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-pdbdump/export-stream.test (added)
+++ llvm/trunk/test/tools/llvm-pdbdump/export-stream.test Mon Apr 2 11:35:21 2018
@@ -0,0 +1,2 @@
+; RUN: llvm-pdbutil export -stream=2 -out=%t.tpi.bin %p/Inputs/InjectedSource.pdb
+; RUN: diff %t.tpi.bin %p/Inputs/tpi.bin
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=329002&r1=329001&r2=329002&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Mon Apr 2 11:35:21 2018
@@ -50,6 +50,7 @@
#include "llvm/DebugInfo/PDB/IPDBSession.h"
#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
@@ -115,6 +116,9 @@ cl::SubCommand MergeSubcommand("merge",
cl::SubCommand ExplainSubcommand("explain",
"Explain the meaning of a file offset");
+cl::SubCommand ExportSubcommand("export",
+ "Write binary data from a stream to a file");
+
cl::OptionCategory TypeCategory("Symbol Type Options");
cl::OptionCategory FilterCategory("Filtering and Sorting Options");
cl::OptionCategory OtherOptions("Other Options");
@@ -618,6 +622,24 @@ cl::list<std::string> InputFilename(cl::
cl::list<uint64_t> Offsets("offset", cl::desc("The file offset to explain"),
cl::sub(ExplainSubcommand), cl::OneOrMore);
} // namespace explain
+
+namespace exportstream {
+cl::list<std::string> InputFilename(cl::Positional,
+ cl::desc("<input PDB file>"), cl::Required,
+ cl::sub(ExportSubcommand));
+cl::opt<std::string> OutputFile("out",
+ cl::desc("The file to write the stream to"),
+ cl::Required, cl::sub(ExportSubcommand));
+cl::opt<std::string>
+ Stream("stream", cl::Required,
+ cl::desc("The index or name of the stream whose contents to export"),
+ cl::sub(ExportSubcommand));
+cl::opt<bool> ForceName("name",
+ cl::desc("Force the interpretation of -stream as a "
+ "string, even if it is a valid integer"),
+ cl::sub(ExportSubcommand), cl::Optional,
+ cl::init(false));
+} // namespace exportstream
}
static ExitOnError ExitOnErr;
@@ -1098,6 +1120,46 @@ static void explain() {
}
}
+static void exportStream() {
+ std::unique_ptr<IPDBSession> Session;
+ PDBFile &File = loadPDB(opts::exportstream::InputFilename.front(), Session);
+
+ std::unique_ptr<MappedBlockStream> SourceStream;
+ uint32_t Index = 0;
+ bool Success = false;
+ std::string OutFileName = opts::exportstream::OutputFile;
+
+ if (!opts::exportstream::ForceName) {
+ // First try to parse it as an integer, if it fails fall back to treating it
+ // as a named stream.
+ if (to_integer(opts::exportstream::Stream, Index)) {
+ if (Index >= File.getNumStreams()) {
+ errs() << "Error: " << Index << " is not a valid stream index.\n";
+ exit(1);
+ }
+ Success = true;
+ outs() << "Dumping contents of stream index " << Index << " to file "
+ << OutFileName << ".\n";
+ }
+ }
+
+ if (!Success) {
+ InfoStream &IS = cantFail(File.getPDBInfoStream());
+ Index = ExitOnErr(IS.getNamedStreamIndex(opts::exportstream::Stream));
+ outs() << "Dumping contents of stream '" << opts::exportstream::Stream
+ << "' (index " << Index << ") to file " << OutFileName << ".\n";
+ }
+
+ SourceStream = MappedBlockStream::createIndexedStream(
+ File.getMsfLayout(), File.getMsfBuffer(), Index, File.getAllocator());
+ auto OutFile = ExitOnErr(
+ FileOutputBuffer::create(OutFileName, SourceStream->getLength()));
+ FileBufferByteStream DestStream(std::move(OutFile), llvm::support::little);
+ BinaryStreamWriter Writer(DestStream);
+ ExitOnErr(Writer.writeStreamRef(*SourceStream));
+ ExitOnErr(DestStream.commit());
+}
+
static bool parseRange(StringRef Str,
Optional<opts::bytes::NumberRange> &Parsed) {
if (Str.empty())
@@ -1274,6 +1336,8 @@ int main(int argc_, const char *argv_[])
mergePdbs();
} else if (opts::ExplainSubcommand) {
explain();
+ } else if (opts::ExportSubcommand) {
+ exportStream();
}
outs().flush();
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=329002&r1=329001&r2=329002&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h Mon Apr 2 11:35:21 2018
@@ -193,6 +193,12 @@ namespace explain {
extern llvm::cl::list<std::string> InputFilename;
extern llvm::cl::list<uint64_t> Offsets;
} // namespace explain
+
+namespace exportstream {
+extern llvm::cl::opt<std::string> OutputFile;
+extern llvm::cl::opt<std::string> Stream;
+extern llvm::cl::opt<bool> ForceName;
+} // namespace exportstream
}
#endif
More information about the llvm-commits
mailing list