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