189cb50c9SDimitry Andric //===- DebugInlineeLinesSubsection.cpp ------------------------*- C++-*-===// 289cb50c9SDimitry Andric // 389cb50c9SDimitry Andric // The LLVM Compiler Infrastructure 489cb50c9SDimitry Andric // 589cb50c9SDimitry Andric // This file is distributed under the University of Illinois Open Source 689cb50c9SDimitry Andric // License. See LICENSE.TXT for details. 789cb50c9SDimitry Andric // 889cb50c9SDimitry Andric //===----------------------------------------------------------------------===// 989cb50c9SDimitry Andric 1089cb50c9SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h" 1189cb50c9SDimitry Andric 1289cb50c9SDimitry Andric #include "llvm/DebugInfo/CodeView/CodeViewError.h" 1389cb50c9SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h" 1489cb50c9SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h" 1589cb50c9SDimitry Andric #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" 1689cb50c9SDimitry Andric 1789cb50c9SDimitry Andric using namespace llvm; 1889cb50c9SDimitry Andric using namespace llvm::codeview; 1989cb50c9SDimitry Andric 20*db17bf38SDimitry Andric Error VarStreamArrayExtractor<InlineeSourceLine>:: 21*db17bf38SDimitry Andric operator()(BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item) { 2289cb50c9SDimitry Andric BinaryStreamReader Reader(Stream); 2389cb50c9SDimitry Andric 2489cb50c9SDimitry Andric if (auto EC = Reader.readObject(Item.Header)) 2589cb50c9SDimitry Andric return EC; 2689cb50c9SDimitry Andric 2789cb50c9SDimitry Andric if (HasExtraFiles) { 2889cb50c9SDimitry Andric uint32_t ExtraFileCount; 2989cb50c9SDimitry Andric if (auto EC = Reader.readInteger(ExtraFileCount)) 3089cb50c9SDimitry Andric return EC; 3189cb50c9SDimitry Andric if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount)) 3289cb50c9SDimitry Andric return EC; 3389cb50c9SDimitry Andric } 3489cb50c9SDimitry Andric 3589cb50c9SDimitry Andric Len = Reader.getOffset(); 3689cb50c9SDimitry Andric return Error::success(); 3789cb50c9SDimitry Andric } 3889cb50c9SDimitry Andric 3989cb50c9SDimitry Andric DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef() 4089cb50c9SDimitry Andric : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {} 4189cb50c9SDimitry Andric 4289cb50c9SDimitry Andric Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) { 4389cb50c9SDimitry Andric if (auto EC = Reader.readEnum(Signature)) 4489cb50c9SDimitry Andric return EC; 4589cb50c9SDimitry Andric 46*db17bf38SDimitry Andric Lines.getExtractor().HasExtraFiles = hasExtraFiles(); 47*db17bf38SDimitry Andric if (auto EC = Reader.readArray(Lines, Reader.bytesRemaining())) 4889cb50c9SDimitry Andric return EC; 4989cb50c9SDimitry Andric 5089cb50c9SDimitry Andric assert(Reader.bytesRemaining() == 0); 5189cb50c9SDimitry Andric return Error::success(); 5289cb50c9SDimitry Andric } 5389cb50c9SDimitry Andric 5489cb50c9SDimitry Andric bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const { 5589cb50c9SDimitry Andric return Signature == InlineeLinesSignature::ExtraFiles; 5689cb50c9SDimitry Andric } 5789cb50c9SDimitry Andric 5889cb50c9SDimitry Andric DebugInlineeLinesSubsection::DebugInlineeLinesSubsection( 5989cb50c9SDimitry Andric DebugChecksumsSubsection &Checksums, bool HasExtraFiles) 6089cb50c9SDimitry Andric : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums), 6189cb50c9SDimitry Andric HasExtraFiles(HasExtraFiles) {} 6289cb50c9SDimitry Andric 6389cb50c9SDimitry Andric uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const { 6489cb50c9SDimitry Andric // 4 bytes for the signature 6589cb50c9SDimitry Andric uint32_t Size = sizeof(InlineeLinesSignature); 6689cb50c9SDimitry Andric 6789cb50c9SDimitry Andric // one header for each entry. 6889cb50c9SDimitry Andric Size += Entries.size() * sizeof(InlineeSourceLineHeader); 6989cb50c9SDimitry Andric if (HasExtraFiles) { 7089cb50c9SDimitry Andric // If extra files are enabled, one count for each entry. 7189cb50c9SDimitry Andric Size += Entries.size() * sizeof(uint32_t); 7289cb50c9SDimitry Andric 7389cb50c9SDimitry Andric // And one file id for each file. 7489cb50c9SDimitry Andric Size += ExtraFileCount * sizeof(uint32_t); 7589cb50c9SDimitry Andric } 7689cb50c9SDimitry Andric assert(Size % 4 == 0); 7789cb50c9SDimitry Andric return Size; 7889cb50c9SDimitry Andric } 7989cb50c9SDimitry Andric 8089cb50c9SDimitry Andric Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const { 8189cb50c9SDimitry Andric InlineeLinesSignature Sig = InlineeLinesSignature::Normal; 8289cb50c9SDimitry Andric if (HasExtraFiles) 8389cb50c9SDimitry Andric Sig = InlineeLinesSignature::ExtraFiles; 8489cb50c9SDimitry Andric 8589cb50c9SDimitry Andric if (auto EC = Writer.writeEnum(Sig)) 8689cb50c9SDimitry Andric return EC; 8789cb50c9SDimitry Andric 8889cb50c9SDimitry Andric for (const auto &E : Entries) { 8989cb50c9SDimitry Andric if (auto EC = Writer.writeObject(E.Header)) 9089cb50c9SDimitry Andric return EC; 9189cb50c9SDimitry Andric 9289cb50c9SDimitry Andric if (!HasExtraFiles) 9389cb50c9SDimitry Andric continue; 9489cb50c9SDimitry Andric 9589cb50c9SDimitry Andric if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size())) 9689cb50c9SDimitry Andric return EC; 9789cb50c9SDimitry Andric if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles))) 9889cb50c9SDimitry Andric return EC; 9989cb50c9SDimitry Andric } 10089cb50c9SDimitry Andric 10189cb50c9SDimitry Andric return Error::success(); 10289cb50c9SDimitry Andric } 10389cb50c9SDimitry Andric 10489cb50c9SDimitry Andric void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) { 10589cb50c9SDimitry Andric uint32_t Offset = Checksums.mapChecksumOffset(FileName); 10689cb50c9SDimitry Andric 10789cb50c9SDimitry Andric auto &Entry = Entries.back(); 10889cb50c9SDimitry Andric Entry.ExtraFiles.push_back(ulittle32_t(Offset)); 10989cb50c9SDimitry Andric ++ExtraFileCount; 11089cb50c9SDimitry Andric } 11189cb50c9SDimitry Andric 11289cb50c9SDimitry Andric void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId, 11389cb50c9SDimitry Andric StringRef FileName, 11489cb50c9SDimitry Andric uint32_t SourceLine) { 11589cb50c9SDimitry Andric uint32_t Offset = Checksums.mapChecksumOffset(FileName); 11689cb50c9SDimitry Andric 11789cb50c9SDimitry Andric Entries.emplace_back(); 11889cb50c9SDimitry Andric auto &Entry = Entries.back(); 11989cb50c9SDimitry Andric Entry.Header.FileID = Offset; 12089cb50c9SDimitry Andric Entry.Header.SourceLineNum = SourceLine; 12189cb50c9SDimitry Andric Entry.Header.Inlinee = FuncId; 12289cb50c9SDimitry Andric } 123