diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/ByteStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/ByteStream.h new file mode 100644 index 000000000000..11b9366f73a3 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/ByteStream.h @@ -0,0 +1,47 @@ +//===- ByteStream.h - Reads stream data from a byte sequence ----*- 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_PDB_RAW_BYTESTREAM_H +#define LLVM_DEBUGINFO_PDB_RAW_BYTESTREAM_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/DebugInfo/PDB/Raw/StreamInterface.h" + +#include + +#include +#include + +namespace llvm { +class StreamReader; +class ByteStream : public StreamInterface { +public: + ByteStream(); + explicit ByteStream(MutableArrayRef Bytes); + explicit ByteStream(uint32_t Length); + ~ByteStream() override; + + void reset(); + void initialize(MutableArrayRef Bytes); + void initialize(uint32_t Length); + std::error_code initialize(StreamReader &Reader, uint32_t Length); + + std::error_code readBytes(uint32_t Offset, + MutableArrayRef Buffer) const override; + uint32_t getLength() const override; + + ArrayRef data() const { return Data; } + +private: + MutableArrayRef Data; + bool Owned; +}; +} + +#endif diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h new file mode 100644 index 000000000000..74fae96ffdf3 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/MappedBlockStream.h @@ -0,0 +1,38 @@ +//===- MappedBlockStream.h - Reads stream data from a PDBFile ---*- 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_PDB_RAW_MAPPEDBLOCKSTREAM_H +#define LLVM_DEBUGINFO_PDB_RAW_MAPPEDBLOCKSTREAM_H + +#include "llvm/DebugInfo/PDB/Raw/StreamInterface.h" + +#include + +#include +#include + +namespace llvm { +class PDBFile; + +class MappedBlockStream : public StreamInterface { +public: + MappedBlockStream(uint32_t StreamIdx, const PDBFile &File); + + std::error_code readBytes(uint32_t Offset, + MutableArrayRef Buffer) const override; + uint32_t getLength() const override { return StreamLength; } + +private: + uint32_t StreamLength; + std::vector BlockList; + const PDBFile &Pdb; +}; +} + +#endif diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBDbiStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBDbiStream.h index eac7e4bbb751..0286e36f39f2 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBDbiStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBDbiStream.h @@ -11,9 +11,10 @@ #define LLVM_DEBUGINFO_PDB_RAW_PDBDBISTREAM_H #include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/DebugInfo/PDB/Raw/ByteStream.h" +#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" #include "llvm/DebugInfo/PDB/Raw/PDBRawConstants.h" -#include "llvm/DebugInfo/PDB/Raw/PDBStream.h" #include "llvm/Support/Endian.h" namespace llvm { @@ -46,20 +47,21 @@ public: ArrayRef modules() const; private: - std::error_code readSubstream(std::vector &Bytes, uint32_t Size); std::error_code initializeFileInfo(); PDBFile &Pdb; - PDBStream Stream; + MappedBlockStream Stream; std::vector ModuleInfos; - std::vector ModInfoSubstream; - std::vector SecContrSubstream; - std::vector SecMapSubstream; - std::vector FileInfoSubstream; - std::vector TypeServerMapSubstream; - std::vector ECSubstream; + ByteStream ModInfoSubstream; + ByteStream SecContrSubstream; + ByteStream SecMapSubstream; + ByteStream FileInfoSubstream; + ByteStream TypeServerMapSubstream; + ByteStream ECSubstream; + ByteStream DbgHeader; + std::unique_ptr Header; }; } diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBInfoStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBInfoStream.h index ed914348d9f6..0887c28910ed 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBInfoStream.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBInfoStream.h @@ -12,9 +12,9 @@ #include "llvm/ADT/StringMap.h" #include "llvm/DebugInfo/PDB/PDBTypes.h" +#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Raw/PDBNameMap.h" #include "llvm/DebugInfo/PDB/Raw/PDBRawConstants.h" -#include "llvm/DebugInfo/PDB/Raw/PDBStream.h" #include "llvm/Support/Endian.h" @@ -37,7 +37,7 @@ public: private: PDBFile &Pdb; - PDBStream Stream1; + MappedBlockStream Stream; // PDB file format version. We only support VC70. See the enumeration // `PdbRaw_ImplVer` for the other possible values. diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBNameMap.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBNameMap.h index c747e4996892..3f4aea417671 100644 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBNameMap.h +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBNameMap.h @@ -17,12 +17,12 @@ #include namespace llvm { -class PDBStream; +class StreamReader; class PDBNameMap { public: PDBNameMap(); - std::error_code load(PDBStream &Stream); + std::error_code load(StreamReader &Stream); bool tryGetValue(StringRef Name, uint32_t &Value) const; diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBStream.h b/llvm/include/llvm/DebugInfo/PDB/Raw/PDBStream.h deleted file mode 100644 index 0f71e81cf2e8..000000000000 --- a/llvm/include/llvm/DebugInfo/PDB/Raw/PDBStream.h +++ /dev/null @@ -1,46 +0,0 @@ -//===- PDBStream.h - Low level interface to a PDB 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_PDB_RAW_PDBSTREAM_H -#define LLVM_DEBUGINFO_PDB_RAW_PDBSTREAM_H - -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" - -namespace llvm { - -class MemoryBufferRef; -class PDBFile; - -class PDBStream { -public: - PDBStream(uint32_t StreamIdx, const PDBFile &File); - - std::error_code readInteger(uint32_t &Dest); - std::error_code readZeroString(std::string &Dest); - std::error_code readBytes(void *Dest, uint32_t Length); - - void setOffset(uint32_t Off); - uint32_t getOffset() const; - uint32_t getLength() const; - - template std::error_code readObject(T *Dest) { - return readBytes(reinterpret_cast(Dest), sizeof(T)); - } - -private: - uint32_t Offset; - - uint32_t StreamLength; - std::vector BlockList; - const PDBFile &Pdb; -}; -} - -#endif diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/StreamInterface.h b/llvm/include/llvm/DebugInfo/PDB/Raw/StreamInterface.h new file mode 100644 index 000000000000..6f235049d7e5 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/StreamInterface.h @@ -0,0 +1,29 @@ +//===- StreamInterface.h - Base interface for a PDB 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_PDB_RAW_STREAMINTERFACE_H +#define LLVM_DEBUGINFO_PDB_RAW_STREAMINTERFACE_H + +#include "llvm/ADT/ArrayRef.h" + +#include +#include + +namespace llvm { +class StreamInterface { +public: + virtual ~StreamInterface() {} + + virtual std::error_code readBytes(uint32_t Offset, + MutableArrayRef Buffer) const = 0; + virtual uint32_t getLength() const = 0; +}; +} + +#endif diff --git a/llvm/include/llvm/DebugInfo/PDB/Raw/StreamReader.h b/llvm/include/llvm/DebugInfo/PDB/Raw/StreamReader.h new file mode 100644 index 000000000000..84527ab840f1 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/PDB/Raw/StreamReader.h @@ -0,0 +1,46 @@ +//===- StreamReader.h - Reads bytes and objects from 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_PDB_RAW_STREAMREADER_H +#define LLVM_DEBUGINFO_PDB_RAW_STREAMREADER_H + +#include "llvm/DebugInfo/PDB/Raw/StreamInterface.h" +#include "llvm/Support/Endian.h" + +#include +#include + +namespace llvm { + +class StreamReader { +public: + StreamReader(const StreamInterface &S); + + std::error_code readBytes(MutableArrayRef Buffer); + std::error_code readInteger(uint32_t &Dest); + std::error_code readZeroString(std::string &Dest); + + template std::error_code readObject(T *Dest) { + MutableArrayRef Buffer(reinterpret_cast(Dest), + sizeof(T)); + return readBytes(Buffer); + } + + void setOffset(uint32_t Off) { Offset = Off; } + uint32_t getOffset() const { return Offset; } + uint32_t getLength() const { return Stream.getLength(); } + uint32_t bytesRemaining() const { return getLength() - getOffset(); } + +private: + const StreamInterface &Stream; + uint32_t Offset; +}; +} + +#endif diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index b98c37bfbc8d..93960c8ec316 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 000000000000..20abe4c0d97c --- /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 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(); +} + +void ByteStream::initialize(MutableArrayRef Bytes) { + reset(); + Data = Bytes; + Owned = false; +} + +void ByteStream::initialize(uint32_t Length) { + reset(); + Data = MutableArrayRef(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 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 similarity index 54% rename from llvm/lib/DebugInfo/PDB/Raw/PDBStream.cpp rename to llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp index 6db04a559701..ed954bbed289 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 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(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 9c8b814d2b2b..6c15385a16c3 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 PDBDbiStream::modules() const { return ModuleInfos; } -std::error_code PDBDbiStream::readSubstream(std::vector &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(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 fdf32470e784..90397db45bc2 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 ed469317ee8c..4dd8cf0c7aa5 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 000000000000..707f77f5d732 --- /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 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(); +} diff --git a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp index b91d86857152..45096daf0971 100644 --- a/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp +++ b/llvm/tools/llvm-pdbdump/llvm-pdbdump.cpp @@ -35,12 +35,13 @@ #include "llvm/DebugInfo/PDB/PDBSymbolExe.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolThunk.h" +#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h" #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" #include "llvm/DebugInfo/PDB/Raw/PDBDbiStream.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/DebugInfo/PDB/Raw/PDBInfoStream.h" -#include "llvm/DebugInfo/PDB/Raw/PDBStream.h" #include "llvm/DebugInfo/PDB/Raw/RawSession.h" +#include "llvm/DebugInfo/PDB/Raw/StreamReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/FileSystem.h" @@ -246,17 +247,19 @@ static void dumpStructure(RawSession &RS) { // Let's try to dump out the named stream "/names". uint32_t NameStreamIndex = InfoStream.getNamedStreamIndex("/names"); if (NameStreamIndex != 0) { - PDBStream NameStream(NameStreamIndex, File); + MappedBlockStream NameStream(NameStreamIndex, File); + StreamReader Reader(NameStream); + outs() << "NameStream: " << NameStreamIndex << '\n'; // The name stream appears to start with a signature and version. uint32_t NameStreamSignature; - NameStream.readInteger(NameStreamSignature); + Reader.readInteger(NameStreamSignature); outs() << "NameStreamSignature: "; outs().write_hex(NameStreamSignature) << '\n'; uint32_t NameStreamVersion; - NameStream.readInteger(NameStreamVersion); + Reader.readInteger(NameStreamVersion); outs() << "NameStreamVersion: " << NameStreamVersion << '\n'; // We only support this particular version of the name stream.