summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/CodeView/ByteStream.cpp27
-rw-r--r--llvm/lib/DebugInfo/CodeView/StreamReader.cpp66
-rw-r--r--llvm/lib/DebugInfo/PDB/CMakeLists.txt1
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/DbiStream.cpp85
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/InfoStream.cpp14
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/MappedBlockStream.cpp85
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModInfo.cpp77
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/ModStream.cpp8
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/NameHashTable.cpp30
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/NameMap.cpp2
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/PublicsStream.cpp7
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/SymbolStream.cpp4
-rw-r--r--llvm/lib/DebugInfo/PDB/Raw/TpiStream.cpp13
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();
OpenPOWER on IntegriCloud