[llvm-pdbutil] Dump raw bytes of various DBI stream subsections.

llvm-svn: 306160
This commit is contained in:
Zachary Turner 2017-06-23 21:11:54 +00:00
parent 9e0d3878fb
commit dd73968256
9 changed files with 249 additions and 27 deletions

View File

@ -63,6 +63,13 @@ public:
PDB_Machine getMachineType() const;
BinarySubstreamRef getSectionContributionData() const;
BinarySubstreamRef getSecMapSubstreamData() const;
BinarySubstreamRef getModiSubstreamData() const;
BinarySubstreamRef getFileInfoSubstreamData() const;
BinarySubstreamRef getTypeServerMapSubstreamData() const;
BinarySubstreamRef getECSubstreamData() const;
/// If the given stream type is present, returns its stream index. If it is
/// not present, returns InvalidStreamIndex.
uint32_t getDebugStreamIndex(DbgHeaderType Type) const;
@ -87,10 +94,12 @@ private:
PDBStringTable ECNames;
BinaryStreamRef SecContrSubstream;
BinaryStreamRef SecMapSubstream;
BinaryStreamRef TypeServerMapSubstream;
BinaryStreamRef ECSubstream;
BinarySubstreamRef SecContrSubstream;
BinarySubstreamRef SecMapSubstream;
BinarySubstreamRef ModiSubstream;
BinarySubstreamRef FileInfoSubstream;
BinarySubstreamRef TypeServerMapSubstream;
BinarySubstreamRef ECSubstream;
DbiModuleList Modules;

View File

@ -169,6 +169,9 @@ public:
struct BinarySubstreamRef {
uint32_t Offset; // Offset in the parent stream
BinaryStreamRef StreamData; // Stream Data
uint32_t size() const { return StreamData.getLength(); }
bool empty() const { return size() == 0; }
};
class WritableBinaryStreamRef

View File

@ -99,29 +99,27 @@ Error DbiStream::reload() {
return make_error<RawError>(raw_error_code::corrupt_file,
"DBI type server substream not aligned.");
BinaryStreamRef ModInfoSubstream;
BinaryStreamRef FileInfoSubstream;
if (auto EC =
Reader.readStreamRef(ModInfoSubstream, Header->ModiSubstreamSize))
if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize))
return EC;
if (auto EC = Reader.readStreamRef(SecContrSubstream,
if (auto EC = Reader.readSubstream(SecContrSubstream,
Header->SecContrSubstreamSize))
return EC;
if (auto EC = Reader.readStreamRef(SecMapSubstream, Header->SectionMapSize))
if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize))
return EC;
if (auto EC = Reader.readStreamRef(FileInfoSubstream, Header->FileInfoSize))
if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize))
return EC;
if (auto EC =
Reader.readStreamRef(TypeServerMapSubstream, Header->TypeServerSize))
Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize))
return EC;
if (auto EC = Reader.readStreamRef(ECSubstream, Header->ECSubstreamSize))
if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize))
return EC;
if (auto EC = Reader.readArray(
DbgStreams, Header->OptionalDbgHdrSize / sizeof(ulittle16_t)))
return EC;
if (auto EC = Modules.initialize(ModInfoSubstream, FileInfoSubstream))
if (auto EC = Modules.initialize(ModiSubstream.StreamData,
FileInfoSubstream.StreamData))
return EC;
if (auto EC = initializeSectionContributionData())
@ -137,8 +135,8 @@ Error DbiStream::reload() {
return make_error<RawError>(raw_error_code::corrupt_file,
"Found unexpected bytes in DBI Stream.");
if (ECSubstream.getLength() > 0) {
BinaryStreamReader ECReader(ECSubstream);
if (!ECSubstream.empty()) {
BinaryStreamReader ECReader(ECSubstream.StreamData);
if (auto EC = ECNames.reload(ECReader))
return EC;
}
@ -228,10 +226,10 @@ void DbiStream::visitSectionContributions(
}
Error DbiStream::initializeSectionContributionData() {
if (SecContrSubstream.getLength() == 0)
if (SecContrSubstream.empty())
return Error::success();
BinaryStreamReader SCReader(SecContrSubstream);
BinaryStreamReader SCReader(SecContrSubstream.StreamData);
if (auto EC = SCReader.readEnum(SectionContribVersion))
return EC;
@ -302,11 +300,33 @@ Error DbiStream::initializeFpoRecords() {
return Error::success();
}
BinarySubstreamRef DbiStream::getSectionContributionData() const {
return SecContrSubstream;
}
BinarySubstreamRef DbiStream::getSecMapSubstreamData() const {
return SecMapSubstream;
}
BinarySubstreamRef DbiStream::getModiSubstreamData() const {
return ModiSubstream;
}
BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const {
return FileInfoSubstream;
}
BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const {
return TypeServerMapSubstream;
}
BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; }
Error DbiStream::initializeSectionMapData() {
if (SecMapSubstream.getLength() == 0)
if (SecMapSubstream.empty())
return Error::success();
BinaryStreamReader SMReader(SecMapSubstream);
BinaryStreamReader SMReader(SecMapSubstream.StreamData);
const SecMapHeader *Header;
if (auto EC = SMReader.readObject(Header))
return EC;

View File

@ -0,0 +1,59 @@
; RUN: llvm-pdbutil bytes -ec %p/Inputs/empty.pdb | FileCheck --check-prefix=EC %s
; RUN: llvm-pdbutil bytes -files %p/Inputs/empty.pdb | FileCheck --check-prefix=FILES %s
; RUN: llvm-pdbutil bytes -modi %p/Inputs/empty.pdb | FileCheck --check-prefix=MODI %s
; RUN: llvm-pdbutil bytes -sc %p/Inputs/empty.pdb | FileCheck --check-prefix=SC %s
; RUN: llvm-pdbutil bytes -sm %p/Inputs/empty.pdb | FileCheck --check-prefix=SM %s
; RUN: llvm-pdbutil bytes -type-server %p/Inputs/empty.pdb | FileCheck --check-prefix=TYPE-SERVER %s
EC: Edit and Continue Data
EC-NEXT: ============================================================
EC-NEXT: Edit and Continue Data (
EC-NEXT: E280: FEEFFEEF 01000000 31000000 00643A5C 7372635C 6C6C766D 5C746573 745C4465 |........1....d:\src\llvm\test\De|
EC-NEXT: E2A0: 62756749 6E666F5C 5044425C 496E7075 74735C65 6D707479 2E706462 00020000 |bugInfo\PDB\Inputs\empty.pdb....|
EC-NEXT: E2C0: 00010000 00000000 00010000 00 |.............|
EC-NEXT: )
FILES: File Info
FILES-NEXT: ============================================================
FILES-NEXT: File Info (
FILES-NEXT: E240: 02000100 00000100 01000000 00000000 643A5C73 72635C6C 6C766D5C 74657374 |................d:\src\llvm\test|
FILES-NEXT: E260: 5C646562 7567696E 666F5C70 64625C69 6E707574 735C656D 7074792E 63707000 |\debuginfo\pdb\inputs\empty.cpp.|
FILES-NEXT: )
MODI: Module Infos
MODI-NEXT: ============================================================
MODI-NEXT: Module Infos (
MODI-NEXT: E040: 00000000 01000000 10000000 0A000000 20005060 00000000 347497D7 00000000 |................ .P`....4t......|
MODI-NEXT: E060: 00000C00 D0000000 00000000 58000000 01000000 D035E900 00000000 00000000 |............X........5..........|
MODI-NEXT: E080: 643A5C73 72635C6C 6C766D5C 74657374 5C446562 7567496E 666F5C50 44425C49 |d:\src\llvm\test\DebugInfo\PDB\I|
MODI-NEXT: E0A0: 6E707574 735C656D 7074792E 6F626A00 643A5C73 72635C6C 6C766D5C 74657374 |nputs\empty.obj.d:\src\llvm\test|
MODI-NEXT: E0C0: 5C446562 7567496E 666F5C50 44425C49 6E707574 735C656D 7074792E 6F626A00 |\DebugInfo\PDB\Inputs\empty.obj.|
MODI-NEXT: E0E0: 00000000 01000000 00000000 0A000000 20000060 01000000 00000000 00000000 |................ ..`............|
MODI-NEXT: E100: 00000E00 04020000 00000000 00000000 00000000 00000000 00000000 01000000 |................................|
MODI-NEXT: E120: 2A204C69 6E6B6572 202A0000 |* Linker *..|
MODI-NEXT: )
SC: Section Contributions
SC-NEXT: ============================================================
SC-NEXT: Section Contributions (
SC-NEXT: E12C: 2DBA2EF1 01002511 00000000 0A000000 20000060 01000000 00000000 00000000 |-.....%......... ..`............|
SC-NEXT: E14C: 01000000 10000000 0A000000 20005060 00000000 347497D7 00000000 02000000 |............ .P`....4t..........|
SC-NEXT: E16C: 00000000 38000000 40000040 01000000 00000000 00000000 02000000 44010000 |....8...@..@................D...|
SC-NEXT: E18C: 48000000 40003040 01000000 00000000 00000000 02000000 8C010000 14000000 |H...@.0@........................|
SC-NEXT: E1AC: 40003040 01000000 00000000 00000000 03000000 00000000 04000000 800030C0 |@.0@..........................0.|
SC-NEXT: E1CC: 00000000 00000000 00000000 |............|
SC-NEXT: )
SM: Section Map
SM-NEXT: ============================================================
SM-NEXT: Section Map (
SM-NEXT: E1D8: 05000500 0D010000 00000100 FFFFFFFF 00000000 1A100000 09010000 00000200 |................................|
SM-NEXT: E1F8: FFFFFFFF 00000000 B2020000 0B010000 00000300 FFFFFFFF 00000000 04000000 |................................|
SM-NEXT: E218: 09010000 00000400 FFFFFFFF 00000000 08000000 08020000 00000000 FFFFFFFF |................................|
SM-NEXT: E238: 00000000 FFFFFFFF |........|
SM-NEXT: )
TYPE-SERVER: Type Server Map
TYPE-SERVER-NEXT: ============================================================
TYPE-SERVER-NEXT: Type Server Map (
TYPE-SERVER-NEXT: )

View File

@ -13,6 +13,7 @@
#include "llvm-pdbutil.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/RawError.h"
@ -122,6 +123,37 @@ Error BytesOutputStyle::dump() {
dumpNameMap();
P.NewLine();
}
if (opts::bytes::SectionContributions) {
dumpSectionContributions();
P.NewLine();
}
if (opts::bytes::SectionMap) {
dumpSectionMap();
P.NewLine();
}
if (opts::bytes::ModuleInfos) {
dumpModuleInfos();
P.NewLine();
}
if (opts::bytes::FileInfo) {
dumpFileInfo();
P.NewLine();
}
if (opts::bytes::TypeServerMap) {
dumpTypeServerMap();
P.NewLine();
}
if (opts::bytes::ECData) {
dumpECData();
P.NewLine();
}
return Error::success();
}
@ -155,6 +187,72 @@ void BytesOutputStyle::dumpBlockRanges(uint32_t Min, uint32_t Max) {
}
}
void BytesOutputStyle::dumpSectionContributions() {
printHeader(P, "Section Contributions");
AutoIndent Indent(P);
auto &DbiS = Err(File.getPDBDbiStream());
BinarySubstreamRef NS = DbiS.getSectionContributionData();
auto Layout = File.getStreamLayout(StreamDBI);
P.formatMsfStreamData("Section Contributions", File, Layout, NS);
}
void BytesOutputStyle::dumpSectionMap() {
printHeader(P, "Section Map");
AutoIndent Indent(P);
auto &DbiS = Err(File.getPDBDbiStream());
BinarySubstreamRef NS = DbiS.getSecMapSubstreamData();
auto Layout = File.getStreamLayout(StreamDBI);
P.formatMsfStreamData("Section Map", File, Layout, NS);
}
void BytesOutputStyle::dumpModuleInfos() {
printHeader(P, "Module Infos");
AutoIndent Indent(P);
auto &DbiS = Err(File.getPDBDbiStream());
BinarySubstreamRef NS = DbiS.getModiSubstreamData();
auto Layout = File.getStreamLayout(StreamDBI);
P.formatMsfStreamData("Module Infos", File, Layout, NS);
}
void BytesOutputStyle::dumpFileInfo() {
printHeader(P, "File Info");
AutoIndent Indent(P);
auto &DbiS = Err(File.getPDBDbiStream());
BinarySubstreamRef NS = DbiS.getFileInfoSubstreamData();
auto Layout = File.getStreamLayout(StreamDBI);
P.formatMsfStreamData("File Info", File, Layout, NS);
}
void BytesOutputStyle::dumpTypeServerMap() {
printHeader(P, "Type Server Map");
AutoIndent Indent(P);
auto &DbiS = Err(File.getPDBDbiStream());
BinarySubstreamRef NS = DbiS.getTypeServerMapSubstreamData();
auto Layout = File.getStreamLayout(StreamDBI);
P.formatMsfStreamData("Type Server Map", File, Layout, NS);
}
void BytesOutputStyle::dumpECData() {
printHeader(P, "Edit and Continue Data");
AutoIndent Indent(P);
auto &DbiS = Err(File.getPDBDbiStream());
BinarySubstreamRef NS = DbiS.getECSubstreamData();
auto Layout = File.getStreamLayout(StreamDBI);
P.formatMsfStreamData("Edit and Continue Data", File, Layout, NS);
}
void BytesOutputStyle::dumpByteRanges(uint32_t Min, uint32_t Max) {
printHeader(P, "MSF Bytes");

View File

@ -33,6 +33,13 @@ private:
void dumpByteRanges(uint32_t Min, uint32_t Max);
void dumpStreamBytes();
void dumpSectionContributions();
void dumpSectionMap();
void dumpModuleInfos();
void dumpFileInfo();
void dumpTypeServerMap();
void dumpECData();
PDBFile &File;
LinePrinter P;
ExitOnError Err;

View File

@ -146,18 +146,19 @@ static std::vector<Run> computeBlockRuns(uint32_t BlockSize,
ArrayRef<support::ulittle32_t> Blocks = Layout.Blocks;
assert(!Blocks.empty());
uint32_t StreamBytesRemaining = Layout.Length;
Runs.emplace_back(Blocks[0]);
uint32_t CurrentBlock = Blocks[0];
Runs.emplace_back(CurrentBlock);
while (!Blocks.empty()) {
Run *CurrentRun = &Runs.back();
uint32_t NextBlock = Blocks.front();
if (NextBlock < CurrentRun->Block || (NextBlock - CurrentRun->Block > 1)) {
if (NextBlock < CurrentBlock || (NextBlock - CurrentBlock > 1)) {
Runs.emplace_back(NextBlock);
CurrentRun = &Runs.back();
}
uint32_t Used = std::min(BlockSize, StreamBytesRemaining);
CurrentRun->ByteLen += Used;
StreamBytesRemaining -= Used;
CurrentBlock = NextBlock;
Blocks = Blocks.drop_front();
}
return Runs;

View File

@ -267,27 +267,44 @@ cl::list<std::string> InputFilenames(cl::Positional,
cl::OptionCategory FileOptions("Module & File Options");
namespace bytes {
cl::OptionCategory MsfBytes("MSF File Options");
cl::OptionCategory DbiBytes("Dbi Stream Options");
cl::OptionCategory PdbBytes("PDB Stream Options");
llvm::Optional<NumberRange> DumpBlockRange;
llvm::Optional<NumberRange> DumpByteRange;
cl::opt<std::string> DumpBlockRangeOpt(
"block-range", cl::value_desc("start[-end]"),
cl::desc("Dump binary data from specified range of blocks."),
cl::sub(BytesSubcommand));
cl::sub(BytesSubcommand), cl::cat(MsfBytes));
cl::opt<std::string>
DumpByteRangeOpt("byte-range", cl::value_desc("start[-end]"),
cl::desc("Dump binary data from specified range of bytes"),
cl::sub(BytesSubcommand));
cl::sub(BytesSubcommand), cl::cat(MsfBytes));
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::sub(BytesSubcommand), cl::cat(MsfBytes));
cl::opt<bool> NameMap("name-map", cl::desc("Dump bytes of PDB Name Map"),
cl::sub(BytesSubcommand));
cl::sub(BytesSubcommand), cl::cat(PdbBytes));
cl::opt<bool> SectionContributions("sc", cl::desc("Dump section contributions"),
cl::sub(BytesSubcommand), cl::cat(DbiBytes));
cl::opt<bool> SectionMap("sm", cl::desc("Dump section map"),
cl::sub(BytesSubcommand), cl::cat(DbiBytes));
cl::opt<bool> ModuleInfos("modi", cl::desc("Dump module info"),
cl::sub(BytesSubcommand), cl::cat(DbiBytes));
cl::opt<bool> FileInfo("files", cl::desc("Dump source file info"),
cl::sub(BytesSubcommand), cl::cat(DbiBytes));
cl::opt<bool> TypeServerMap("type-server", cl::desc("Dump type server map"),
cl::sub(BytesSubcommand), cl::cat(DbiBytes));
cl::opt<bool> ECData("ec", cl::desc("Dump edit and continue map"),
cl::sub(BytesSubcommand), cl::cat(DbiBytes));
cl::list<std::string> InputFilenames(cl::Positional,
cl::desc("<input PDB files>"),

View File

@ -102,6 +102,14 @@ extern llvm::Optional<NumberRange> DumpBlockRange;
extern llvm::Optional<NumberRange> DumpByteRange;
extern llvm::cl::list<std::string> DumpStreamData;
extern llvm::cl::opt<bool> NameMap;
extern llvm::cl::opt<bool> SectionContributions;
extern llvm::cl::opt<bool> SectionMap;
extern llvm::cl::opt<bool> ModuleInfos;
extern llvm::cl::opt<bool> FileInfo;
extern llvm::cl::opt<bool> TypeServerMap;
extern llvm::cl::opt<bool> ECData;
} // namespace bytes
namespace dump {