167c56014SZachary Turner //===- ModuleDebugStream.cpp - PDB Module Info Stream Access --------------===//
267c56014SZachary Turner //
367c56014SZachary Turner //                     The LLVM Compiler Infrastructure
467c56014SZachary Turner //
567c56014SZachary Turner // This file is distributed under the University of Illinois Open Source
667c56014SZachary Turner // License. See LICENSE.TXT for details.
767c56014SZachary Turner //
867c56014SZachary Turner //===----------------------------------------------------------------------===//
967c56014SZachary Turner 
1067c56014SZachary Turner #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
1167c56014SZachary Turner #include "llvm/ADT/iterator_range.h"
1267c56014SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
1367c56014SZachary Turner #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
1467c56014SZachary Turner #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
1567c56014SZachary Turner #include "llvm/DebugInfo/PDB/Native/RawError.h"
1667c56014SZachary Turner #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
1767c56014SZachary Turner #include "llvm/Support/BinaryStreamReader.h"
1867c56014SZachary Turner #include "llvm/Support/BinaryStreamRef.h"
1967c56014SZachary Turner #include "llvm/Support/Error.h"
2067c56014SZachary Turner #include <algorithm>
2167c56014SZachary Turner #include <cstdint>
2267c56014SZachary Turner 
2367c56014SZachary Turner using namespace llvm;
24c37cb0c6SZachary Turner using namespace llvm::codeview;
2567c56014SZachary Turner using namespace llvm::msf;
2667c56014SZachary Turner using namespace llvm::pdb;
2767c56014SZachary Turner 
2867c56014SZachary Turner ModuleDebugStream::ModuleDebugStream(const DbiModuleDescriptor &Module,
2967c56014SZachary Turner                                      std::unique_ptr<MappedBlockStream> Stream)
3067c56014SZachary Turner     : Mod(Module), Stream(std::move(Stream)) {}
3167c56014SZachary Turner 
3267c56014SZachary Turner ModuleDebugStream::~ModuleDebugStream() = default;
3367c56014SZachary Turner 
3467c56014SZachary Turner Error ModuleDebugStream::reload() {
3567c56014SZachary Turner   BinaryStreamReader Reader(*Stream);
3667c56014SZachary Turner 
3767c56014SZachary Turner   uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize();
38*5b6e4e0aSZachary Turner   uint32_t C11Size = Mod.getC11LineInfoByteSize();
3967c56014SZachary Turner   uint32_t C13Size = Mod.getC13LineInfoByteSize();
4067c56014SZachary Turner 
4167c56014SZachary Turner   if (C11Size > 0 && C13Size > 0)
4267c56014SZachary Turner     return make_error<RawError>(raw_error_code::corrupt_file,
4367c56014SZachary Turner                                 "Module has both C11 and C13 line info");
4467c56014SZachary Turner 
4567c56014SZachary Turner   BinaryStreamRef S;
4667c56014SZachary Turner 
4767c56014SZachary Turner   if (auto EC = Reader.readInteger(Signature))
4867c56014SZachary Turner     return EC;
4967c56014SZachary Turner   if (auto EC = Reader.readArray(SymbolsSubstream, SymbolSize - 4))
5067c56014SZachary Turner     return EC;
5167c56014SZachary Turner 
5267c56014SZachary Turner   if (auto EC = Reader.readStreamRef(LinesSubstream, C11Size))
5367c56014SZachary Turner     return EC;
5467c56014SZachary Turner   if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))
5567c56014SZachary Turner     return EC;
5667c56014SZachary Turner 
5767c56014SZachary Turner   BinaryStreamReader LineReader(C13LinesSubstream);
58c37cb0c6SZachary Turner   if (auto EC =
59c37cb0c6SZachary Turner           LineReader.readArray(LinesAndChecksums, LineReader.bytesRemaining()))
6067c56014SZachary Turner     return EC;
6167c56014SZachary Turner 
6267c56014SZachary Turner   uint32_t GlobalRefsSize;
6367c56014SZachary Turner   if (auto EC = Reader.readInteger(GlobalRefsSize))
6467c56014SZachary Turner     return EC;
6567c56014SZachary Turner   if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize))
6667c56014SZachary Turner     return EC;
6767c56014SZachary Turner   if (Reader.bytesRemaining() > 0)
6867c56014SZachary Turner     return make_error<RawError>(raw_error_code::corrupt_file,
6967c56014SZachary Turner                                 "Unexpected bytes in module stream.");
7067c56014SZachary Turner 
7167c56014SZachary Turner   return Error::success();
7267c56014SZachary Turner }
7367c56014SZachary Turner 
7467c56014SZachary Turner iterator_range<codeview::CVSymbolArray::Iterator>
7567c56014SZachary Turner ModuleDebugStream::symbols(bool *HadError) const {
7667c56014SZachary Turner   return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end());
7767c56014SZachary Turner }
7867c56014SZachary Turner 
79c37cb0c6SZachary Turner llvm::iterator_range<ModuleDebugStream::LinesAndChecksumsIterator>
80c37cb0c6SZachary Turner ModuleDebugStream::linesAndChecksums() const {
81c37cb0c6SZachary Turner   return make_range(LinesAndChecksums.begin(), LinesAndChecksums.end());
8267c56014SZachary Turner }
8367c56014SZachary Turner 
8467c56014SZachary Turner bool ModuleDebugStream::hasLineInfo() const {
85c37cb0c6SZachary Turner   return C13LinesSubstream.getLength() > 0;
8667c56014SZachary Turner }
8767c56014SZachary Turner 
8867c56014SZachary Turner Error ModuleDebugStream::commit() { return Error::success(); }
89