diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/DebugInfo/CodeView/ByteStream.cpp | 27 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/CodeView/StreamReader.cpp | 66 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp | 85 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp | 14 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp | 85 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp | 77 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp | 8 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp | 30 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp | 13 |
13 files changed, 244 insertions, 175 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/ByteStream.cpp b/llvm/lib/DebugInfo/CodeView/ByteStream.cpp index 879343afbfd..1ea976b6a26 100644 --- a/llvm/lib/DebugInfo/CodeView/ByteStream.cpp +++ b/llvm/lib/DebugInfo/CodeView/ByteStream.cpp @@ -17,31 +17,24 @@ using namespace llvm::codeview; ByteStream::ByteStream() {} -ByteStream::ByteStream(MutableArrayRef<uint8_t> Bytes) { initialize(Bytes); } +ByteStream::ByteStream(MutableArrayRef<uint8_t> Data) : Data(Data) {} -ByteStream::ByteStream(uint32_t Length) { initialize(Length); } - -ByteStream::~ByteStream() { reset(); } +ByteStream::~ByteStream() {} void ByteStream::reset() { Ownership.reset(); Data = MutableArrayRef<uint8_t>(); } -void ByteStream::initialize(MutableArrayRef<uint8_t> Bytes) { - reset(); - Data = Bytes; -} - -void ByteStream::initialize(uint32_t Length) { +void ByteStream::load(uint32_t Length) { reset(); if (Length > 0) Data = MutableArrayRef<uint8_t>(new uint8_t[Length], Length); Ownership.reset(Data.data()); } -Error ByteStream::initialize(StreamReader &Reader, uint32_t Length) { - initialize(Length); +Error ByteStream::load(StreamReader &Reader, uint32_t Length) { + load(Length); auto EC = Reader.readBytes(Data); if (EC) reset(); @@ -52,15 +45,15 @@ Error ByteStream::readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer) const { if (Data.size() < Buffer.size() + Offset) return make_error<CodeViewError>(cv_error_code::insufficient_buffer); - ::memcpy(Buffer.data(), Data.data() + Offset, Buffer.size()); + ::memcpy(Buffer.data() + Offset, Data.data(), Buffer.size()); return Error::success(); } -Error ByteStream::getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer, - uint32_t Length) const { - if (Data.size() < Length + Offset) +Error ByteStream::readBytes(uint32_t Offset, uint32_t Size, + ArrayRef<uint8_t> &Buffer) const { + if (Data.size() < Buffer.size() + Offset) return make_error<CodeViewError>(cv_error_code::insufficient_buffer); - Buffer = Data.slice(Offset, Length); + Buffer = Data.slice(Offset, Size); return Error::success(); } diff --git a/llvm/lib/DebugInfo/CodeView/StreamReader.cpp b/llvm/lib/DebugInfo/CodeView/StreamReader.cpp index 8a2926bc883..64985bfd0e2 100644 --- a/llvm/lib/DebugInfo/CodeView/StreamReader.cpp +++ b/llvm/lib/DebugInfo/CodeView/StreamReader.cpp @@ -10,12 +10,20 @@ #include "llvm/DebugInfo/CodeView/StreamReader.h" #include "llvm/DebugInfo/CodeView/CodeViewError.h" +#include "llvm/DebugInfo/CodeView/StreamRef.h" using namespace llvm; using namespace llvm::codeview; StreamReader::StreamReader(const StreamInterface &S) : Stream(S), Offset(0) {} +Error StreamReader::readBytes(uint32_t Size, ArrayRef<uint8_t> &Buffer) { + if (auto EC = Stream.readBytes(Offset, Size, Buffer)) + return EC; + Offset += Size; + return Error::success(); +} + Error StreamReader::readBytes(MutableArrayRef<uint8_t> Buffer) { if (auto EC = Stream.readBytes(Offset, Buffer)) return EC; @@ -23,29 +31,63 @@ Error StreamReader::readBytes(MutableArrayRef<uint8_t> Buffer) { return Error::success(); } +Error StreamReader::readInteger(uint16_t &Dest) { + const support::ulittle16_t *P; + if (auto EC = readObject(P)) + return EC; + Dest = *P; + return Error::success(); +} + Error StreamReader::readInteger(uint32_t &Dest) { - support::ulittle32_t P; - if (auto EC = readObject(&P)) + const support::ulittle32_t *P; + if (auto EC = readObject(P)) return EC; - Dest = P; + Dest = *P; return Error::success(); } -Error StreamReader::readZeroString(std::string &Dest) { - Dest.clear(); - char C; +Error StreamReader::readZeroString(StringRef &Dest) { + uint32_t Length = 0; + // First compute the length of the string by reading 1 byte at a time. + uint32_t OriginalOffset = getOffset(); + const char *C; do { - if (auto EC = readObject(&C)) + if (auto EC = readObject(C)) return EC; - if (C != '\0') - Dest.push_back(C); - } while (C != '\0'); + if (*C != '\0') + ++Length; + } while (*C != '\0'); + // Now go back and request a reference for that many bytes. + uint32_t NewOffset = getOffset(); + setOffset(OriginalOffset); + + ArrayRef<uint8_t> Data; + if (auto EC = readBytes(Length, Data)) + return EC; + Dest = StringRef(reinterpret_cast<const char *>(Data.begin()), Data.size()); + + // Now set the offset back to where it was after we calculated the length. + setOffset(NewOffset); return Error::success(); } -Error StreamReader::getArrayRef(ArrayRef<uint8_t> &Array, uint32_t Length) { - if (auto EC = Stream.getArrayRef(Offset, Array, Length)) +Error StreamReader::readFixedString(StringRef &Dest, uint32_t Length) { + ArrayRef<uint8_t> Bytes; + if (auto EC = readBytes(Length, Bytes)) return EC; + Dest = StringRef(reinterpret_cast<const char *>(Bytes.begin()), Bytes.size()); + return Error::success(); +} + +Error StreamReader::readStreamRef(StreamRef &Ref) { + return readStreamRef(Ref, bytesRemaining()); +} + +Error StreamReader::readStreamRef(StreamRef &Ref, uint32_t Length) { + if (bytesRemaining() < Length) + return make_error<CodeViewError>(cv_error_code::insufficient_buffer); + Ref = StreamRef(Stream, Offset, Length); Offset += Length; return Error::success(); } diff --git a/llvm/lib/DebugInfo/PDB/CMakeLists.txt b/llvm/lib/DebugInfo/PDB/CMakeLists.txt index 113a2ad0ec4..0938c0762c8 100644 --- a/llvm/lib/DebugInfo/PDB/CMakeLists.txt +++ b/llvm/lib/DebugInfo/PDB/CMakeLists.txt @@ -42,6 +42,7 @@ add_pdb_impl_folder(Raw Raw/SymbolStream.cpp Raw/TpiStream.cpp) +list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB/Raw") list(APPEND LIBPDB_ADDITIONAL_HEADER_DIRS "${LLVM_MAIN_INCLUDE_DIR}/llvm/DebugInfo/PDB") add_llvm_library(LLVMDebugInfoPDB diff --git a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp index 078384ebae3..35937574645 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp @@ -6,9 +6,9 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// - #include "llvm/DebugInfo/PDB/Raw/DbiStream.h" +#include "llvm/DebugInfo/CodeView/StreamArray.h" #include "llvm/DebugInfo/CodeView/StreamReader.h" #include "llvm/DebugInfo/PDB/Raw/InfoStream.h" #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" @@ -73,7 +73,8 @@ struct DbiStream::HeaderInfo { ulittle32_t Reserved; // Pad to 64 bytes }; -DbiStream::DbiStream(PDBFile &File) : Pdb(File), Stream(StreamDBI, File) { +DbiStream::DbiStream(PDBFile &File) + : Pdb(File), Stream(StreamDBI, File), Header(nullptr) { static_assert(sizeof(HeaderInfo) == 64, "Invalid HeaderInfo size!"); } @@ -82,12 +83,10 @@ DbiStream::~DbiStream() {} Error DbiStream::reload() { codeview::StreamReader Reader(Stream); - Header.reset(new HeaderInfo()); - if (Stream.getLength() < sizeof(HeaderInfo)) return make_error<RawError>(raw_error_code::corrupt_file, "DBI Stream does not contain a header."); - if (auto EC = Reader.readObject(Header.get())) + if (auto EC = Reader.readObject(Header)) return make_error<RawError>(raw_error_code::corrupt_file, "DBI Stream does not contain a header."); @@ -137,30 +136,31 @@ Error DbiStream::reload() { return make_error<RawError>(raw_error_code::corrupt_file, "DBI type server substream not aligned."); - if (auto EC = ModInfoSubstream.initialize(Reader, Header->ModiSubstreamSize)) + if (auto EC = + Reader.readStreamRef(ModInfoSubstream, Header->ModiSubstreamSize)) return EC; // 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.data().front()), - ModInfoIterator(&ModInfoSubstream.data().back() + 1)); - for (auto Info : Range) - ModuleInfos.push_back(ModuleInfoEx(Info)); + codeview::VarStreamArray ModInfoArray(ModInfoSubstream, ModInfoRecordLength); + for (auto Info : ModInfoArray) { + ModuleInfos.emplace_back(Info); + } - if (auto EC = - SecContrSubstream.initialize(Reader, Header->SecContrSubstreamSize)) + if (auto EC = Reader.readStreamRef(SecContrSubstream, + Header->SecContrSubstreamSize)) return EC; - if (auto EC = SecMapSubstream.initialize(Reader, Header->SectionMapSize)) + if (auto EC = Reader.readStreamRef(SecMapSubstream, Header->SectionMapSize)) return EC; - if (auto EC = FileInfoSubstream.initialize(Reader, Header->FileInfoSize)) + if (auto EC = Reader.readStreamRef(FileInfoSubstream, Header->FileInfoSize)) return EC; if (auto EC = - TypeServerMapSubstream.initialize(Reader, Header->TypeServerSize)) + Reader.readStreamRef(TypeServerMapSubstream, Header->TypeServerSize)) return EC; - if (auto EC = ECSubstream.initialize(Reader, Header->ECSubstreamSize)) + if (auto EC = Reader.readStreamRef(ECSubstream, Header->ECSubstreamSize)) return EC; - if (auto EC = DbgHeader.initialize(Reader, Header->OptionalDbgHdrSize)) + if (auto EC = Reader.readArray(DbgStreams, Header->OptionalDbgHdrSize / + sizeof(ulittle16_t))) return EC; if (auto EC = initializeFileInfo()) @@ -247,25 +247,30 @@ Error DbiStream::initializeFileInfo() { // with the caveat that `NumSourceFiles` cannot be trusted, so // it is computed by summing `ModFileCounts`. // - const uint8_t *Buf = &FileInfoSubstream.data().front(); - auto FI = reinterpret_cast<const FileInfoSubstreamHeader *>(Buf); - Buf += sizeof(FileInfoSubstreamHeader); + const FileInfoSubstreamHeader *FH; + codeview::StreamReader FISR(FileInfoSubstream); + if (auto EC = FISR.readObject(FH)) + return EC; + // The number of modules in the stream should be the same as reported by // the FileInfoSubstreamHeader. - if (FI->NumModules != ModuleInfos.size()) + if (FH->NumModules != ModuleInfos.size()) return make_error<RawError>(raw_error_code::corrupt_file, "FileInfo substream count doesn't match DBI."); + codeview::FixedStreamArray<ulittle16_t> ModIndexArray; + codeview::FixedStreamArray<ulittle16_t> ModFileCountArray; + codeview::FixedStreamArray<little32_t> FileNameOffsets; + // First is an array of `NumModules` module indices. This is not used for the // same reason that `NumSourceFiles` is not used. It's an array of uint16's, // but it's possible there are more than 64k source files, which would imply // more than 64k modules (e.g. object files) as well. So we ignore this // field. - llvm::ArrayRef<ulittle16_t> ModIndexArray( - reinterpret_cast<const ulittle16_t *>(Buf), ModuleInfos.size()); - - llvm::ArrayRef<ulittle16_t> ModFileCountArray(ModIndexArray.end(), - ModuleInfos.size()); + if (auto EC = FISR.readArray(ModIndexArray, ModuleInfos.size())) + return EC; + if (auto EC = FISR.readArray(ModFileCountArray, ModuleInfos.size())) + return EC; // Compute the real number of source files. uint32_t NumSourceFiles = 0; @@ -280,11 +285,13 @@ Error DbiStream::initializeFileInfo() { // them in `ModuleInfoEx`. The value written to and read from the file is // not used anyway, it is only there as a way to store the offsets for the // purposes of later accessing the names at runtime. - llvm::ArrayRef<little32_t> FileNameOffsets( - reinterpret_cast<const little32_t *>(ModFileCountArray.end()), - NumSourceFiles); + if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles)) + return EC; - const char *Names = reinterpret_cast<const char *>(FileNameOffsets.end()); + codeview::StreamRef NamesBufferRef; + if (auto EC = FISR.readStreamRef(NamesBufferRef)) + return EC; + codeview::StreamReader Names(NamesBufferRef); // We go through each ModuleInfo, determine the number N of source files for // that module, and then get the next N offsets from the Offsets array, using @@ -295,8 +302,10 @@ Error DbiStream::initializeFileInfo() { uint32_t NumFiles = ModFileCountArray[I]; ModuleInfos[I].SourceFiles.resize(NumFiles); for (size_t J = 0; J < NumFiles; ++J, ++NextFileIndex) { - uint32_t FileIndex = FileNameOffsets[NextFileIndex]; - ModuleInfos[I].SourceFiles[J] = StringRef(Names + FileIndex); + uint32_t FileOffset = FileNameOffsets[NextFileIndex]; + Names.setOffset(FileOffset); + if (auto EC = Names.readZeroString(ModuleInfos[I].SourceFiles[J])) + return EC; } } @@ -304,13 +313,5 @@ Error DbiStream::initializeFileInfo() { } uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const { - ArrayRef<uint8_t> DbgData; - if (auto EC = DbgHeader.getArrayRef(0, DbgData, DbgHeader.getLength())) { - consumeError(std::move(EC)); - return uint32_t(-1); - } - ArrayRef<ulittle16_t> DebugStreams( - reinterpret_cast<const ulittle16_t *>(DbgData.data()), - DbgData.size() / sizeof(ulittle16_t)); - return DebugStreams[static_cast<uint16_t>(Type)]; + return DbgStreams[static_cast<uint16_t>(Type)]; } diff --git a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp index e7c8a831c73..64d8319efe1 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp @@ -29,19 +29,19 @@ Error InfoStream::reload() { PDB_UniqueId Guid; }; - Header H; - if (auto EC = Reader.readObject(&H)) + const Header *H; + if (auto EC = Reader.readObject(H)) return make_error<RawError>(raw_error_code::corrupt_file, "PDB Stream does not contain a header."); - if (H.Version < PdbRaw_ImplVer::PdbImplVC70) + if (H->Version < PdbRaw_ImplVer::PdbImplVC70) return make_error<RawError>(raw_error_code::corrupt_file, "Unsupported PDB stream version."); - Version = H.Version; - Signature = H.Signature; - Age = H.Age; - Guid = H.Guid; + Version = H->Version; + Signature = H->Signature; + Age = H->Age; + Guid = H->Guid; return NamedStreams.load(Reader); } diff --git a/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp index 09d71985031..a3db147f57e 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp @@ -23,6 +23,69 @@ MappedBlockStream::MappedBlockStream(uint32_t StreamIdx, const PDBFile &File) : } } +Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size, + ArrayRef<uint8_t> &Buffer) const { + // Make sure we aren't trying to read beyond the end of the stream. + if (Buffer.size() > StreamLength) + return make_error<RawError>(raw_error_code::insufficient_buffer); + if (Offset > StreamLength - Buffer.size()) + return make_error<RawError>(raw_error_code::insufficient_buffer); + + if (tryReadContiguously(Offset, Size, Buffer)) + return Error::success(); + + auto CacheIter = CacheMap.find(Offset); + if (CacheIter != CacheMap.end()) { + // In a more general solution, we would need to guarantee that the + // cached allocation is at least the requested size. In practice, since + // these are CodeView / PDB records, we know they are always formatted + // the same way and never change, so we should never be requesting two + // allocations from the same address with different sizes. + Buffer = ArrayRef<uint8_t>(CacheIter->second, Size); + return Error::success(); + } + + // Otherwise allocate a large enough buffer in the pool, memcpy the data + // into it, and return an ArrayRef to that. + uint8_t *WriteBuffer = Pool.Allocate<uint8_t>(Size); + + if (auto EC = readBytes(Offset, MutableArrayRef<uint8_t>(WriteBuffer, Size))) + return EC; + CacheMap.insert(std::make_pair(Offset, WriteBuffer)); + Buffer = ArrayRef<uint8_t>(WriteBuffer, Size); + return Error::success(); +} + +bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size, + ArrayRef<uint8_t> &Buffer) const { + // Attempt to fulfill the request with a reference directly into the stream. + // This can work even if the request crosses a block boundary, provided that + // all subsequent blocks are contiguous. For example, a 10k read with a 4k + // block size can be filled with a reference if, from the starting offset, + // 3 blocks in a row are contiguous. + uint32_t BlockNum = Offset / Pdb.getBlockSize(); + uint32_t OffsetInBlock = Offset % Pdb.getBlockSize(); + uint32_t BytesFromFirstBlock = + std::min(Size, Pdb.getBlockSize() - OffsetInBlock); + uint32_t NumAdditionalBlocks = + llvm::alignTo(Size - BytesFromFirstBlock, Pdb.getBlockSize()) / + Pdb.getBlockSize(); + + uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1; + uint32_t E = BlockList[BlockNum]; + for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) { + if (BlockList[I + BlockNum] != E) + return false; + } + + uint32_t FirstBlockAddr = BlockList[BlockNum]; + StringRef Str = Pdb.getBlockData(FirstBlockAddr, Pdb.getBlockSize()); + Str = Str.drop_front(OffsetInBlock); + Buffer = + ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(Str.data()), Size); + return true; +} + Error MappedBlockStream::readBytes(uint32_t Offset, MutableArrayRef<uint8_t> Buffer) const { uint32_t BlockNum = Offset / Pdb.getBlockSize(); @@ -54,27 +117,5 @@ Error MappedBlockStream::readBytes(uint32_t Offset, } return Error::success(); -} -Error MappedBlockStream::getArrayRef(uint32_t Offset, ArrayRef<uint8_t> &Buffer, - uint32_t Length) const { - uint32_t BlockNum = Offset / Pdb.getBlockSize(); - uint32_t OffsetInBlock = Offset % Pdb.getBlockSize(); - uint32_t BytesAvailableInBlock = Pdb.getBlockSize() - OffsetInBlock; - - // If this is the last block in the stream, not all of the data is valid. - if (BlockNum == BlockList.size() - 1) { - uint32_t AllocatedBytesInBlock = StreamLength % Pdb.getBlockSize(); - if (AllocatedBytesInBlock < BytesAvailableInBlock) - BytesAvailableInBlock = AllocatedBytesInBlock; - } - if (BytesAvailableInBlock < Length) - return make_error<RawError>(raw_error_code::feature_unsupported); - - uint32_t StreamBlockAddr = BlockList[BlockNum]; - StringRef Data = Pdb.getBlockData(StreamBlockAddr, Pdb.getBlockSize()); - Data = Data.substr(OffsetInBlock, Length); - - Buffer = ArrayRef<uint8_t>(Data.bytes_begin(), Data.bytes_end()); - return Error::success(); } diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp index 362c402c09b..9ccb7edd696 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp @@ -8,6 +8,8 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/PDB/Raw/ModInfo.h" + +#include "llvm/DebugInfo/CodeView/StreamReader.h" #include "llvm/DebugInfo/PDB/Raw/PDBFile.h" #include "llvm/Support/Endian.h" @@ -16,6 +18,7 @@ using namespace llvm::pdb; using namespace llvm::support; namespace { + struct SCBytes { ulittle16_t Section; char Padding1[2]; @@ -60,17 +63,29 @@ struct ModInfo::FileLayout { // for now since it is unused. ulittle32_t SrcFileNameNI; // Name Index for src file name ulittle32_t PdbFilePathNI; // Name Index for path to compiler PDB - char VarInfo[1]; // Module name followed by Obj File Name - - StringRef getModuleName() const { return StringRef(VarInfo); } + // Null terminated Module name + // Null terminated Obj File Name +}; - StringRef getObjectFileName() const { - return StringRef(getModuleName().end() + 1); +ModInfo::ModInfo(codeview::StreamRef Stream) : Layout(nullptr) { + codeview::StreamReader Reader(Stream); + if (auto EC = Reader.readObject(Layout)) { + consumeError(std::move(EC)); + return; } -}; + if (auto EC = Reader.readZeroString(ModuleName)) { + consumeError(std::move(EC)); + return; + } + if (auto EC = Reader.readZeroString(ObjFileName)) { + consumeError(std::move(EC)); + return; + } +} -ModInfo::ModInfo(const uint8_t *Bytes) - : Layout(reinterpret_cast<const FileLayout *>(Bytes)) {} +ModInfo::ModInfo(const ModInfo &Info) + : ModuleName(Info.ModuleName), ObjFileName(Info.ObjFileName), + Layout(Info.Layout) {} ModInfo::~ModInfo() {} @@ -100,44 +115,14 @@ uint32_t ModInfo::getPdbFilePathNameIndex() const { return Layout->PdbFilePathNI; } -llvm::StringRef ModInfo::getModuleName() const { - return Layout->getModuleName(); -} - -llvm::StringRef ModInfo::getObjFileName() const { - return Layout->getObjectFileName(); -} - -ModInfoIterator::ModInfoIterator(const uint8_t *Stream) : Bytes(Stream) {} - -ModInfoIterator::ModInfoIterator(const ModInfoIterator &Other) - : Bytes(Other.Bytes) {} - -ModInfo ModInfoIterator::operator*() { return ModInfo(Bytes); } - -ModInfoIterator &ModInfoIterator::operator++() { - StringRef Obj = ModInfo(Bytes).getObjFileName(); - Bytes = Obj.bytes_end() + 1; - Bytes = reinterpret_cast<const uint8_t *>(llvm::alignAddr(Bytes, 4)); - - return *this; -} +StringRef ModInfo::getModuleName() const { return ModuleName; } -ModInfoIterator ModInfoIterator::operator++(int) { - ModInfoIterator Copy(*this); - ++(*this); - return Copy; -} - -bool ModInfoIterator::operator==(const ModInfoIterator &Other) { - return Bytes == Other.Bytes; -} - -bool ModInfoIterator::operator!=(const ModInfoIterator &Other) { - return !(*this == Other); -} +StringRef ModInfo::getObjFileName() const { return ObjFileName; } -ModInfoIterator &ModInfoIterator::operator=(const ModInfoIterator &Other) { - Bytes = Other.Bytes; - return *this; +uint32_t ModInfo::getRecordLength() const { + uint32_t M = ModuleName.str().size() + 1; + uint32_t O = ObjFileName.str().size() + 1; + uint32_t Size = sizeof(FileLayout) + M + O; + Size = llvm::alignTo(Size, 4); + return Size; } diff --git a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp index c359e7757d0..38d3f2f23e3 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp @@ -32,17 +32,17 @@ Error ModStream::reload() { return llvm::make_error<RawError>(raw_error_code::corrupt_file, "Module has both C11 and C13 line info"); - if (auto EC = SymbolsSubstream.initialize(Reader, SymbolSize)) + if (auto EC = SymbolsSubstream.load(Reader, SymbolSize)) return EC; - if (auto EC = LinesSubstream.initialize(Reader, C11Size)) + if (auto EC = Reader.readStreamRef(LinesSubstream, C11Size)) return EC; - if (auto EC = C13LinesSubstream.initialize(Reader, C13Size)) + if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size)) return EC; uint32_t GlobalRefsSize; if (auto EC = Reader.readInteger(GlobalRefsSize)) return EC; - if (auto EC = GlobalRefsSubstream.initialize(Reader, GlobalRefsSize)) + if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize)) return EC; if (Reader.bytesRemaining() > 0) return llvm::make_error<RawError>(raw_error_code::corrupt_file, diff --git a/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp b/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp index a542a51b188..7eae7489a0e 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp @@ -84,28 +84,28 @@ Error NameHashTable::load(codeview::StreamReader &Stream) { support::ulittle32_t ByteSize; }; - Header H; - if (auto EC = Stream.readObject(&H)) + const Header *H; + if (auto EC = Stream.readObject(H)) return EC; - if (H.Signature != 0xEFFEEFFE) + if (H->Signature != 0xEFFEEFFE) return make_error<RawError>(raw_error_code::corrupt_file, "Invalid hash table signature"); - if (H.HashVersion != 1 && H.HashVersion != 2) + if (H->HashVersion != 1 && H->HashVersion != 2) return make_error<RawError>(raw_error_code::corrupt_file, "Unsupported hash version"); - Signature = H.Signature; - HashVersion = H.HashVersion; - if (auto EC = NamesBuffer.initialize(Stream, H.ByteSize)) + Signature = H->Signature; + HashVersion = H->HashVersion; + if (auto EC = Stream.readStreamRef(NamesBuffer, H->ByteSize)) return make_error<RawError>(raw_error_code::corrupt_file, "Invalid hash table byte length"); - support::ulittle32_t HashCount; - if (auto EC = Stream.readObject(&HashCount)) + const support::ulittle32_t *HashCount; + if (auto EC = Stream.readObject(HashCount)) return EC; - std::vector<support::ulittle32_t> BucketArray(HashCount); + std::vector<support::ulittle32_t> BucketArray(*HashCount); if (auto EC = Stream.readArray<support::ulittle32_t>(BucketArray)) return make_error<RawError>(raw_error_code::corrupt_file, "Could not read bucket array"); @@ -124,7 +124,15 @@ StringRef NameHashTable::getStringForID(uint32_t ID) const { if (ID == IDs[0]) return StringRef(); - return StringRef(NamesBuffer.str().begin() + ID); + // NamesBuffer is a buffer of null terminated strings back to back. ID is + // the starting offset of the string we're looking for. So just seek into + // the desired offset and a read a null terminated stream from that offset. + StringRef Result; + codeview::StreamReader NameReader(NamesBuffer); + NameReader.setOffset(ID); + if (auto EC = NameReader.readZeroString(Result)) + consumeError(std::move(EC)); + return Result; } uint32_t NameHashTable::getIDForString(StringRef Str) const { diff --git a/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp b/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp index 777d93279c1..be4ce56ab15 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp @@ -113,7 +113,7 @@ Error NameMap::load(codeview::StreamReader &Stream) { uint32_t StringOffset = StringsOffset + NameOffset; uint32_t OldOffset = Stream.getOffset(); // Pump out our c-string from the stream. - std::string Str; + StringRef Str; Stream.setOffset(StringOffset); if (Stream.readZeroString(Str)) return make_error<RawError>(raw_error_code::corrupt_file, diff --git a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp index db66f536e5a..aba6a147afc 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp @@ -107,12 +107,11 @@ Error PublicsStream::reload() { "Publics Stream does not contain a header."); // Read PSGSIHDR and GSIHashHdr structs. - Header.reset(new HeaderInfo()); - if (Reader.readObject(Header.get())) + if (Reader.readObject(Header)) return make_error<RawError>(raw_error_code::corrupt_file, "Publics Stream does not contain a header."); - HashHdr.reset(new GSIHashHeader()); - if (Reader.readObject(HashHdr.get())) + + if (Reader.readObject(HashHdr)) return make_error<RawError>(raw_error_code::corrupt_file, "Publics Stream does not contain a header."); diff --git a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp index 2037a646de7..ba4ea577d81 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp @@ -30,7 +30,7 @@ SymbolStream::~SymbolStream() {} Error SymbolStream::reload() { codeview::StreamReader Reader(MappedStream); - if (Stream.initialize(Reader, MappedStream.getLength())) + if (Stream.load(Reader, MappedStream.getLength())) return make_error<RawError>(raw_error_code::corrupt_file, "Could not load symbol stream."); @@ -40,7 +40,7 @@ Error SymbolStream::reload() { iterator_range<codeview::SymbolIterator> SymbolStream::getSymbols() const { using codeview::SymbolIterator; ArrayRef<uint8_t> Data; - if (auto Error = Stream.getArrayRef(0, Data, Stream.getLength())) { + if (auto Error = Stream.readBytes(0, Stream.getLength(), Data)) { consumeError(std::move(Error)); return iterator_range<SymbolIterator>(SymbolIterator(), SymbolIterator()); } diff --git a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp index 99daf6e29fd..3345ab27571 100644 --- a/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp +++ b/llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp @@ -68,8 +68,7 @@ Error TpiStream::reload() { return make_error<RawError>(raw_error_code::corrupt_file, "TPI Stream does not contain a header."); - Header.reset(new HeaderInfo()); - if (Reader.readObject(Header.get())) + if (Reader.readObject(Header)) return make_error<RawError>(raw_error_code::corrupt_file, "TPI Stream does not contain a header."); @@ -93,7 +92,7 @@ Error TpiStream::reload() { HashFunction = HashBufferV8; // The actual type records themselves come from this stream - if (auto EC = RecordsBuffer.initialize(Reader, Header->TypeRecordBytes)) + if (auto EC = RecordsBuffer.load(Reader, Header->TypeRecordBytes)) return EC; // Hash indices, hash values, etc come from the hash stream. @@ -101,16 +100,16 @@ Error TpiStream::reload() { codeview::StreamReader HSR(HS); HSR.setOffset(Header->HashValueBuffer.Off); if (auto EC = - HashValuesBuffer.initialize(HSR, Header->HashValueBuffer.Length)) + HSR.readStreamRef(HashValuesBuffer, Header->HashValueBuffer.Length)) return EC; HSR.setOffset(Header->HashAdjBuffer.Off); - if (auto EC = HashAdjBuffer.initialize(HSR, Header->HashAdjBuffer.Length)) + if (auto EC = HSR.readStreamRef(HashAdjBuffer, Header->HashAdjBuffer.Length)) return EC; HSR.setOffset(Header->IndexOffsetBuffer.Off); - if (auto EC = TypeIndexOffsetBuffer.initialize( - HSR, Header->IndexOffsetBuffer.Length)) + if (auto EC = HSR.readStreamRef(TypeIndexOffsetBuffer, + Header->IndexOffsetBuffer.Length)) return EC; return Error::success(); |

