summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-04-29 17:22:58 +0000
committerZachary Turner <zturner@google.com>2016-04-29 17:22:58 +0000
commit6ba65deeb9b017e4144cdae341dcb9e3564c7c7b (patch)
tree7b038a1cbb48d78056d0af5bd76f9a3ad44ea9d6 /llvm/lib
parenteaaec4a4c85a81ee9169e1647b733d839159c648 (diff)
downloadbcm5719-llvm-6ba65deeb9b017e4144cdae341dcb9e3564c7c7b.tar.gz
bcm5719-llvm-6ba65deeb9b017e4144cdae341dcb9e3564c7c7b.zip
Refactor the PDB Stream reading interface.
The motivation for this change is that PDB has the notion of streams and substreams. Substreams often consist of variable length structures that are convenient to be able to treat as guaranteed, contiguous byte arrays, whereas the streams they are contained in are not necessarily so, as a single stream could be spread across many discontiguous blocks. So, when processing data from a substream, we want to be able to assume that we have a contiguous byte array so that we can cast pointers to variable length arrays and such. This leads to the question of how to be able to read the same data structure from either a stream or a substream using the same interface, which is where this patch comes in. We separate out the stream's read state from the underlying representation, and introduce a `StreamReader` class. Then we change the name of `PDBStream` to `MappedBlockStream`, and introduce a second kind of stream called a `ByteStream` which is simply a sequence of contiguous bytes. Finally, we update all of the std::vectors in `PDBDbiStream` to use `ByteStream` instead as a proof of concept. llvm-svn: 268071
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt6
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ByteStream.cpp60
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp (renamed from llvm/lib/DebugInfo/PDB/Raw/PDBStream.cpp)46
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBDbiStream.cpp52
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp16
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp5
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/StreamReader.cpp40
7 files changed, 151 insertions, 74 deletions
diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
index b98c37bfbc8..93960c8ec31 100644
--- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt
+++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt
@@ -27,13 +27,15 @@ if(HAVE_DIA_SDK)
endif()
add_pdb_impl_folder(Raw
+ Raw/ByteStream.cpp
+ Raw/MappedBlockStream.cpp
Raw/ModInfo.cpp
Raw/PDBFile.cpp
Raw/PDBDbiStream.cpp
Raw/PDBInfoStream.cpp
Raw/PDBNameMap.cpp
- Raw/PDBStream.cpp
- Raw/RawSession.cpp)
+ Raw/RawSession.cpp
+ Raw/StreamReader.cpp)
list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB")
diff --git a/llvm/lib/DebugInfo/PDB/Raw/ByteStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ByteStream.cpp
new file mode 100644
index 00000000000..20abe4c0d97
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Raw/ByteStream.cpp
@@ -0,0 +1,60 @@
+//===- ByteStream.cpp - Reads stream data from a byte sequence ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Raw/ByteStream.h"
+#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
+
+using namespace llvm;
+
+ByteStream::ByteStream() : Owned(false) {}
+
+ByteStream::ByteStream(MutableArrayRef<uint8_t> Bytes) : Owned(false) {
+ initialize(Bytes);
+}
+
+ByteStream::ByteStream(uint32_t Length) : Owned(false) { initialize(Length); }
+
+ByteStream::~ByteStream() { reset(); }
+
+void ByteStream::reset() {
+ if (Owned)
+ delete[] Data.data();
+ Owned = false;
+ Data = MutableArrayRef<uint8_t>();
+}
+
+void ByteStream::initialize(MutableArrayRef<uint8_t> Bytes) {
+ reset();
+ Data = Bytes;
+ Owned = false;
+}
+
+void ByteStream::initialize(uint32_t Length) {
+ reset();
+ Data = MutableArrayRef<uint8_t>(new uint8_t[Length], Length);
+ Owned = true;
+}
+
+std::error_code ByteStream::initialize(StreamReader &Reader, uint32_t Length) {
+ initialize(Length);
+ std::error_code EC = Reader.readBytes(Data);
+ if (EC)
+ reset();
+ return EC;
+}
+
+std::error_code ByteStream::readBytes(uint32_t Offset,
+ MutableArrayRef<uint8_t> Buffer) const {
+ if (Data.size() < Buffer.size() + Offset)
+ return std::make_error_code(std::errc::bad_address);
+ ::memcpy(Buffer.data(), Data.data() + Offset, Buffer.size());
+ return std::error_code();
+}
+
+uint32_t ByteStream::getLength() const { return Data.size(); }
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp
index 6db04a55970..ed954bbed28 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp
@@ -1,4 +1,4 @@
-//===- PDBStream.cpp - Low level interface to a PDB stream ------*- C++ -*-===//
+//===- MappedBlockStream.cpp - Reads stream data from a PDBFile -----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -7,48 +7,31 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/PDB/Raw/PDBStream.h"
+#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
using namespace llvm;
-PDBStream::PDBStream(uint32_t StreamIdx, const PDBFile &File) : Pdb(File) {
+MappedBlockStream::MappedBlockStream(uint32_t StreamIdx, const PDBFile &File) : Pdb(File) {
StreamLength = Pdb.getStreamByteSize(StreamIdx);
BlockList = Pdb.getStreamBlockList(StreamIdx);
- Offset = 0;
}
-std::error_code PDBStream::readInteger(uint32_t &Dest) {
- support::ulittle32_t P;
- if (std::error_code EC = readObject(&P))
- return EC;
- Dest = P;
- return std::error_code();
-}
-
-std::error_code PDBStream::readZeroString(std::string &Dest) {
- char C;
- do {
- readObject(&C);
- if (C != '\0')
- Dest.push_back(C);
- } while (C != '\0');
- return std::error_code();
-}
-
-std::error_code PDBStream::readBytes(void *Dest, uint32_t Length) {
+std::error_code
+MappedBlockStream::readBytes(uint32_t Offset,
+ MutableArrayRef<uint8_t> Buffer) const {
uint32_t BlockNum = Offset / Pdb.getBlockSize();
uint32_t OffsetInBlock = Offset % Pdb.getBlockSize();
// Make sure we aren't trying to read beyond the end of the stream.
- if (Length > StreamLength)
+ if (Buffer.size() > StreamLength)
return std::make_error_code(std::errc::bad_address);
- if (Offset > StreamLength - Length)
+ if (Offset > StreamLength - Buffer.size())
return std::make_error_code(std::errc::bad_address);
- uint32_t BytesLeft = Length;
+ uint32_t BytesLeft = Buffer.size();
uint32_t BytesWritten = 0;
- char *WriteBuffer = static_cast<char *>(Dest);
+ uint8_t *WriteBuffer = Buffer.data();
while (BytesLeft > 0) {
uint32_t StreamBlockAddr = BlockList[BlockNum];
@@ -65,14 +48,5 @@ std::error_code PDBStream::readBytes(void *Dest, uint32_t Length) {
OffsetInBlock = 0;
}
- // Modify the offset to point to the data after the object.
- Offset += Length;
-
return std::error_code();
}
-
-void PDBStream::setOffset(uint32_t O) { Offset = O; }
-
-uint32_t PDBStream::getOffset() const { return Offset; }
-
-uint32_t PDBStream::getLength() const { return StreamLength; }
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBDbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBDbiStream.cpp
index 9c8b814d2b2..6c15385a16c 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBDbiStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBDbiStream.cpp
@@ -12,6 +12,7 @@
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/PDBInfoStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBRawConstants.h"
+#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
using namespace llvm;
using namespace llvm::support;
@@ -58,12 +59,12 @@ struct PDBDbiStream::HeaderInfo {
little32_t SecContrSubstreamSize; // Size of sec. contribution stream
little32_t SectionMapSize; // Size of sec. map substream
little32_t FileInfoSize; // Size of file info substream
- little32_t TypeServerSize; // Size of type server map
- ulittle32_t MFCTypeServerIndex; // Index of MFC Type Server
- little32_t OptionalDbgHdrSize; // Size of DbgHeader info
- little32_t ECSubstreamSize; // Size of EC stream (what is EC?)
- ulittle16_t Flags; // See DbiFlags enum.
- ulittle16_t MachineType; // See PDB_MachineType enum.
+ little32_t TypeServerSize; // Size of type server map
+ ulittle32_t MFCTypeServerIndex; // Index of MFC Type Server
+ little32_t OptionalDbgHdrSize; // Size of DbgHeader info
+ little32_t ECSubstreamSize; // Size of EC stream (what is EC?)
+ ulittle16_t Flags; // See DbiFlags enum.
+ ulittle16_t MachineType; // See PDB_MachineType enum.
ulittle32_t Reserved; // Pad to 64 bytes
};
@@ -75,12 +76,13 @@ PDBDbiStream::PDBDbiStream(PDBFile &File) : Pdb(File), Stream(3, File) {
PDBDbiStream::~PDBDbiStream() {}
std::error_code PDBDbiStream::reload() {
- Stream.setOffset(0);
+ StreamReader Reader(Stream);
+
Header.reset(new HeaderInfo());
if (Stream.getLength() < sizeof(HeaderInfo))
return std::make_error_code(std::errc::illegal_byte_sequence);
- Stream.readObject(Header.get());
+ Reader.readObject(Header.get());
if (Header->VersionSignature != -1)
return std::make_error_code(std::errc::illegal_byte_sequence);
@@ -115,30 +117,35 @@ std::error_code PDBDbiStream::reload() {
return std::make_error_code(std::errc::illegal_byte_sequence);
std::error_code EC;
- if ((EC = readSubstream(ModInfoSubstream, Header->ModiSubstreamSize)))
- return EC;
+ ModInfoSubstream.initialize(Reader, Header->ModiSubstreamSize);
// Since each ModInfo in the stream is a variable length, we have to iterate
// them to know how many there actually are.
- auto Range = llvm::make_range(ModInfoIterator(&ModInfoSubstream.front()),
- ModInfoIterator(&ModInfoSubstream.back() + 1));
+ auto Range =
+ llvm::make_range(ModInfoIterator(&ModInfoSubstream.data().front()),
+ ModInfoIterator(&ModInfoSubstream.data().back() + 1));
for (auto Info : Range)
ModuleInfos.push_back(ModuleInfoEx(Info));
- if ((EC = readSubstream(SecContrSubstream, Header->SecContrSubstreamSize)))
+ if ((EC = SecContrSubstream.initialize(Reader, Header->SecContrSubstreamSize)))
return EC;
- if ((EC = readSubstream(SecMapSubstream, Header->SectionMapSize)))
+ if ((EC = SecMapSubstream.initialize(Reader, Header->SectionMapSize)))
return EC;
- if ((EC = readSubstream(FileInfoSubstream, Header->FileInfoSize)))
+ if ((EC = FileInfoSubstream.initialize(Reader, Header->FileInfoSize)))
return EC;
- if ((EC = readSubstream(TypeServerMapSubstream, Header->TypeServerSize)))
+ if ((EC = TypeServerMapSubstream.initialize(Reader, Header->TypeServerSize)))
return EC;
- if ((EC = readSubstream(ECSubstream, Header->ECSubstreamSize)))
+ if ((EC = ECSubstream.initialize(Reader, Header->ECSubstreamSize)))
+ return EC;
+ if ((EC = DbgHeader.initialize(Reader, Header->OptionalDbgHdrSize)))
return EC;
if ((EC = initializeFileInfo()))
return EC;
+ if (Reader.bytesRemaining() > 0)
+ return std::make_error_code(std::errc::illegal_byte_sequence);
+
return std::error_code();
}
@@ -182,15 +189,6 @@ PDB_Machine PDBDbiStream::getMachineType() const {
ArrayRef<ModuleInfoEx> PDBDbiStream::modules() const { return ModuleInfos; }
-std::error_code PDBDbiStream::readSubstream(std::vector<uint8_t> &Bytes, uint32_t Size) {
- Bytes.clear();
- if (Size == 0)
- return std::error_code();
-
- Bytes.resize(Size);
- return Stream.readBytes(&Bytes[0], Size);
-}
-
std::error_code PDBDbiStream::initializeFileInfo() {
struct FileInfoSubstreamHeader {
ulittle16_t NumModules; // Total # of modules, should match number of
@@ -213,7 +211,7 @@ std::error_code PDBDbiStream::initializeFileInfo() {
// with the caveat that `NumSourceFiles` cannot be trusted, so
// it is computed by summing `ModFileCounts`.
//
- const uint8_t *Buf = &FileInfoSubstream[0];
+ const uint8_t *Buf = &FileInfoSubstream.data().front();
auto FI = reinterpret_cast<const FileInfoSubstreamHeader *>(Buf);
Buf += sizeof(FileInfoSubstreamHeader);
// The number of modules in the stream should be the same as reported by
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp
index fdf32470e78..90397db45bc 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp
@@ -10,28 +10,30 @@
#include "llvm/DebugInfo/PDB/Raw/PDBInfoStream.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
using namespace llvm;
-PDBInfoStream::PDBInfoStream(PDBFile &File) : Pdb(File), Stream1(1, File) {}
+PDBInfoStream::PDBInfoStream(PDBFile &File) : Pdb(File), Stream(1, File) {}
std::error_code PDBInfoStream::reload() {
- Stream1.setOffset(0);
+ StreamReader Reader(Stream);
+
support::ulittle32_t Value;
- Stream1.readObject(&Value);
+ Reader.readObject(&Value);
Version = Value;
if (Version < PdbRaw_ImplVer::PdbImplVC70)
return std::make_error_code(std::errc::not_supported);
- Stream1.readObject(&Value);
+ Reader.readObject(&Value);
Signature = Value;
- Stream1.readObject(&Value);
+ Reader.readObject(&Value);
Age = Value;
- Stream1.readObject(&Guid);
- NamedStreams.load(Stream1);
+ Reader.readObject(&Guid);
+ NamedStreams.load(Reader);
return std::error_code();
}
diff --git a/llvm/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp b/llvm/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp
index ed469317ee8..4dd8cf0c7aa 100644
--- a/llvm/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp
+++ b/llvm/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp
@@ -9,13 +9,14 @@
#include "llvm/DebugInfo/PDB/Raw/PDBNameMap.h"
#include "llvm/ADT/BitVector.h"
-#include "llvm/DebugInfo/PDB/Raw/PDBStream.h"
+#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
using namespace llvm;
PDBNameMap::PDBNameMap() {}
-std::error_code PDBNameMap::load(PDBStream &Stream) {
+std::error_code PDBNameMap::load(StreamReader &Stream) {
+
// This is some sort of weird string-set/hash table encoded in the stream.
// It starts with the number of bytes in the table.
uint32_t NumberOfBytes;
diff --git a/llvm/lib/DebugInfo/PDB/Raw/StreamReader.cpp b/llvm/lib/DebugInfo/PDB/Raw/StreamReader.cpp
new file mode 100644
index 00000000000..707f77f5d73
--- /dev/null
+++ b/llvm/lib/DebugInfo/PDB/Raw/StreamReader.cpp
@@ -0,0 +1,40 @@
+//===- StreamReader.cpp - Reads bytes and objects from a stream -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Raw/StreamReader.h"
+
+using namespace llvm;
+
+StreamReader::StreamReader(const StreamInterface &S) : Stream(S), Offset(0) {}
+
+std::error_code StreamReader::readBytes(MutableArrayRef<uint8_t> Buffer) {
+ if (auto EC = Stream.readBytes(Offset, Buffer))
+ return EC;
+ Offset += Buffer.size();
+ return std::error_code();
+}
+
+std::error_code StreamReader::readInteger(uint32_t &Dest) {
+ support::ulittle32_t P;
+ if (std::error_code EC = readObject(&P))
+ return EC;
+ Dest = P;
+ return std::error_code();
+}
+
+std::error_code StreamReader::readZeroString(std::string &Dest) {
+ Dest.clear();
+ char C;
+ do {
+ readObject(&C);
+ if (C != '\0')
+ Dest.push_back(C);
+ } while (C != '\0');
+ return std::error_code();
+}
OpenPOWER on IntegriCloud