static void dumpStreamData(ScopedPrinter &P, PDBFile &File) { uint32_t StreamCount = File.getNumStreams(); StringRef DumpStreamStr = opts::DumpStreamData; uint32_t DumpStreamNum; if (DumpStreamStr.getAsInteger(/*Radix=*/0U, DumpStreamNum) || DumpStreamNum >= StreamCount) return; uint32_t StreamBytesRead = 0; uint32_t StreamSize = File.getStreamByteSize(DumpStreamNum); auto StreamBlocks = File.getStreamBlockList(DumpStreamNum); for (uint32_t StreamBlockAddr : StreamBlocks) { uint32_t BytesLeftToReadInStream = StreamSize - StreamBytesRead; if (BytesLeftToReadInStream == 0) break; uint32_t BytesToReadInBlock = std::min( BytesLeftToReadInStream, static_cast<uint32_t>(File.getBlockSize())); auto StreamBlockData = File.getBlockData(StreamBlockAddr, BytesToReadInBlock); outs() << StreamBlockData; StreamBytesRead += StreamBlockData.size(); } }
static void dumpFileHeaders(ScopedPrinter &P, PDBFile &File) { if (!opts::DumpHeaders) return; DictScope D(P, "FileHeaders"); P.printNumber("BlockSize", File.getBlockSize()); P.printNumber("Unknown0", File.getUnknown0()); P.printNumber("NumBlocks", File.getBlockCount()); P.printNumber("NumDirectoryBytes", File.getNumDirectoryBytes()); P.printNumber("Unknown1", File.getUnknown1()); P.printNumber("BlockMapAddr", File.getBlockMapIndex()); P.printNumber("NumDirectoryBlocks", File.getNumDirectoryBlocks()); P.printNumber("BlockMapOffset", File.getBlockMapOffset()); // The directory is not contiguous. Instead, the block map contains a // contiguous list of block numbers whose contents, when concatenated in // order, make up the directory. P.printList("DirectoryBlocks", File.getDirectoryBlockArray()); P.printNumber("NumStreams", File.getNumStreams()); }