aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2017-08-02 22:25:52 +0000
committerZachary Turner <zturner@google.com>2017-08-02 22:25:52 +0000
commit34173def44aa86280505e4d06661d763c64d15c7 (patch)
tree9ca95c9782350e3d3a717ebcd29c27f61e37ed00
parentcd14d227ff2bc8503b80ad02a22b081684c199c2 (diff)
[pdbutil] Add a command to dump the FPM.
Recently problems have been discovered in the way we write the FPM (free page map). In order to fix this, we first need to establish a baseline about what a correct FPM looks like using an MSVC generated PDB, so that we can then make our own generated PDBs match. And in order to do this, the dumper needs a mode where it can dump an FPM so that we can write tests for it. This patch adds a command to dump the FPM, as well as a test against a known-good PDB. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309894 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/DebugInfo/MSF/MSFCommon.h17
-rw-r--r--include/llvm/DebugInfo/MSF/MSFStreamLayout.h35
-rw-r--r--include/llvm/DebugInfo/MSF/MappedBlockStream.h2
-rw-r--r--include/llvm/DebugInfo/PDB/Native/PDBFile.h5
-rw-r--r--lib/DebugInfo/MSF/MSFCommon.cpp15
-rw-r--r--lib/DebugInfo/MSF/MappedBlockStream.cpp20
-rw-r--r--lib/DebugInfo/PDB/Native/PDBFile.cpp4
-rw-r--r--test/DebugInfo/PDB/dump-fpm.test9
-rw-r--r--tools/llvm-pdbutil/BytesOutputStyle.cpp13
-rw-r--r--tools/llvm-pdbutil/BytesOutputStyle.h1
-rw-r--r--tools/llvm-pdbutil/LinePrinter.cpp25
-rw-r--r--tools/llvm-pdbutil/LinePrinter.h1
-rw-r--r--tools/llvm-pdbutil/llvm-pdbutil.cpp2
-rw-r--r--tools/llvm-pdbutil/llvm-pdbutil.h2
-rw-r--r--unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp1
15 files changed, 92 insertions, 60 deletions
diff --git a/include/llvm/DebugInfo/MSF/MSFCommon.h b/include/llvm/DebugInfo/MSF/MSFCommon.h
index eca1b8b89eb..458de415ee1 100644
--- a/include/llvm/DebugInfo/MSF/MSFCommon.h
+++ b/include/llvm/DebugInfo/MSF/MSFCommon.h
@@ -59,6 +59,23 @@ struct MSFLayout {
std::vector<ArrayRef<support::ulittle32_t>> StreamMap;
};
+/// \brief Describes the layout of a stream in an MSF layout. A "stream" here
+/// is defined as any logical unit of data which may be arranged inside the MSF
+/// file as a sequence of (possibly discontiguous) blocks. When we want to read
+/// from a particular MSF Stream, we fill out a stream layout structure and the
+/// reader uses it to determine which blocks in the underlying MSF file contain
+/// the data, so that it can be pieced together in the right order.
+class MSFStreamLayout {
+public:
+ uint32_t Length;
+ std::vector<support::ulittle32_t> Blocks;
+};
+
+/// \brief Determine the layout of the FPM stream, given the MSF layout. An FPM
+/// stream spans 1 or more blocks, each at equally spaced intervals throughout
+/// the file.
+MSFStreamLayout getFpmStreamLayout(const MSFLayout &Msf);
+
inline bool isValidBlockSize(uint32_t Size) {
switch (Size) {
case 512:
diff --git a/include/llvm/DebugInfo/MSF/MSFStreamLayout.h b/include/llvm/DebugInfo/MSF/MSFStreamLayout.h
deleted file mode 100644
index bdde98f5266..00000000000
--- a/include/llvm/DebugInfo/MSF/MSFStreamLayout.h
+++ /dev/null
@@ -1,35 +0,0 @@
-//===- MSFStreamLayout.h - Describes the layout of a stream -----*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_DEBUGINFO_MSF_MSFSTREAMLAYOUT_H
-#define LLVM_DEBUGINFO_MSF_MSFSTREAMLAYOUT_H
-
-#include "llvm/Support/Endian.h"
-
-#include <cstdint>
-#include <vector>
-
-namespace llvm {
-namespace msf {
-
-/// \brief Describes the layout of a stream in an MSF layout. A "stream" here
-/// is defined as any logical unit of data which may be arranged inside the MSF
-/// file as a sequence of (possibly discontiguous) blocks. When we want to read
-/// from a particular MSF Stream, we fill out a stream layout structure and the
-/// reader uses it to determine which blocks in the underlying MSF file contain
-/// the data, so that it can be pieced together in the right order.
-class MSFStreamLayout {
-public:
- uint32_t Length;
- std::vector<support::ulittle32_t> Blocks;
-};
-} // namespace msf
-} // namespace llvm
-
-#endif // LLVM_DEBUGINFO_MSF_MSFSTREAMLAYOUT_H
diff --git a/include/llvm/DebugInfo/MSF/MappedBlockStream.h b/include/llvm/DebugInfo/MSF/MappedBlockStream.h
index 6d88d2be85c..6cb07d26836 100644
--- a/include/llvm/DebugInfo/MSF/MappedBlockStream.h
+++ b/include/llvm/DebugInfo/MSF/MappedBlockStream.h
@@ -12,7 +12,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryStream.h"
#include "llvm/Support/BinaryStreamRef.h"
diff --git a/include/llvm/DebugInfo/PDB/Native/PDBFile.h b/include/llvm/DebugInfo/PDB/Native/PDBFile.h
index 4f6ad115e7d..a785ff3d928 100644
--- a/include/llvm/DebugInfo/PDB/Native/PDBFile.h
+++ b/include/llvm/DebugInfo/PDB/Native/PDBFile.h
@@ -13,7 +13,6 @@
#include "llvm/ADT/DenseMap.h"
#include "llvm/DebugInfo/MSF/IMSFFile.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
-#include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/BinaryStreamRef.h"
#include "llvm/Support/Endian.h"
@@ -72,8 +71,6 @@ public:
Error setBlockData(uint32_t BlockIndex, uint32_t Offset,
ArrayRef<uint8_t> Data) const override;
- ArrayRef<uint32_t> getFpmPages() const { return FpmPages; }
-
ArrayRef<support::ulittle32_t> getStreamSizes() const {
return ContainerLayout.StreamSizes;
}
@@ -87,6 +84,7 @@ public:
ArrayRef<support::ulittle32_t> getDirectoryBlockArray() const;
msf::MSFStreamLayout getStreamLayout(uint32_t StreamIdx) const;
+ msf::MSFStreamLayout getFpmStreamLayout() const;
Error parseFileHeaders();
Error parseStreamData();
@@ -124,7 +122,6 @@ private:
std::unique_ptr<BinaryStream> Buffer;
- std::vector<uint32_t> FpmPages;
msf::MSFLayout ContainerLayout;
std::unique_ptr<GlobalsStream> Globals;
diff --git a/lib/DebugInfo/MSF/MSFCommon.cpp b/lib/DebugInfo/MSF/MSFCommon.cpp
index 1facf5efb4b..484e1845ce2 100644
--- a/lib/DebugInfo/MSF/MSFCommon.cpp
+++ b/lib/DebugInfo/MSF/MSFCommon.cpp
@@ -59,3 +59,18 @@ Error llvm::msf::validateSuperBlock(const SuperBlock &SB) {
return Error::success();
}
+
+MSFStreamLayout llvm::msf::getFpmStreamLayout(const MSFLayout &Msf) {
+ MSFStreamLayout FL;
+ uint32_t NumFpmIntervals = getNumFpmIntervals(Msf);
+ support::ulittle32_t FpmBlock = Msf.SB->FreeBlockMapBlock;
+ assert(FpmBlock == 1 || FpmBlock == 2);
+ while (NumFpmIntervals > 0) {
+ FL.Blocks.push_back(FpmBlock);
+ FpmBlock += msf::getFpmIntervalLength(Msf);
+ --NumFpmIntervals;
+ }
+ FL.Length = getFullFpmByteSize(Msf);
+
+ return FL;
+}
diff --git a/lib/DebugInfo/MSF/MappedBlockStream.cpp b/lib/DebugInfo/MSF/MappedBlockStream.cpp
index e45f4ae0ed9..2a200edeaf7 100644
--- a/lib/DebugInfo/MSF/MappedBlockStream.cpp
+++ b/lib/DebugInfo/MSF/MappedBlockStream.cpp
@@ -11,7 +11,6 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
-#include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/MathExtras.h"
@@ -36,19 +35,6 @@ public:
} // end anonymous namespace
-static void initializeFpmStreamLayout(const MSFLayout &Layout,
- MSFStreamLayout &FpmLayout) {
- uint32_t NumFpmIntervals = msf::getNumFpmIntervals(Layout);
- support::ulittle32_t FpmBlock = Layout.SB->FreeBlockMapBlock;
- assert(FpmBlock == 1 || FpmBlock == 2);
- while (NumFpmIntervals > 0) {
- FpmLayout.Blocks.push_back(FpmBlock);
- FpmBlock += msf::getFpmIntervalLength(Layout);
- --NumFpmIntervals;
- }
- FpmLayout.Length = msf::getFullFpmByteSize(Layout);
-}
-
using Interval = std::pair<uint32_t, uint32_t>;
static Interval intersect(const Interval &I1, const Interval &I2) {
@@ -95,8 +81,7 @@ std::unique_ptr<MappedBlockStream>
MappedBlockStream::createFpmStream(const MSFLayout &Layout,
BinaryStreamRef MsfData,
BumpPtrAllocator &Allocator) {
- MSFStreamLayout SL;
- initializeFpmStreamLayout(Layout, SL);
+ MSFStreamLayout SL(getFpmStreamLayout(Layout));
return createStream(Layout.SB->BlockSize, SL, MsfData, Allocator);
}
@@ -363,8 +348,7 @@ std::unique_ptr<WritableMappedBlockStream>
WritableMappedBlockStream::createFpmStream(const MSFLayout &Layout,
WritableBinaryStreamRef MsfData,
BumpPtrAllocator &Allocator) {
- MSFStreamLayout SL;
- initializeFpmStreamLayout(Layout, SL);
+ MSFStreamLayout SL(getFpmStreamLayout(Layout));
return createStream(Layout.SB->BlockSize, SL, MsfData, Allocator);
}
diff --git a/lib/DebugInfo/PDB/Native/PDBFile.cpp b/lib/DebugInfo/PDB/Native/PDBFile.cpp
index f19e70ee8e3..e0bb460d21c 100644
--- a/lib/DebugInfo/PDB/Native/PDBFile.cpp
+++ b/lib/DebugInfo/PDB/Native/PDBFile.cpp
@@ -238,6 +238,10 @@ MSFStreamLayout PDBFile::getStreamLayout(uint32_t StreamIdx) const {
return Result;
}
+msf::MSFStreamLayout PDBFile::getFpmStreamLayout() const {
+ return msf::getFpmStreamLayout(ContainerLayout);
+}
+
Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
if (!Globals) {
auto DbiS = getPDBDbiStream();
diff --git a/test/DebugInfo/PDB/dump-fpm.test b/test/DebugInfo/PDB/dump-fpm.test
new file mode 100644
index 00000000000..8e37c0c7b27
--- /dev/null
+++ b/test/DebugInfo/PDB/dump-fpm.test
@@ -0,0 +1,9 @@
+RUN: llvm-pdbutil bytes -fpm %p/Inputs/empty.pdb | FileCheck %s
+
+CHECK: Free Page Map
+CHECK-NEXT: ============================================================
+CHECK-NEXT: Block 2 (
+CHECK-NEXT: 2000: 380300FE FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |8...............................|
+CHECK-NEXT: 2020: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................................|
+CHECK: 2FE0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................................|
+CHECK-NEXT: )
diff --git a/tools/llvm-pdbutil/BytesOutputStyle.cpp b/tools/llvm-pdbutil/BytesOutputStyle.cpp
index 9e5a28c2b98..a50da5c580b 100644
--- a/tools/llvm-pdbutil/BytesOutputStyle.cpp
+++ b/tools/llvm-pdbutil/BytesOutputStyle.cpp
@@ -15,6 +15,7 @@
#include "llvm/DebugInfo/CodeView/Formatters.h"
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
@@ -120,6 +121,11 @@ Error BytesOutputStyle::dump() {
P.NewLine();
}
+ if (opts::bytes::Fpm) {
+ dumpFpm();
+ P.NewLine();
+ }
+
if (!opts::bytes::DumpStreamData.empty()) {
dumpStreamBytes();
P.NewLine();
@@ -480,6 +486,13 @@ BytesOutputStyle::initializeTypes(uint32_t StreamIdx) {
return *TypeCollection;
}
+void BytesOutputStyle::dumpFpm() {
+ printHeader(P, "Free Page Map");
+
+ msf::MSFStreamLayout FpmLayout = File.getFpmStreamLayout();
+ P.formatMsfStreamBlocks(File, FpmLayout);
+}
+
void BytesOutputStyle::dumpStreamBytes() {
if (StreamPurposes.empty())
discoverStreamPurposes(File, StreamPurposes);
diff --git a/tools/llvm-pdbutil/BytesOutputStyle.h b/tools/llvm-pdbutil/BytesOutputStyle.h
index c162163fdd0..876178d56ab 100644
--- a/tools/llvm-pdbutil/BytesOutputStyle.h
+++ b/tools/llvm-pdbutil/BytesOutputStyle.h
@@ -35,6 +35,7 @@ private:
void dumpNameMap();
void dumpBlockRanges(uint32_t Min, uint32_t Max);
void dumpByteRanges(uint32_t Min, uint32_t Max);
+ void dumpFpm();
void dumpStreamBytes();
void dumpSectionContributions();
diff --git a/tools/llvm-pdbutil/LinePrinter.cpp b/tools/llvm-pdbutil/LinePrinter.cpp
index 6e4d95af944..e80a1762450 100644
--- a/tools/llvm-pdbutil/LinePrinter.cpp
+++ b/tools/llvm-pdbutil/LinePrinter.cpp
@@ -13,7 +13,6 @@
#include "llvm/ADT/STLExtras.h"
#include "llvm/DebugInfo/MSF/MSFCommon.h"
-#include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/UDTLayout.h"
@@ -246,6 +245,30 @@ void LinePrinter::formatMsfStreamData(StringRef Label, PDBFile &File,
OS << ")";
}
+void LinePrinter::formatMsfStreamBlocks(
+ PDBFile &File, const msf::MSFStreamLayout &StreamLayout) {
+ auto Blocks = makeArrayRef(StreamLayout.Blocks);
+ uint32_t L = StreamLayout.Length;
+
+ while (L > 0) {
+ NewLine();
+ assert(!Blocks.empty());
+ OS << formatv("Block {0} (\n", uint32_t(Blocks.front()));
+ uint32_t UsedBytes = std::min(L, File.getBlockSize());
+ ArrayRef<uint8_t> BlockData =
+ cantFail(File.getBlockData(Blocks.front(), File.getBlockSize()));
+ uint64_t BaseOffset = Blocks.front();
+ BaseOffset *= File.getBlockSize();
+ OS << format_bytes_with_ascii(BlockData, BaseOffset, 32, 4,
+ CurrentIndent + IndentSpaces, true);
+ NewLine();
+ OS << ")";
+ NewLine();
+ L -= UsedBytes;
+ Blocks = Blocks.drop_front();
+ }
+}
+
bool LinePrinter::IsTypeExcluded(llvm::StringRef TypeName, uint32_t Size) {
if (IsItemExcluded(TypeName, IncludeTypeFilters, ExcludeTypeFilters))
return true;
diff --git a/tools/llvm-pdbutil/LinePrinter.h b/tools/llvm-pdbutil/LinePrinter.h
index 68ce321a27e..a831dbd9e6e 100644
--- a/tools/llvm-pdbutil/LinePrinter.h
+++ b/tools/llvm-pdbutil/LinePrinter.h
@@ -60,6 +60,7 @@ public:
void formatMsfStreamData(StringRef Label, PDBFile &File,
const msf::MSFStreamLayout &Stream,
BinarySubstreamRef Substream);
+ void formatMsfStreamBlocks(PDBFile &File, const msf::MSFStreamLayout &Stream);
bool hasColor() const { return UseColor; }
raw_ostream &getStream() { return OS; }
diff --git a/tools/llvm-pdbutil/llvm-pdbutil.cpp b/tools/llvm-pdbutil/llvm-pdbutil.cpp
index aae5de2b95c..99766870ebe 100644
--- a/tools/llvm-pdbutil/llvm-pdbutil.cpp
+++ b/tools/llvm-pdbutil/llvm-pdbutil.cpp
@@ -342,6 +342,8 @@ cl::list<std::string>
cl::opt<bool> NameMap("name-map", cl::desc("Dump bytes of PDB Name Map"),
cl::sub(BytesSubcommand), cl::cat(PdbBytes));
+cl::opt<bool> Fpm("fpm", cl::desc("Dump free page map"),
+ cl::sub(BytesSubcommand), cl::cat(MsfBytes));
cl::opt<bool> SectionContributions("sc", cl::desc("Dump section contributions"),
cl::sub(BytesSubcommand), cl::cat(DbiBytes));
diff --git a/tools/llvm-pdbutil/llvm-pdbutil.h b/tools/llvm-pdbutil/llvm-pdbutil.h
index 0c01fae911c..e4e9a4a5de1 100644
--- a/tools/llvm-pdbutil/llvm-pdbutil.h
+++ b/tools/llvm-pdbutil/llvm-pdbutil.h
@@ -102,6 +102,7 @@ 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> Fpm;
extern llvm::cl::opt<bool> SectionContributions;
extern llvm::cl::opt<bool> SectionMap;
@@ -123,6 +124,7 @@ extern llvm::cl::opt<bool> SplitChunks;
namespace dump {
extern llvm::cl::opt<bool> DumpSummary;
+extern llvm::cl::opt<bool> DumpFpm;
extern llvm::cl::opt<bool> DumpStreams;
extern llvm::cl::opt<bool> DumpStreamBlocks;
diff --git a/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp b/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp
index a9a1ee4d65b..59c8c4b714c 100644
--- a/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp
+++ b/unittests/DebugInfo/PDB/MappedBlockStreamTest.cpp
@@ -10,7 +10,6 @@
#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
#include "llvm/DebugInfo/MSF/IMSFFile.h"
#include "llvm/DebugInfo/MSF/MSFError.h"
-#include "llvm/DebugInfo/MSF/MSFStreamLayout.h"
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/BinaryStreamRef.h"