Parse the TPI (type information) stream of PDB files.
This parses the TPI stream (stream 2) from the PDB file. This stream
contains some header information followed by a series of codeview records.
There is some additional complexity here in that alongside this stream of
codeview records is a serialized hash table in order to efficiently query
the types. We parse the necessary bookkeeping information to allow us to
reconstruct the hash table, but we do not actually construct it yet as
there are still a few things that need to be understood first.
Differential Revision: http://reviews.llvm.org/D19840
Reviewed By: ruiu, rnk
llvm-svn: 268343
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
index df47ced..05b3dc7 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBFile.cpp
@@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/PDB/Raw/DbiStream.h"
#include "llvm/DebugInfo/PDB/Raw/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -119,6 +120,8 @@
std::error_code PDBFile::parseFileHeaders() {
std::error_code EC;
MemoryBufferRef BufferRef = *Context->Buffer;
+ // Make sure the file is sufficiently large to hold a super block.
+ // Do this before attempting to read the super block.
if (BufferRef.getBufferSize() < sizeof(SuperBlock))
return std::make_error_code(std::errc::illegal_byte_sequence);
@@ -135,10 +138,6 @@
if (BufferRef.getBufferSize() % SB->BlockSize != 0)
return std::make_error_code(std::errc::illegal_byte_sequence);
- // Make sure the file is sufficiently large to hold a super block.
- if (BufferRef.getBufferSize() < sizeof(SuperBlock))
- return std::make_error_code(std::errc::illegal_byte_sequence);
-
// Check the magic bytes.
if (memcmp(SB->MagicBytes, Magic, sizeof(Magic)) != 0)
return std::make_error_code(std::errc::illegal_byte_sequence);
@@ -271,3 +270,11 @@
}
return *Dbi;
}
+
+TpiStream &PDBFile::getPDBTpiStream() {
+ if (!Tpi) {
+ Tpi.reset(new TpiStream(*this));
+ Tpi->reload();
+ }
+ return *Tpi;
+}