diff options
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Raw')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/ByteStream.cpp | 60 | ||||
-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.cpp | 52 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PDBInfoStream.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PDBNameMap.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/StreamReader.cpp | 40 |
6 files changed, 147 insertions, 72 deletions
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(); +} |