[llvm] r329207 - [llvm-pdbutil] Add the ability to explain binary files.
Zachary Turner via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 4 10:29:10 PDT 2018
Author: zturner
Date: Wed Apr 4 10:29:09 2018
New Revision: 329207
URL: http://llvm.org/viewvc/llvm-project?rev=329207&view=rev
Log:
[llvm-pdbutil] Add the ability to explain binary files.
Using this, you can use llvm-pdbutil to export the contents of a
stream to a binary file, then run explain on the binary file so
that it treats the offset as an offset into the stream instead
of an offset into a file. This makes it easy to compare the
contents of the same stream from two different files.
Modified:
llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStream.h
llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStream.h
llvm/trunk/include/llvm/DebugInfo/PDB/Native/RawTypes.h
llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp
llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp
llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp
llvm/trunk/tools/llvm-pdbutil/ExplainOutputStyle.cpp
llvm/trunk/tools/llvm-pdbutil/ExplainOutputStyle.h
llvm/trunk/tools/llvm-pdbutil/InputFile.cpp
llvm/trunk/tools/llvm-pdbutil/InputFile.h
llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp
llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStream.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStream.h?rev=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/DbiStream.h Wed Apr 4 10:29:09 2018
@@ -38,9 +38,9 @@ class DbiStream {
friend class DbiStreamBuilder;
public:
- DbiStream(PDBFile &File, std::unique_ptr<msf::MappedBlockStream> Stream);
+ explicit DbiStream(std::unique_ptr<BinaryStream> Stream);
~DbiStream();
- Error reload();
+ Error reload(PDBFile *Pdb);
PdbRaw_DbiVer getDbiVersion() const;
uint32_t getAge() const;
@@ -89,12 +89,11 @@ public:
private:
Error initializeSectionContributionData();
- Error initializeSectionHeadersData();
+ Error initializeSectionHeadersData(PDBFile *Pdb);
Error initializeSectionMapData();
- Error initializeFpoRecords();
+ Error initializeFpoRecords(PDBFile *Pdb);
- PDBFile &Pdb;
- std::unique_ptr<msf::MappedBlockStream> Stream;
+ std::unique_ptr<BinaryStream> Stream;
PDBStringTable ECNames;
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=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStream.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/InfoStream.h Wed Apr 4 10:29:09 2018
@@ -30,7 +30,7 @@ class InfoStream {
friend class InfoStreamBuilder;
public:
- InfoStream(std::unique_ptr<msf::MappedBlockStream> Stream);
+ InfoStream(std::unique_ptr<BinaryStream> Stream);
Error reload();
@@ -56,7 +56,7 @@ public:
StringMap<uint32_t> named_streams() const;
private:
- std::unique_ptr<msf::MappedBlockStream> Stream;
+ std::unique_ptr<BinaryStream> Stream;
const InfoStreamHeader *Header;
Modified: llvm/trunk/include/llvm/DebugInfo/PDB/Native/RawTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/PDB/Native/RawTypes.h?rev=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/include/llvm/DebugInfo/PDB/Native/RawTypes.h (original)
+++ llvm/trunk/include/llvm/DebugInfo/PDB/Native/RawTypes.h Wed Apr 4 10:29:09 2018
@@ -112,6 +112,8 @@ struct DbiBuildNo {
static const uint16_t BuildMajorMask = 0x7F00;
static const uint16_t BuildMajorShift = 8;
+
+ static const uint16_t NewVersionFormatMask = 0x8000;
};
/// The fixed size header that appears at the beginning of the DBI Stream.
Modified: llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp?rev=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/DbiStream.cpp Wed Apr 4 10:29:09 2018
@@ -45,12 +45,12 @@ static Error loadSectionContribs(FixedSt
return Error::success();
}
-DbiStream::DbiStream(PDBFile &File, std::unique_ptr<MappedBlockStream> Stream)
- : Pdb(File), Stream(std::move(Stream)), Header(nullptr) {}
+DbiStream::DbiStream(std::unique_ptr<BinaryStream> Stream)
+ : Stream(std::move(Stream)), Header(nullptr) {}
DbiStream::~DbiStream() = default;
-Error DbiStream::reload() {
+Error DbiStream::reload(PDBFile *Pdb) {
BinaryStreamReader Reader(*Stream);
if (Stream->getLength() < sizeof(DbiStreamHeader))
@@ -123,11 +123,11 @@ Error DbiStream::reload() {
if (auto EC = initializeSectionContributionData())
return EC;
- if (auto EC = initializeSectionHeadersData())
+ if (auto EC = initializeSectionHeadersData(Pdb))
return EC;
if (auto EC = initializeSectionMapData())
return EC;
- if (auto EC = initializeFpoRecords())
+ if (auto EC = initializeFpoRecords(Pdb))
return EC;
if (Reader.bytesRemaining() > 0)
@@ -246,7 +246,10 @@ Error DbiStream::initializeSectionContri
}
// Initializes this->SectionHeaders.
-Error DbiStream::initializeSectionHeadersData() {
+Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) {
+ if (!Pdb)
+ return Error::success();
+
if (DbgStreams.size() == 0)
return Error::success();
@@ -254,11 +257,11 @@ Error DbiStream::initializeSectionHeader
if (StreamNum == kInvalidStreamIndex)
return Error::success();
- if (StreamNum >= Pdb.getNumStreams())
+ if (StreamNum >= Pdb->getNumStreams())
return make_error<RawError>(raw_error_code::no_stream);
auto SHS = MappedBlockStream::createIndexedStream(
- Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum, Pdb.getAllocator());
+ Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator());
size_t StreamLen = SHS->getLength();
if (StreamLen % sizeof(object::coff_section))
@@ -276,7 +279,10 @@ Error DbiStream::initializeSectionHeader
}
// Initializes this->Fpos.
-Error DbiStream::initializeFpoRecords() {
+Error DbiStream::initializeFpoRecords(PDBFile *Pdb) {
+ if (!Pdb)
+ return Error::success();
+
if (DbgStreams.size() == 0)
return Error::success();
@@ -286,11 +292,11 @@ Error DbiStream::initializeFpoRecords()
if (StreamNum == kInvalidStreamIndex)
return Error::success();
- if (StreamNum >= Pdb.getNumStreams())
+ if (StreamNum >= Pdb->getNumStreams())
return make_error<RawError>(raw_error_code::no_stream);
auto FS = MappedBlockStream::createIndexedStream(
- Pdb.getMsfLayout(), Pdb.getMsfBuffer(), StreamNum, Pdb.getAllocator());
+ Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator());
size_t StreamLen = FS->getLength();
if (StreamLen % sizeof(object::FpoData))
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=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/InfoStream.cpp Wed Apr 4 10:29:09 2018
@@ -20,7 +20,7 @@ using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;
-InfoStream::InfoStream(std::unique_ptr<MappedBlockStream> Stream)
+InfoStream::InfoStream(std::unique_ptr<BinaryStream> Stream)
: Stream(std::move(Stream)), Header(nullptr) {}
Error InfoStream::reload() {
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=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp (original)
+++ llvm/trunk/lib/DebugInfo/PDB/Native/PDBFile.cpp Wed Apr 4 10:29:09 2018
@@ -289,8 +289,8 @@ Expected<DbiStream &> PDBFile::getPDBDbi
auto DbiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamDBI);
if (!DbiS)
return DbiS.takeError();
- auto TempDbi = llvm::make_unique<DbiStream>(*this, std::move(*DbiS));
- if (auto EC = TempDbi->reload())
+ auto TempDbi = llvm::make_unique<DbiStream>(std::move(*DbiS));
+ if (auto EC = TempDbi->reload(this))
return std::move(EC);
Dbi = std::move(TempDbi);
}
Modified: llvm/trunk/tools/llvm-pdbutil/ExplainOutputStyle.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/ExplainOutputStyle.cpp?rev=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/ExplainOutputStyle.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/ExplainOutputStyle.cpp Wed Apr 4 10:29:09 2018
@@ -10,6 +10,7 @@
#include "ExplainOutputStyle.h"
#include "FormatUtil.h"
+#include "InputFile.h"
#include "StreamUtil.h"
#include "llvm-pdbutil.h"
@@ -19,6 +20,7 @@
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamArray.h"
#include "llvm/Support/Error.h"
@@ -27,114 +29,157 @@ using namespace llvm::codeview;
using namespace llvm::msf;
using namespace llvm::pdb;
-ExplainOutputStyle::ExplainOutputStyle(PDBFile &File, uint64_t FileOffset)
- : File(File), FileOffset(FileOffset),
- BlockIndex(FileOffset / File.getBlockSize()),
- OffsetInBlock(FileOffset - BlockIndex * File.getBlockSize()),
- P(2, false, outs()) {}
+ExplainOutputStyle::ExplainOutputStyle(InputFile &File, uint64_t FileOffset)
+ : File(File), FileOffset(FileOffset), P(2, false, outs()) {}
Error ExplainOutputStyle::dump() {
P.formatLine("Explaining file offset {0} of file '{1}'.", FileOffset,
File.getFilePath());
- bool IsAllocated = explainBlockStatus();
+ if (File.isPdb())
+ return explainPdbFile();
+
+ return explainBinaryFile();
+}
+
+Error ExplainOutputStyle::explainPdbFile() {
+ bool IsAllocated = explainPdbBlockStatus();
if (!IsAllocated)
return Error::success();
AutoIndent Indent(P);
- if (isSuperBlock())
- explainSuperBlockOffset();
- else if (isFpmBlock())
- explainFpmBlockOffset();
- else if (isBlockMapBlock())
- explainBlockMapOffset();
- else if (isStreamDirectoryBlock())
- explainStreamDirectoryOffset();
- else if (auto Index = getBlockStreamIndex())
- explainStreamOffset(*Index);
+ if (isPdbSuperBlock())
+ explainPdbSuperBlockOffset();
+ else if (isPdbFpmBlock())
+ explainPdbFpmBlockOffset();
+ else if (isPdbBlockMapBlock())
+ explainPdbBlockMapOffset();
+ else if (isPdbStreamDirectoryBlock())
+ explainPdbStreamDirectoryOffset();
+ else if (auto Index = getPdbBlockStreamIndex())
+ explainPdbStreamOffset(*Index);
else
- explainUnknownBlock();
+ explainPdbUnknownBlock();
return Error::success();
}
-bool ExplainOutputStyle::isSuperBlock() const { return BlockIndex == 0; }
+Error ExplainOutputStyle::explainBinaryFile() {
+ std::unique_ptr<BinaryByteStream> Stream =
+ llvm::make_unique<BinaryByteStream>(File.unknown().getBuffer(),
+ llvm::support::little);
+ switch (opts::explain::InputType) {
+ case opts::explain::InputFileType::DBIStream: {
+ DbiStream Dbi(std::move(Stream));
+ if (auto EC = Dbi.reload(nullptr))
+ return EC;
+ explainStreamOffset(Dbi, FileOffset);
+ break;
+ }
+ case opts::explain::InputFileType::PDBStream: {
+ InfoStream Info(std::move(Stream));
+ if (auto EC = Info.reload())
+ return EC;
+ explainStreamOffset(Info, FileOffset);
+ break;
+ }
+ default:
+ llvm_unreachable("Invalid input file type!");
+ }
+ return Error::success();
+}
-bool ExplainOutputStyle::isFpm1() const {
- return ((BlockIndex - 1) % File.getBlockSize() == 0);
+uint32_t ExplainOutputStyle::pdbBlockIndex() const {
+ return FileOffset / File.pdb().getBlockSize();
}
-bool ExplainOutputStyle::isFpm2() const {
- return ((BlockIndex - 2) % File.getBlockSize() == 0);
+
+uint32_t ExplainOutputStyle::pdbBlockOffset() const {
+ uint64_t BlockStart = pdbBlockIndex() * File.pdb().getBlockSize();
+ assert(FileOffset >= BlockStart);
+ return FileOffset - BlockStart;
+}
+
+bool ExplainOutputStyle::isPdbSuperBlock() const {
+ return pdbBlockIndex() == 0;
+}
+
+bool ExplainOutputStyle::isPdbFpm1() const {
+ return ((pdbBlockIndex() - 1) % File.pdb().getBlockSize() == 0);
+}
+bool ExplainOutputStyle::isPdbFpm2() const {
+ return ((pdbBlockIndex() - 2) % File.pdb().getBlockSize() == 0);
}
-bool ExplainOutputStyle::isFpmBlock() const { return isFpm1() || isFpm2(); }
+bool ExplainOutputStyle::isPdbFpmBlock() const {
+ return isPdbFpm1() || isPdbFpm2();
+}
-bool ExplainOutputStyle::isBlockMapBlock() const {
- return BlockIndex == File.getBlockMapIndex();
+bool ExplainOutputStyle::isPdbBlockMapBlock() const {
+ return pdbBlockIndex() == File.pdb().getBlockMapIndex();
}
-bool ExplainOutputStyle::isStreamDirectoryBlock() const {
- const auto &Layout = File.getMsfLayout();
- return llvm::is_contained(Layout.DirectoryBlocks, BlockIndex);
+bool ExplainOutputStyle::isPdbStreamDirectoryBlock() const {
+ const auto &Layout = File.pdb().getMsfLayout();
+ return llvm::is_contained(Layout.DirectoryBlocks, pdbBlockIndex());
}
-Optional<uint32_t> ExplainOutputStyle::getBlockStreamIndex() const {
- const auto &Layout = File.getMsfLayout();
+Optional<uint32_t> ExplainOutputStyle::getPdbBlockStreamIndex() const {
+ const auto &Layout = File.pdb().getMsfLayout();
for (const auto &Entry : enumerate(Layout.StreamMap)) {
- if (!llvm::is_contained(Entry.value(), BlockIndex))
+ if (!llvm::is_contained(Entry.value(), pdbBlockIndex()))
continue;
return Entry.index();
}
return None;
}
-bool ExplainOutputStyle::explainBlockStatus() {
- if (FileOffset >= File.getFileSize()) {
+bool ExplainOutputStyle::explainPdbBlockStatus() {
+ if (FileOffset >= File.pdb().getFileSize()) {
P.formatLine("Address {0} is not in the file (file size = {1}).",
- FileOffset, File.getFileSize());
+ FileOffset, File.pdb().getFileSize());
return false;
}
- P.formatLine("Block:Offset = {2:X-}:{1:X-4}.", FileOffset, OffsetInBlock,
- BlockIndex);
+ P.formatLine("Block:Offset = {2:X-}:{1:X-4}.", FileOffset, pdbBlockOffset(),
+ pdbBlockIndex());
- bool IsFree = File.getMsfLayout().FreePageMap[BlockIndex];
- P.formatLine("Address is in block {0} ({1}allocated).", BlockIndex,
+ bool IsFree = File.pdb().getMsfLayout().FreePageMap[pdbBlockIndex()];
+ P.formatLine("Address is in block {0} ({1}allocated).", pdbBlockIndex(),
IsFree ? "un" : "");
return !IsFree;
}
#define endof(Class, Field) (offsetof(Class, Field) + sizeof(Class::Field))
-void ExplainOutputStyle::explainSuperBlockOffset() {
+void ExplainOutputStyle::explainPdbSuperBlockOffset() {
P.formatLine("This corresponds to offset {0} of the MSF super block, ",
- OffsetInBlock);
- if (OffsetInBlock < endof(SuperBlock, MagicBytes))
+ pdbBlockOffset());
+ if (pdbBlockOffset() < endof(SuperBlock, MagicBytes))
P.printLine("which is part of the MSF file magic.");
- else if (OffsetInBlock < endof(SuperBlock, BlockSize)) {
+ else if (pdbBlockOffset() < endof(SuperBlock, BlockSize)) {
P.printLine("which contains the block size of the file.");
P.formatLine("The current value is {0}.",
- uint32_t(File.getMsfLayout().SB->BlockSize));
- } else if (OffsetInBlock < endof(SuperBlock, FreeBlockMapBlock)) {
+ uint32_t(File.pdb().getMsfLayout().SB->BlockSize));
+ } else if (pdbBlockOffset() < endof(SuperBlock, FreeBlockMapBlock)) {
P.printLine("which contains the index of the FPM block (e.g. 1 or 2).");
P.formatLine("The current value is {0}.",
- uint32_t(File.getMsfLayout().SB->FreeBlockMapBlock));
- } else if (OffsetInBlock < endof(SuperBlock, NumBlocks)) {
+ uint32_t(File.pdb().getMsfLayout().SB->FreeBlockMapBlock));
+ } else if (pdbBlockOffset() < endof(SuperBlock, NumBlocks)) {
P.printLine("which contains the number of blocks in the file.");
P.formatLine("The current value is {0}.",
- uint32_t(File.getMsfLayout().SB->NumBlocks));
- } else if (OffsetInBlock < endof(SuperBlock, NumDirectoryBytes)) {
+ uint32_t(File.pdb().getMsfLayout().SB->NumBlocks));
+ } else if (pdbBlockOffset() < endof(SuperBlock, NumDirectoryBytes)) {
P.printLine("which contains the number of bytes in the stream directory.");
P.formatLine("The current value is {0}.",
- uint32_t(File.getMsfLayout().SB->NumDirectoryBytes));
- } else if (OffsetInBlock < endof(SuperBlock, Unknown1)) {
+ uint32_t(File.pdb().getMsfLayout().SB->NumDirectoryBytes));
+ } else if (pdbBlockOffset() < endof(SuperBlock, Unknown1)) {
P.printLine("whose purpose is unknown.");
P.formatLine("The current value is {0}.",
- uint32_t(File.getMsfLayout().SB->Unknown1));
- } else if (OffsetInBlock < endof(SuperBlock, BlockMapAddr)) {
+ uint32_t(File.pdb().getMsfLayout().SB->Unknown1));
+ } else if (pdbBlockOffset() < endof(SuperBlock, BlockMapAddr)) {
P.printLine("which contains the file offset of the block map.");
P.formatLine("The current value is {0}.",
- uint32_t(File.getMsfLayout().SB->BlockMapAddr));
+ uint32_t(File.pdb().getMsfLayout().SB->BlockMapAddr));
} else {
- assert(OffsetInBlock > sizeof(SuperBlock));
+ assert(pdbBlockOffset() > sizeof(SuperBlock));
P.printLine(
"which is outside the range of valid data for the super block.");
}
@@ -150,21 +195,21 @@ static std::string toBinaryString(uint8_
return std::string(Result);
}
-void ExplainOutputStyle::explainFpmBlockOffset() {
- const MSFLayout &Layout = File.getMsfLayout();
+void ExplainOutputStyle::explainPdbFpmBlockOffset() {
+ const MSFLayout &Layout = File.pdb().getMsfLayout();
uint32_t MainFpm = Layout.mainFpmBlock();
uint32_t AltFpm = Layout.alternateFpmBlock();
- assert(isFpmBlock());
- uint32_t Fpm = isFpm1() ? 1 : 2;
- uint32_t FpmChunk = BlockIndex / File.getBlockSize();
+ assert(isPdbFpmBlock());
+ uint32_t Fpm = isPdbFpm1() ? 1 : 2;
+ uint32_t FpmChunk = pdbBlockIndex() / File.pdb().getBlockSize();
assert((Fpm == MainFpm) || (Fpm == AltFpm));
(void)AltFpm;
bool IsMain = (Fpm == MainFpm);
P.formatLine("Address is in FPM{0} ({1} FPM)", Fpm, IsMain ? "Main" : "Alt");
uint32_t DescribedBlockStart =
- 8 * (FpmChunk * File.getBlockSize() + OffsetInBlock);
- if (DescribedBlockStart > File.getBlockCount()) {
+ 8 * (FpmChunk * File.pdb().getBlockSize() + pdbBlockOffset());
+ if (DescribedBlockStart > File.pdb().getBlockCount()) {
P.printLine("Address is in extraneous FPM space.");
return;
}
@@ -172,13 +217,13 @@ void ExplainOutputStyle::explainFpmBlock
P.formatLine("Address describes the allocation status of blocks [{0},{1})",
DescribedBlockStart, DescribedBlockStart + 8);
ArrayRef<uint8_t> Bytes;
- cantFail(File.getMsfBuffer().readBytes(FileOffset, 1, Bytes));
+ cantFail(File.pdb().getMsfBuffer().readBytes(FileOffset, 1, Bytes));
P.formatLine("Status = {0} (Note: 0 = allocated, 1 = free)",
toBinaryString(Bytes[0]));
}
-void ExplainOutputStyle::explainBlockMapOffset() {
- uint64_t BlockMapOffset = File.getBlockMapOffset();
+void ExplainOutputStyle::explainPdbBlockMapOffset() {
+ uint64_t BlockMapOffset = File.pdb().getBlockMapOffset();
uint32_t OffsetInBlock = FileOffset - BlockMapOffset;
P.formatLine("Address is at offset {0} of the directory block list",
OffsetInBlock);
@@ -195,25 +240,29 @@ static uint32_t getOffsetInStream(ArrayR
return StreamBlockIndex * BlockSize + OffsetInBlock;
}
-void ExplainOutputStyle::explainStreamOffset(uint32_t Stream) {
+void ExplainOutputStyle::explainPdbStreamOffset(uint32_t Stream) {
SmallVector<StreamInfo, 12> Streams;
- discoverStreamPurposes(File, Streams);
+ discoverStreamPurposes(File.pdb(), Streams);
assert(Stream <= Streams.size());
const StreamInfo &S = Streams[Stream];
- const auto &Layout = File.getStreamLayout(Stream);
+ const auto &Layout = File.pdb().getStreamLayout(Stream);
uint32_t StreamOff =
- getOffsetInStream(Layout.Blocks, FileOffset, File.getBlockSize());
+ getOffsetInStream(Layout.Blocks, FileOffset, File.pdb().getBlockSize());
P.formatLine("Address is at offset {0}/{1} of Stream {2} ({3}){4}.",
StreamOff, Layout.Length, Stream, S.getLongName(),
(StreamOff > Layout.Length) ? " in unused space" : "");
switch (S.getPurpose()) {
- case StreamPurpose::DBI:
- explainDbiStream(Stream, StreamOff);
+ case StreamPurpose::DBI: {
+ DbiStream &Dbi = cantFail(File.pdb().getPDBDbiStream());
+ explainStreamOffset(Dbi, StreamOff);
break;
- case StreamPurpose::PDB:
- explainPdbStream(Stream, StreamOff);
+ }
+ case StreamPurpose::PDB: {
+ InfoStream &Info = cantFail(File.pdb().getPDBInfoStream());
+ explainStreamOffset(Info, StreamOff);
break;
+ }
case StreamPurpose::IPI:
case StreamPurpose::TPI:
case StreamPurpose::ModuleStream:
@@ -223,11 +272,11 @@ void ExplainOutputStyle::explainStreamOf
}
}
-void ExplainOutputStyle::explainStreamDirectoryOffset() {
- auto DirectoryBlocks = File.getDirectoryBlockArray();
- const auto &Layout = File.getMsfLayout();
+void ExplainOutputStyle::explainPdbStreamDirectoryOffset() {
+ auto DirectoryBlocks = File.pdb().getDirectoryBlockArray();
+ const auto &Layout = File.pdb().getMsfLayout();
uint32_t StreamOff =
- getOffsetInStream(DirectoryBlocks, FileOffset, File.getBlockSize());
+ getOffsetInStream(DirectoryBlocks, FileOffset, File.pdb().getBlockSize());
P.formatLine("Address is at offset {0}/{1} of Stream Directory{2}.",
StreamOff, uint32_t(Layout.SB->NumDirectoryBytes),
uint32_t(StreamOff > Layout.SB->NumDirectoryBytes)
@@ -235,7 +284,7 @@ void ExplainOutputStyle::explainStreamDi
: "");
}
-void ExplainOutputStyle::explainUnknownBlock() {
+void ExplainOutputStyle::explainPdbUnknownBlock() {
P.formatLine("Address has unknown purpose.");
}
@@ -352,10 +401,9 @@ static void explainSubstreamOffset(LineP
}
}
-void ExplainOutputStyle::explainDbiStream(uint32_t StreamIdx,
- uint32_t OffsetInStream) {
+void ExplainOutputStyle::explainStreamOffset(DbiStream &Dbi,
+ uint32_t OffsetInStream) {
P.printLine("Within the DBI stream:");
- DbiStream &Dbi = cantFail(File.getPDBDbiStream());
AutoIndent Indent(P);
const DbiStreamHeader *Header = Dbi.getHeader();
assert(Header != nullptr);
@@ -401,10 +449,9 @@ static void explainPdbStreamHeaderOffset
printStructField(P, "the guid of the PDB", fmt_guid(Header->Guid.Guid));
}
-void ExplainOutputStyle::explainPdbStream(uint32_t StreamIdx,
- uint32_t OffsetInStream) {
+void ExplainOutputStyle::explainStreamOffset(InfoStream &Info,
+ uint32_t OffsetInStream) {
P.printLine("Within the PDB stream:");
- InfoStream &Info = cantFail(File.getPDBInfoStream());
AutoIndent Indent(P);
struct SubstreamInfo {
Modified: llvm/trunk/tools/llvm-pdbutil/ExplainOutputStyle.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/ExplainOutputStyle.h?rev=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/ExplainOutputStyle.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/ExplainOutputStyle.h Wed Apr 4 10:29:09 2018
@@ -20,41 +20,46 @@ namespace llvm {
namespace pdb {
class DbiStream;
-class PDBFile;
+class InfoStream;
+class InputFile;
class ExplainOutputStyle : public OutputStyle {
public:
- ExplainOutputStyle(PDBFile &File, uint64_t FileOffset);
+ ExplainOutputStyle(InputFile &File, uint64_t FileOffset);
Error dump() override;
private:
- bool explainBlockStatus();
+ Error explainPdbFile();
+ Error explainBinaryFile();
- bool isFpm1() const;
- bool isFpm2() const;
+ bool explainPdbBlockStatus();
- bool isSuperBlock() const;
- bool isFpmBlock() const;
- bool isBlockMapBlock() const;
- bool isStreamDirectoryBlock() const;
- Optional<uint32_t> getBlockStreamIndex() const;
-
- void explainSuperBlockOffset();
- void explainFpmBlockOffset();
- void explainBlockMapOffset();
- void explainStreamDirectoryOffset();
- void explainStreamOffset(uint32_t Stream);
- void explainUnknownBlock();
+ bool isPdbFpm1() const;
+ bool isPdbFpm2() const;
- void explainDbiStream(uint32_t StreamIdx, uint32_t OffsetInStream);
- void explainPdbStream(uint32_t StreamIdx, uint32_t OffsetInStream);
+ bool isPdbSuperBlock() const;
+ bool isPdbFpmBlock() const;
+ bool isPdbBlockMapBlock() const;
+ bool isPdbStreamDirectoryBlock() const;
+ Optional<uint32_t> getPdbBlockStreamIndex() const;
+
+ void explainPdbSuperBlockOffset();
+ void explainPdbFpmBlockOffset();
+ void explainPdbBlockMapOffset();
+ void explainPdbStreamDirectoryOffset();
+ void explainPdbStreamOffset(uint32_t Stream);
+ void explainPdbUnknownBlock();
- PDBFile &File;
+ void explainStreamOffset(DbiStream &Stream, uint32_t OffsetInStream);
+ void explainStreamOffset(InfoStream &Stream, uint32_t OffsetInStream);
+
+ uint32_t pdbBlockIndex() const;
+ uint32_t pdbBlockOffset() const;
+
+ InputFile &File;
const uint64_t FileOffset;
- const uint64_t BlockIndex;
- const uint64_t OffsetInBlock;
LinePrinter P;
};
} // namespace pdb
Modified: llvm/trunk/tools/llvm-pdbutil/InputFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/InputFile.cpp?rev=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/InputFile.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/InputFile.cpp Wed Apr 4 10:29:09 2018
@@ -242,7 +242,7 @@ void SymbolGroup::formatFromChecksumsOff
}
}
-Expected<InputFile> InputFile::open(StringRef Path) {
+Expected<InputFile> InputFile::open(StringRef Path, bool AllowUnknownFile) {
InputFile IF;
if (!llvm::sys::fs::exists(Path))
return make_error<StringError>(formatv("File {0} not found", Path),
@@ -274,9 +274,19 @@ Expected<InputFile> InputFile::open(Stri
return std::move(IF);
}
- return make_error<StringError>(
- formatv("File {0} is not a supported file type", Path),
- inconvertibleErrorCode());
+ if (!AllowUnknownFile)
+ return make_error<StringError>(
+ formatv("File {0} is not a supported file type", Path),
+ inconvertibleErrorCode());
+
+ auto Result = MemoryBuffer::getFile(Path, -1i64, false);
+ if (!Result)
+ return make_error<StringError>(
+ formatv("File {0} could not be opened", Path), Result.getError());
+
+ IF.UnknownFile = std::move(*Result);
+ IF.PdbOrObj = IF.UnknownFile.get();
+ return std::move(IF);
}
PDBFile &InputFile::pdb() {
@@ -299,6 +309,25 @@ const object::COFFObjectFile &InputFile:
return *PdbOrObj.get<object::COFFObjectFile *>();
}
+MemoryBuffer &InputFile::unknown() {
+ assert(isUnknown());
+ return *PdbOrObj.get<MemoryBuffer *>();
+}
+
+const MemoryBuffer &InputFile::unknown() const {
+ assert(isUnknown());
+ return *PdbOrObj.get<MemoryBuffer *>();
+}
+
+StringRef InputFile::getFilePath() const {
+ if (isPdb())
+ return pdb().getFilePath();
+ if (isObj())
+ return obj().getFileName();
+ assert(isUnknown());
+ return unknown().getBufferIdentifier();
+}
+
bool InputFile::hasTypes() const {
if (isPdb())
return pdb().hasPDBTpiStream();
@@ -323,6 +352,8 @@ bool InputFile::isObj() const {
return PdbOrObj.is<object::COFFObjectFile *>();
}
+bool InputFile::isUnknown() const { return PdbOrObj.is<MemoryBuffer *>(); }
+
codeview::LazyRandomTypeCollection &
InputFile::getOrCreateTypeCollection(TypeCollectionKind Kind) {
if (Types && Kind == kTypes)
Modified: llvm/trunk/tools/llvm-pdbutil/InputFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-pdbutil/InputFile.h?rev=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/InputFile.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/InputFile.h Wed Apr 4 10:29:09 2018
@@ -43,7 +43,8 @@ class InputFile {
std::unique_ptr<NativeSession> PdbSession;
object::OwningBinary<object::Binary> CoffObject;
- PointerUnion<PDBFile *, object::COFFObjectFile *> PdbOrObj;
+ std::unique_ptr<MemoryBuffer> UnknownFile;
+ PointerUnion3<PDBFile *, object::COFFObjectFile *, MemoryBuffer *> PdbOrObj;
using TypeCollectionPtr = std::unique_ptr<codeview::LazyRandomTypeCollection>;
@@ -58,12 +59,17 @@ public:
~InputFile();
InputFile(InputFile &&Other) = default;
- static Expected<InputFile> open(StringRef Path);
+ static Expected<InputFile> open(StringRef Path,
+ bool AllowUnknownFile = false);
PDBFile &pdb();
const PDBFile &pdb() const;
object::COFFObjectFile &obj();
const object::COFFObjectFile &obj() const;
+ MemoryBuffer &unknown();
+ const MemoryBuffer &unknown() const;
+
+ StringRef getFilePath() const;
bool hasTypes() const;
bool hasIds() const;
@@ -77,6 +83,7 @@ public:
bool isPdb() const;
bool isObj() const;
+ bool isUnknown() const;
};
class SymbolGroup {
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=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.cpp Wed Apr 4 10:29:09 2018
@@ -621,6 +621,20 @@ cl::list<std::string> InputFilename(cl::
cl::list<uint64_t> Offsets("offset", cl::desc("The file offset to explain"),
cl::sub(ExplainSubcommand), cl::OneOrMore);
+
+cl::opt<InputFileType> InputType(
+ "input-type", cl::desc("Specify how to interpret the input file"),
+ cl::init(InputFileType::PDBFile), cl::Optional, cl::sub(ExplainSubcommand),
+ cl::values(clEnumValN(InputFileType::PDBFile, "pdb-file",
+ "Treat input as a PDB file (default)"),
+ clEnumValN(InputFileType::PDBStream, "pdb-stream",
+ "Treat input as raw contents of PDB stream"),
+ clEnumValN(InputFileType::DBIStream, "dbi-stream",
+ "Treat input as raw contents of DBI stream"),
+ clEnumValN(InputFileType::Names, "names-stream",
+ "Treat input as raw contents of /names named stream"),
+ clEnumValN(InputFileType::ModuleStream, "mod-stream",
+ "Treat input as raw contents of a module stream")));
} // namespace explain
namespace exportstream {
@@ -772,7 +786,6 @@ static void pdb2Yaml(StringRef Path) {
}
static void dumpRaw(StringRef Path) {
-
InputFile IF = ExitOnErr(InputFile::open(Path));
auto O = llvm::make_unique<DumpOutputStyle>(IF);
@@ -1111,10 +1124,11 @@ static void mergePdbs() {
static void explain() {
std::unique_ptr<IPDBSession> Session;
- PDBFile &File = loadPDB(opts::explain::InputFilename.front(), Session);
+ InputFile IF =
+ ExitOnErr(InputFile::open(opts::explain::InputFilename.front(), true));
for (uint64_t Off : opts::explain::Offsets) {
- auto O = llvm::make_unique<ExplainOutputStyle>(File, Off);
+ auto O = llvm::make_unique<ExplainOutputStyle>(IF, Off);
ExitOnErr(O->dump());
}
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=329207&r1=329206&r2=329207&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h (original)
+++ llvm/trunk/tools/llvm-pdbutil/llvm-pdbutil.h Wed Apr 4 10:29:09 2018
@@ -190,8 +190,11 @@ extern llvm::cl::opt<bool> DumpModuleSym
} // namespace pdb2yaml
namespace explain {
+enum class InputFileType { PDBFile, PDBStream, DBIStream, Names, ModuleStream };
+
extern llvm::cl::list<std::string> InputFilename;
extern llvm::cl::list<uint64_t> Offsets;
+extern llvm::cl::opt<InputFileType> InputType;
} // namespace explain
namespace exportstream {
More information about the llvm-commits
mailing list