1*8c099fe0SZachary Turner //===- DebugInlineeLinesSubsection.cpp ------------------------*- C++-*-===// 2*8c099fe0SZachary Turner // 3*8c099fe0SZachary Turner // The LLVM Compiler Infrastructure 4*8c099fe0SZachary Turner // 5*8c099fe0SZachary Turner // This file is distributed under the University of Illinois Open Source 6*8c099fe0SZachary Turner // License. See LICENSE.TXT for details. 7*8c099fe0SZachary Turner // 8*8c099fe0SZachary Turner //===----------------------------------------------------------------------===// 9*8c099fe0SZachary Turner 10*8c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" 11*8c099fe0SZachary Turner 12*8c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/CodeViewError.h" 13*8c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" 14*8c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" 15*8c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/StringTable.h" 16*8c099fe0SZachary Turner 17*8c099fe0SZachary Turner using namespace llvm; 18*8c099fe0SZachary Turner using namespace llvm::codeview; 19*8c099fe0SZachary Turner 20*8c099fe0SZachary Turner Error VarStreamArrayExtractor<InlineeSourceLine>::extract( 21*8c099fe0SZachary Turner BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item, 22*8c099fe0SZachary Turner bool HasExtraFiles) { 23*8c099fe0SZachary Turner BinaryStreamReader Reader(Stream); 24*8c099fe0SZachary Turner 25*8c099fe0SZachary Turner if (auto EC = Reader.readObject(Item.Header)) 26*8c099fe0SZachary Turner return EC; 27*8c099fe0SZachary Turner 28*8c099fe0SZachary Turner if (HasExtraFiles) { 29*8c099fe0SZachary Turner uint32_t ExtraFileCount; 30*8c099fe0SZachary Turner if (auto EC = Reader.readInteger(ExtraFileCount)) 31*8c099fe0SZachary Turner return EC; 32*8c099fe0SZachary Turner if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount)) 33*8c099fe0SZachary Turner return EC; 34*8c099fe0SZachary Turner } 35*8c099fe0SZachary Turner 36*8c099fe0SZachary Turner Len = Reader.getOffset(); 37*8c099fe0SZachary Turner return Error::success(); 38*8c099fe0SZachary Turner } 39*8c099fe0SZachary Turner 40*8c099fe0SZachary Turner DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef() 41*8c099fe0SZachary Turner : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {} 42*8c099fe0SZachary Turner 43*8c099fe0SZachary Turner Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) { 44*8c099fe0SZachary Turner if (auto EC = Reader.readEnum(Signature)) 45*8c099fe0SZachary Turner return EC; 46*8c099fe0SZachary Turner 47*8c099fe0SZachary Turner if (auto EC = 48*8c099fe0SZachary Turner Reader.readArray(Lines, Reader.bytesRemaining(), hasExtraFiles())) 49*8c099fe0SZachary Turner return EC; 50*8c099fe0SZachary Turner 51*8c099fe0SZachary Turner assert(Reader.bytesRemaining() == 0); 52*8c099fe0SZachary Turner return Error::success(); 53*8c099fe0SZachary Turner } 54*8c099fe0SZachary Turner 55*8c099fe0SZachary Turner bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const { 56*8c099fe0SZachary Turner return Signature == InlineeLinesSignature::ExtraFiles; 57*8c099fe0SZachary Turner } 58*8c099fe0SZachary Turner 59*8c099fe0SZachary Turner DebugInlineeLinesSubsection::DebugInlineeLinesSubsection( 60*8c099fe0SZachary Turner DebugChecksumsSubsection &Checksums, bool HasExtraFiles) 61*8c099fe0SZachary Turner : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums), 62*8c099fe0SZachary Turner HasExtraFiles(HasExtraFiles) {} 63*8c099fe0SZachary Turner 64*8c099fe0SZachary Turner uint32_t DebugInlineeLinesSubsection::calculateSerializedLength() { 65*8c099fe0SZachary Turner // 4 bytes for the signature 66*8c099fe0SZachary Turner uint32_t Size = sizeof(InlineeLinesSignature); 67*8c099fe0SZachary Turner 68*8c099fe0SZachary Turner // one header for each entry. 69*8c099fe0SZachary Turner Size += Entries.size() * sizeof(InlineeSourceLineHeader); 70*8c099fe0SZachary Turner if (HasExtraFiles) { 71*8c099fe0SZachary Turner // If extra files are enabled, one count for each entry. 72*8c099fe0SZachary Turner Size += Entries.size() * sizeof(uint32_t); 73*8c099fe0SZachary Turner 74*8c099fe0SZachary Turner // And one file id for each file. 75*8c099fe0SZachary Turner Size += ExtraFileCount * sizeof(uint32_t); 76*8c099fe0SZachary Turner } 77*8c099fe0SZachary Turner assert(Size % 4 == 0); 78*8c099fe0SZachary Turner return Size; 79*8c099fe0SZachary Turner } 80*8c099fe0SZachary Turner 81*8c099fe0SZachary Turner Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) { 82*8c099fe0SZachary Turner InlineeLinesSignature Sig = InlineeLinesSignature::Normal; 83*8c099fe0SZachary Turner if (HasExtraFiles) 84*8c099fe0SZachary Turner Sig = InlineeLinesSignature::ExtraFiles; 85*8c099fe0SZachary Turner 86*8c099fe0SZachary Turner if (auto EC = Writer.writeEnum(Sig)) 87*8c099fe0SZachary Turner return EC; 88*8c099fe0SZachary Turner 89*8c099fe0SZachary Turner for (const auto &E : Entries) { 90*8c099fe0SZachary Turner if (auto EC = Writer.writeObject(E.Header)) 91*8c099fe0SZachary Turner return EC; 92*8c099fe0SZachary Turner 93*8c099fe0SZachary Turner if (!HasExtraFiles) 94*8c099fe0SZachary Turner continue; 95*8c099fe0SZachary Turner 96*8c099fe0SZachary Turner if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size())) 97*8c099fe0SZachary Turner return EC; 98*8c099fe0SZachary Turner if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles))) 99*8c099fe0SZachary Turner return EC; 100*8c099fe0SZachary Turner } 101*8c099fe0SZachary Turner 102*8c099fe0SZachary Turner return Error::success(); 103*8c099fe0SZachary Turner } 104*8c099fe0SZachary Turner 105*8c099fe0SZachary Turner void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) { 106*8c099fe0SZachary Turner uint32_t Offset = Checksums.mapChecksumOffset(FileName); 107*8c099fe0SZachary Turner 108*8c099fe0SZachary Turner auto &Entry = Entries.back(); 109*8c099fe0SZachary Turner Entry.ExtraFiles.push_back(ulittle32_t(Offset)); 110*8c099fe0SZachary Turner ++ExtraFileCount; 111*8c099fe0SZachary Turner } 112*8c099fe0SZachary Turner 113*8c099fe0SZachary Turner void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId, 114*8c099fe0SZachary Turner StringRef FileName, 115*8c099fe0SZachary Turner uint32_t SourceLine) { 116*8c099fe0SZachary Turner uint32_t Offset = Checksums.mapChecksumOffset(FileName); 117*8c099fe0SZachary Turner 118*8c099fe0SZachary Turner Entries.emplace_back(); 119*8c099fe0SZachary Turner auto &Entry = Entries.back(); 120*8c099fe0SZachary Turner Entry.Header.FileID = Offset; 121*8c099fe0SZachary Turner Entry.Header.SourceLineNum = SourceLine; 122*8c099fe0SZachary Turner Entry.Header.Inlinee = FuncId; 123*8c099fe0SZachary Turner } 124