1*67c56014SZachary Turner //===- ModuleDebugStream.cpp - PDB Module Info Stream Access --------------===//
2*67c56014SZachary Turner //
3*67c56014SZachary Turner //                     The LLVM Compiler Infrastructure
4*67c56014SZachary Turner //
5*67c56014SZachary Turner // This file is distributed under the University of Illinois Open Source
6*67c56014SZachary Turner // License. See LICENSE.TXT for details.
7*67c56014SZachary Turner //
8*67c56014SZachary Turner //===----------------------------------------------------------------------===//
9*67c56014SZachary Turner 
10*67c56014SZachary Turner #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
11*67c56014SZachary Turner #include "llvm/ADT/iterator_range.h"
12*67c56014SZachary Turner #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
13*67c56014SZachary Turner #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
14*67c56014SZachary Turner #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
15*67c56014SZachary Turner #include "llvm/DebugInfo/PDB/Native/RawError.h"
16*67c56014SZachary Turner #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
17*67c56014SZachary Turner #include "llvm/Support/BinaryStreamReader.h"
18*67c56014SZachary Turner #include "llvm/Support/BinaryStreamRef.h"
19*67c56014SZachary Turner #include "llvm/Support/Error.h"
20*67c56014SZachary Turner #include <algorithm>
21*67c56014SZachary Turner #include <cstdint>
22*67c56014SZachary Turner 
23*67c56014SZachary Turner using namespace llvm;
24*67c56014SZachary Turner using namespace llvm::msf;
25*67c56014SZachary Turner using namespace llvm::pdb;
26*67c56014SZachary Turner 
27*67c56014SZachary Turner ModuleDebugStream::ModuleDebugStream(const DbiModuleDescriptor &Module,
28*67c56014SZachary Turner                                      std::unique_ptr<MappedBlockStream> Stream)
29*67c56014SZachary Turner     : Mod(Module), Stream(std::move(Stream)) {}
30*67c56014SZachary Turner 
31*67c56014SZachary Turner ModuleDebugStream::~ModuleDebugStream() = default;
32*67c56014SZachary Turner 
33*67c56014SZachary Turner Error ModuleDebugStream::reload() {
34*67c56014SZachary Turner   BinaryStreamReader Reader(*Stream);
35*67c56014SZachary Turner 
36*67c56014SZachary Turner   uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize();
37*67c56014SZachary Turner   uint32_t C11Size = Mod.getLineInfoByteSize();
38*67c56014SZachary Turner   uint32_t C13Size = Mod.getC13LineInfoByteSize();
39*67c56014SZachary Turner 
40*67c56014SZachary Turner   if (C11Size > 0 && C13Size > 0)
41*67c56014SZachary Turner     return make_error<RawError>(raw_error_code::corrupt_file,
42*67c56014SZachary Turner                                 "Module has both C11 and C13 line info");
43*67c56014SZachary Turner 
44*67c56014SZachary Turner   BinaryStreamRef S;
45*67c56014SZachary Turner 
46*67c56014SZachary Turner   if (auto EC = Reader.readInteger(Signature))
47*67c56014SZachary Turner     return EC;
48*67c56014SZachary Turner   if (auto EC = Reader.readArray(SymbolsSubstream, SymbolSize - 4))
49*67c56014SZachary Turner     return EC;
50*67c56014SZachary Turner 
51*67c56014SZachary Turner   if (auto EC = Reader.readStreamRef(LinesSubstream, C11Size))
52*67c56014SZachary Turner     return EC;
53*67c56014SZachary Turner   if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size))
54*67c56014SZachary Turner     return EC;
55*67c56014SZachary Turner 
56*67c56014SZachary Turner   BinaryStreamReader LineReader(C13LinesSubstream);
57*67c56014SZachary Turner   if (auto EC = LineReader.readArray(LineInfo, LineReader.bytesRemaining()))
58*67c56014SZachary Turner     return EC;
59*67c56014SZachary Turner 
60*67c56014SZachary Turner   uint32_t GlobalRefsSize;
61*67c56014SZachary Turner   if (auto EC = Reader.readInteger(GlobalRefsSize))
62*67c56014SZachary Turner     return EC;
63*67c56014SZachary Turner   if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize))
64*67c56014SZachary Turner     return EC;
65*67c56014SZachary Turner   if (Reader.bytesRemaining() > 0)
66*67c56014SZachary Turner     return make_error<RawError>(raw_error_code::corrupt_file,
67*67c56014SZachary Turner                                 "Unexpected bytes in module stream.");
68*67c56014SZachary Turner 
69*67c56014SZachary Turner   return Error::success();
70*67c56014SZachary Turner }
71*67c56014SZachary Turner 
72*67c56014SZachary Turner iterator_range<codeview::CVSymbolArray::Iterator>
73*67c56014SZachary Turner ModuleDebugStream::symbols(bool *HadError) const {
74*67c56014SZachary Turner   // It's OK if the stream is empty.
75*67c56014SZachary Turner   if (SymbolsSubstream.getUnderlyingStream().getLength() == 0)
76*67c56014SZachary Turner     return make_range(SymbolsSubstream.end(), SymbolsSubstream.end());
77*67c56014SZachary Turner   return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end());
78*67c56014SZachary Turner }
79*67c56014SZachary Turner 
80*67c56014SZachary Turner iterator_range<codeview::ModuleDebugFragmentArray::Iterator>
81*67c56014SZachary Turner ModuleDebugStream::lines(bool *HadError) const {
82*67c56014SZachary Turner   return make_range(LineInfo.begin(HadError), LineInfo.end());
83*67c56014SZachary Turner }
84*67c56014SZachary Turner 
85*67c56014SZachary Turner bool ModuleDebugStream::hasLineInfo() const {
86*67c56014SZachary Turner   return C13LinesSubstream.getLength() > 0 || LinesSubstream.getLength() > 0;
87*67c56014SZachary Turner }
88*67c56014SZachary Turner 
89*67c56014SZachary Turner Error ModuleDebugStream::commit() { return Error::success(); }
90