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