1f37b6182SDimitry Andric //===- ModuleDebugStream.cpp - PDB Module Info Stream Access --------------===// 2f37b6182SDimitry Andric // 3f37b6182SDimitry Andric // The LLVM Compiler Infrastructure 4f37b6182SDimitry Andric // 5f37b6182SDimitry Andric // This file is distributed under the University of Illinois Open Source 6f37b6182SDimitry Andric // License. See LICENSE.TXT for details. 7f37b6182SDimitry Andric // 8f37b6182SDimitry Andric //===----------------------------------------------------------------------===// 9f37b6182SDimitry Andric 10f37b6182SDimitry Andric #include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h" 11f37b6182SDimitry Andric #include "llvm/ADT/iterator_range.h" 12f37b6182SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 13f37b6182SDimitry Andric #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" 14f37b6182SDimitry Andric #include "llvm/DebugInfo/PDB/Native/PDBFile.h" 15f37b6182SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawError.h" 16f37b6182SDimitry Andric #include "llvm/DebugInfo/PDB/Native/RawTypes.h" 17f37b6182SDimitry Andric #include "llvm/Support/BinaryStreamReader.h" 18f37b6182SDimitry Andric #include "llvm/Support/BinaryStreamRef.h" 19f37b6182SDimitry Andric #include "llvm/Support/Error.h" 20f37b6182SDimitry Andric #include <algorithm> 21f37b6182SDimitry Andric #include <cstdint> 22f37b6182SDimitry Andric 23f37b6182SDimitry Andric using namespace llvm; 24f37b6182SDimitry Andric using namespace llvm::codeview; 25f37b6182SDimitry Andric using namespace llvm::msf; 26f37b6182SDimitry Andric using namespace llvm::pdb; 27f37b6182SDimitry Andric 28f37b6182SDimitry Andric ModuleDebugStreamRef::ModuleDebugStreamRef( 29f37b6182SDimitry Andric const DbiModuleDescriptor &Module, 30f37b6182SDimitry Andric std::unique_ptr<MappedBlockStream> Stream) 31f37b6182SDimitry Andric : Mod(Module), Stream(std::move(Stream)) {} 32f37b6182SDimitry Andric 33f37b6182SDimitry Andric ModuleDebugStreamRef::~ModuleDebugStreamRef() = default; 34f37b6182SDimitry Andric 35f37b6182SDimitry Andric Error ModuleDebugStreamRef::reload() { 36f37b6182SDimitry Andric BinaryStreamReader Reader(*Stream); 37f37b6182SDimitry Andric 38f37b6182SDimitry Andric uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize(); 39f37b6182SDimitry Andric uint32_t C11Size = Mod.getC11LineInfoByteSize(); 40f37b6182SDimitry Andric uint32_t C13Size = Mod.getC13LineInfoByteSize(); 41f37b6182SDimitry Andric 42f37b6182SDimitry Andric if (C11Size > 0 && C13Size > 0) 43f37b6182SDimitry Andric return make_error<RawError>(raw_error_code::corrupt_file, 44f37b6182SDimitry Andric "Module has both C11 and C13 line info"); 45f37b6182SDimitry Andric 46f37b6182SDimitry Andric BinaryStreamRef S; 47f37b6182SDimitry Andric 48f37b6182SDimitry Andric if (auto EC = Reader.readInteger(Signature)) 49f37b6182SDimitry Andric return EC; 50f37b6182SDimitry Andric if (auto EC = Reader.readArray(SymbolsSubstream, SymbolSize - 4)) 51f37b6182SDimitry Andric return EC; 52f37b6182SDimitry Andric 53f37b6182SDimitry Andric if (auto EC = Reader.readStreamRef(C11LinesSubstream, C11Size)) 54f37b6182SDimitry Andric return EC; 55f37b6182SDimitry Andric if (auto EC = Reader.readStreamRef(C13LinesSubstream, C13Size)) 56f37b6182SDimitry Andric return EC; 57f37b6182SDimitry Andric 586d97bb29SDimitry Andric BinaryStreamReader SubsectionsReader(C13LinesSubstream); 596d97bb29SDimitry Andric if (auto EC = SubsectionsReader.readArray(Subsections, 606d97bb29SDimitry Andric SubsectionsReader.bytesRemaining())) 61f37b6182SDimitry Andric return EC; 62f37b6182SDimitry Andric 63f37b6182SDimitry Andric uint32_t GlobalRefsSize; 64f37b6182SDimitry Andric if (auto EC = Reader.readInteger(GlobalRefsSize)) 65f37b6182SDimitry Andric return EC; 66f37b6182SDimitry Andric if (auto EC = Reader.readStreamRef(GlobalRefsSubstream, GlobalRefsSize)) 67f37b6182SDimitry Andric return EC; 68f37b6182SDimitry Andric if (Reader.bytesRemaining() > 0) 69f37b6182SDimitry Andric return make_error<RawError>(raw_error_code::corrupt_file, 70f37b6182SDimitry Andric "Unexpected bytes in module stream."); 71f37b6182SDimitry Andric 72f37b6182SDimitry Andric return Error::success(); 73f37b6182SDimitry Andric } 74f37b6182SDimitry Andric 75f37b6182SDimitry Andric iterator_range<codeview::CVSymbolArray::Iterator> 76f37b6182SDimitry Andric ModuleDebugStreamRef::symbols(bool *HadError) const { 77f37b6182SDimitry Andric return make_range(SymbolsSubstream.begin(HadError), SymbolsSubstream.end()); 78f37b6182SDimitry Andric } 79f37b6182SDimitry Andric 806d97bb29SDimitry Andric llvm::iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator> 816d97bb29SDimitry Andric ModuleDebugStreamRef::subsections() const { 826d97bb29SDimitry Andric return make_range(Subsections.begin(), Subsections.end()); 83f37b6182SDimitry Andric } 84f37b6182SDimitry Andric 856d97bb29SDimitry Andric bool ModuleDebugStreamRef::hasDebugSubsections() const { 86f37b6182SDimitry Andric return C13LinesSubstream.getLength() > 0; 87f37b6182SDimitry Andric } 88f37b6182SDimitry Andric 89f37b6182SDimitry Andric Error ModuleDebugStreamRef::commit() { return Error::success(); } 906d97bb29SDimitry Andric 916d97bb29SDimitry Andric Expected<codeview::DebugChecksumsSubsectionRef> 926d97bb29SDimitry Andric ModuleDebugStreamRef::findChecksumsSubsection() const { 936d97bb29SDimitry Andric for (const auto &SS : subsections()) { 946d97bb29SDimitry Andric if (SS.kind() != DebugSubsectionKind::FileChecksums) 956d97bb29SDimitry Andric continue; 966d97bb29SDimitry Andric 976d97bb29SDimitry Andric codeview::DebugChecksumsSubsectionRef Result; 986d97bb29SDimitry Andric if (auto EC = Result.initialize(SS.getRecordData())) 996d97bb29SDimitry Andric return std::move(EC); 1006d97bb29SDimitry Andric return Result; 1016d97bb29SDimitry Andric } 1026d97bb29SDimitry Andric return make_error<RawError>(raw_error_code::no_entry); 1036d97bb29SDimitry Andric } 104