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; 50edd7eaddSDimitry Andric if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize - 4)) 51edd7eaddSDimitry Andric return EC; 52edd7eaddSDimitry Andric if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size)) 53edd7eaddSDimitry Andric return EC; 54edd7eaddSDimitry Andric if (auto EC = Reader.readSubstream(C13LinesSubstream, C13Size)) 55f37b6182SDimitry Andric return EC; 56f37b6182SDimitry Andric 57edd7eaddSDimitry Andric BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData); 58edd7eaddSDimitry Andric if (auto EC = 59edd7eaddSDimitry Andric SymbolReader.readArray(SymbolArray, SymbolReader.bytesRemaining())) 60f37b6182SDimitry Andric return EC; 61f37b6182SDimitry Andric 62edd7eaddSDimitry Andric BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData); 636d97bb29SDimitry Andric if (auto EC = SubsectionsReader.readArray(Subsections, 646d97bb29SDimitry Andric SubsectionsReader.bytesRemaining())) 65f37b6182SDimitry Andric return EC; 66f37b6182SDimitry Andric 67f37b6182SDimitry Andric uint32_t GlobalRefsSize; 68f37b6182SDimitry Andric if (auto EC = Reader.readInteger(GlobalRefsSize)) 69f37b6182SDimitry Andric return EC; 70edd7eaddSDimitry Andric if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize)) 71f37b6182SDimitry Andric return EC; 72f37b6182SDimitry Andric if (Reader.bytesRemaining() > 0) 73f37b6182SDimitry Andric return make_error<RawError>(raw_error_code::corrupt_file, 74f37b6182SDimitry Andric "Unexpected bytes in module stream."); 75f37b6182SDimitry Andric 76f37b6182SDimitry Andric return Error::success(); 77f37b6182SDimitry Andric } 78f37b6182SDimitry Andric 79edd7eaddSDimitry Andric BinarySubstreamRef ModuleDebugStreamRef::getSymbolsSubstream() const { 80edd7eaddSDimitry Andric return SymbolsSubstream; 81edd7eaddSDimitry Andric } 82edd7eaddSDimitry Andric 83edd7eaddSDimitry Andric BinarySubstreamRef ModuleDebugStreamRef::getC11LinesSubstream() const { 84edd7eaddSDimitry Andric return C11LinesSubstream; 85edd7eaddSDimitry Andric } 86edd7eaddSDimitry Andric 87edd7eaddSDimitry Andric BinarySubstreamRef ModuleDebugStreamRef::getC13LinesSubstream() const { 88edd7eaddSDimitry Andric return C13LinesSubstream; 89edd7eaddSDimitry Andric } 90edd7eaddSDimitry Andric 91edd7eaddSDimitry Andric BinarySubstreamRef ModuleDebugStreamRef::getGlobalRefsSubstream() const { 92edd7eaddSDimitry Andric return GlobalRefsSubstream; 93edd7eaddSDimitry Andric } 94edd7eaddSDimitry Andric 95f37b6182SDimitry Andric iterator_range<codeview::CVSymbolArray::Iterator> 96f37b6182SDimitry Andric ModuleDebugStreamRef::symbols(bool *HadError) const { 97edd7eaddSDimitry Andric return make_range(SymbolArray.begin(HadError), SymbolArray.end()); 98f37b6182SDimitry Andric } 99f37b6182SDimitry Andric 1006d97bb29SDimitry Andric llvm::iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator> 1016d97bb29SDimitry Andric ModuleDebugStreamRef::subsections() const { 1026d97bb29SDimitry Andric return make_range(Subsections.begin(), Subsections.end()); 103f37b6182SDimitry Andric } 104f37b6182SDimitry Andric 1056d97bb29SDimitry Andric bool ModuleDebugStreamRef::hasDebugSubsections() const { 106edd7eaddSDimitry Andric return !C13LinesSubstream.empty(); 107f37b6182SDimitry Andric } 108f37b6182SDimitry Andric 109f37b6182SDimitry Andric Error ModuleDebugStreamRef::commit() { return Error::success(); } 1106d97bb29SDimitry Andric 1116d97bb29SDimitry Andric Expected<codeview::DebugChecksumsSubsectionRef> 1126d97bb29SDimitry Andric ModuleDebugStreamRef::findChecksumsSubsection() const { 113db17bf38SDimitry Andric codeview::DebugChecksumsSubsectionRef Result; 1146d97bb29SDimitry Andric for (const auto &SS : subsections()) { 1156d97bb29SDimitry Andric if (SS.kind() != DebugSubsectionKind::FileChecksums) 1166d97bb29SDimitry Andric continue; 1176d97bb29SDimitry Andric 1186d97bb29SDimitry Andric if (auto EC = Result.initialize(SS.getRecordData())) 1196d97bb29SDimitry Andric return std::move(EC); 1206d97bb29SDimitry Andric return Result; 1216d97bb29SDimitry Andric } 122db17bf38SDimitry Andric return Result; 1236d97bb29SDimitry Andric } 124