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