xref: /src/contrib/llvm-project/llvm/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
19df3605dSDimitry Andric //===- DebugInlineeLinesSubsection.cpp ------------------------------------===//
2a303c417SDimitry Andric //
3e6d15924SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e6d15924SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5e6d15924SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a303c417SDimitry Andric //
7a303c417SDimitry Andric //===----------------------------------------------------------------------===//
8a303c417SDimitry Andric 
9ee2f195dSDimitry Andric #include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
109df3605dSDimitry Andric #include "llvm/ADT/ArrayRef.h"
119df3605dSDimitry Andric #include "llvm/DebugInfo/CodeView/CodeView.h"
12ee2f195dSDimitry Andric #include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
13145449b1SDimitry Andric #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
149df3605dSDimitry Andric #include "llvm/Support/BinaryStreamReader.h"
159df3605dSDimitry Andric #include "llvm/Support/BinaryStreamWriter.h"
169df3605dSDimitry Andric #include "llvm/Support/Endian.h"
179df3605dSDimitry Andric #include "llvm/Support/Error.h"
189df3605dSDimitry Andric #include <cassert>
199df3605dSDimitry Andric #include <cstdint>
20a303c417SDimitry Andric 
21a303c417SDimitry Andric using namespace llvm;
22a303c417SDimitry Andric using namespace llvm::codeview;
23a303c417SDimitry Andric 
247ab83427SDimitry Andric Error VarStreamArrayExtractor<InlineeSourceLine>::
operator ()(BinaryStreamRef Stream,uint32_t & Len,InlineeSourceLine & Item)257ab83427SDimitry Andric operator()(BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item) {
26a303c417SDimitry Andric   BinaryStreamReader Reader(Stream);
27a303c417SDimitry Andric 
28a303c417SDimitry Andric   if (auto EC = Reader.readObject(Item.Header))
29a303c417SDimitry Andric     return EC;
30a303c417SDimitry Andric 
31148779dfSDimitry Andric   if (HasExtraFiles) {
32a303c417SDimitry Andric     uint32_t ExtraFileCount;
33a303c417SDimitry Andric     if (auto EC = Reader.readInteger(ExtraFileCount))
34a303c417SDimitry Andric       return EC;
35a303c417SDimitry Andric     if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
36a303c417SDimitry Andric       return EC;
37a303c417SDimitry Andric   }
38a303c417SDimitry Andric 
39a303c417SDimitry Andric   Len = Reader.getOffset();
40a303c417SDimitry Andric   return Error::success();
41a303c417SDimitry Andric }
42a303c417SDimitry Andric 
DebugInlineeLinesSubsectionRef()43ee2f195dSDimitry Andric DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef()
44ee2f195dSDimitry Andric     : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {}
45a303c417SDimitry Andric 
initialize(BinaryStreamReader Reader)46ee2f195dSDimitry Andric Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
47a303c417SDimitry Andric   if (auto EC = Reader.readEnum(Signature))
48a303c417SDimitry Andric     return EC;
49a303c417SDimitry Andric 
507ab83427SDimitry Andric   Lines.getExtractor().HasExtraFiles = hasExtraFiles();
517ab83427SDimitry Andric   if (auto EC = Reader.readArray(Lines, Reader.bytesRemaining()))
52a303c417SDimitry Andric     return EC;
53a303c417SDimitry Andric 
54a303c417SDimitry Andric   assert(Reader.bytesRemaining() == 0);
55a303c417SDimitry Andric   return Error::success();
56a303c417SDimitry Andric }
57a303c417SDimitry Andric 
hasExtraFiles() const58ee2f195dSDimitry Andric bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const {
59a303c417SDimitry Andric   return Signature == InlineeLinesSignature::ExtraFiles;
60a303c417SDimitry Andric }
61a303c417SDimitry Andric 
DebugInlineeLinesSubsection(DebugChecksumsSubsection & Checksums,bool HasExtraFiles)62ee2f195dSDimitry Andric DebugInlineeLinesSubsection::DebugInlineeLinesSubsection(
63ee2f195dSDimitry Andric     DebugChecksumsSubsection &Checksums, bool HasExtraFiles)
64ee2f195dSDimitry Andric     : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums),
65ee2f195dSDimitry Andric       HasExtraFiles(HasExtraFiles) {}
66a303c417SDimitry Andric 
calculateSerializedSize() const67ee2f195dSDimitry Andric uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const {
68a303c417SDimitry Andric   // 4 bytes for the signature
69a303c417SDimitry Andric   uint32_t Size = sizeof(InlineeLinesSignature);
70a303c417SDimitry Andric 
71a303c417SDimitry Andric   // one header for each entry.
72a303c417SDimitry Andric   Size += Entries.size() * sizeof(InlineeSourceLineHeader);
73a303c417SDimitry Andric   if (HasExtraFiles) {
74a303c417SDimitry Andric     // If extra files are enabled, one count for each entry.
75a303c417SDimitry Andric     Size += Entries.size() * sizeof(uint32_t);
76a303c417SDimitry Andric 
77a303c417SDimitry Andric     // And one file id for each file.
78a303c417SDimitry Andric     Size += ExtraFileCount * sizeof(uint32_t);
79a303c417SDimitry Andric   }
80a303c417SDimitry Andric   assert(Size % 4 == 0);
81a303c417SDimitry Andric   return Size;
82a303c417SDimitry Andric }
83a303c417SDimitry Andric 
commit(BinaryStreamWriter & Writer) const84ee2f195dSDimitry Andric Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const {
85a303c417SDimitry Andric   InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
86a303c417SDimitry Andric   if (HasExtraFiles)
87a303c417SDimitry Andric     Sig = InlineeLinesSignature::ExtraFiles;
88a303c417SDimitry Andric 
89a303c417SDimitry Andric   if (auto EC = Writer.writeEnum(Sig))
90a303c417SDimitry Andric     return EC;
91a303c417SDimitry Andric 
92a303c417SDimitry Andric   for (const auto &E : Entries) {
93a303c417SDimitry Andric     if (auto EC = Writer.writeObject(E.Header))
94a303c417SDimitry Andric       return EC;
95a303c417SDimitry Andric 
96a303c417SDimitry Andric     if (!HasExtraFiles)
97a303c417SDimitry Andric       continue;
98a303c417SDimitry Andric 
99a303c417SDimitry Andric     if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
100a303c417SDimitry Andric       return EC;
101e3b55780SDimitry Andric     if (auto EC = Writer.writeArray(ArrayRef(E.ExtraFiles)))
102a303c417SDimitry Andric       return EC;
103a303c417SDimitry Andric   }
104a303c417SDimitry Andric 
105a303c417SDimitry Andric   return Error::success();
106a303c417SDimitry Andric }
107a303c417SDimitry Andric 
addExtraFile(StringRef FileName)108ee2f195dSDimitry Andric void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) {
109148779dfSDimitry Andric   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
110148779dfSDimitry Andric 
111a303c417SDimitry Andric   auto &Entry = Entries.back();
112148779dfSDimitry Andric   Entry.ExtraFiles.push_back(ulittle32_t(Offset));
113a303c417SDimitry Andric   ++ExtraFileCount;
114a303c417SDimitry Andric }
115a303c417SDimitry Andric 
addInlineSite(TypeIndex FuncId,StringRef FileName,uint32_t SourceLine)116ee2f195dSDimitry Andric void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId,
117148779dfSDimitry Andric                                                 StringRef FileName,
118a303c417SDimitry Andric                                                 uint32_t SourceLine) {
119148779dfSDimitry Andric   uint32_t Offset = Checksums.mapChecksumOffset(FileName);
120148779dfSDimitry Andric 
121a303c417SDimitry Andric   Entries.emplace_back();
122a303c417SDimitry Andric   auto &Entry = Entries.back();
123148779dfSDimitry Andric   Entry.Header.FileID = Offset;
124a303c417SDimitry Andric   Entry.Header.SourceLineNum = SourceLine;
125a303c417SDimitry Andric   Entry.Header.Inlinee = FuncId;
126a303c417SDimitry Andric }
127