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