blob: a565a6a64bed6e900af38dd478cf5548624959bc [file] [log] [blame]
Zachary Turner8c099fe2017-05-30 16:36:15 +00001//===- DebugInlineeLinesSubsection.cpp ------------------------*- C++-*-===//
Zachary Turneredef1452017-05-02 16:56:09 +00002//
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
Zachary Turner8c099fe2017-05-30 16:36:15 +000010#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
Zachary Turneredef1452017-05-02 16:56:09 +000011
12#include "llvm/DebugInfo/CodeView/CodeViewError.h"
Zachary Turner8c099fe2017-05-30 16:36:15 +000013#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
14#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
Zachary Turnercf468d82017-05-03 17:11:40 +000015#include "llvm/DebugInfo/CodeView/StringTable.h"
Zachary Turneredef1452017-05-02 16:56:09 +000016
17using namespace llvm;
18using namespace llvm::codeview;
19
20Error VarStreamArrayExtractor<InlineeSourceLine>::extract(
21 BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item,
Zachary Turner59e83892017-05-03 05:34:00 +000022 bool HasExtraFiles) {
Zachary Turneredef1452017-05-02 16:56:09 +000023 BinaryStreamReader Reader(Stream);
24
25 if (auto EC = Reader.readObject(Item.Header))
26 return EC;
27
Zachary Turner59e83892017-05-03 05:34:00 +000028 if (HasExtraFiles) {
Zachary Turneredef1452017-05-02 16:56:09 +000029 uint32_t ExtraFileCount;
30 if (auto EC = Reader.readInteger(ExtraFileCount))
31 return EC;
32 if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
33 return EC;
34 }
35
36 Len = Reader.getOffset();
37 return Error::success();
38}
39
Zachary Turner8c099fe2017-05-30 16:36:15 +000040DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef()
41 : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {}
Zachary Turneredef1452017-05-02 16:56:09 +000042
Zachary Turner8c099fe2017-05-30 16:36:15 +000043Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
Zachary Turneredef1452017-05-02 16:56:09 +000044 if (auto EC = Reader.readEnum(Signature))
45 return EC;
46
Zachary Turner59e83892017-05-03 05:34:00 +000047 if (auto EC =
48 Reader.readArray(Lines, Reader.bytesRemaining(), hasExtraFiles()))
Zachary Turneredef1452017-05-02 16:56:09 +000049 return EC;
50
51 assert(Reader.bytesRemaining() == 0);
52 return Error::success();
53}
54
Zachary Turner8c099fe2017-05-30 16:36:15 +000055bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const {
Zachary Turneredef1452017-05-02 16:56:09 +000056 return Signature == InlineeLinesSignature::ExtraFiles;
57}
58
Zachary Turner8c099fe2017-05-30 16:36:15 +000059DebugInlineeLinesSubsection::DebugInlineeLinesSubsection(
60 DebugChecksumsSubsection &Checksums, bool HasExtraFiles)
61 : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums),
62 HasExtraFiles(HasExtraFiles) {}
Zachary Turneredef1452017-05-02 16:56:09 +000063
Zachary Turner8c099fe2017-05-30 16:36:15 +000064uint32_t DebugInlineeLinesSubsection::calculateSerializedLength() {
Zachary Turneredef1452017-05-02 16:56:09 +000065 // 4 bytes for the signature
66 uint32_t Size = sizeof(InlineeLinesSignature);
67
68 // one header for each entry.
69 Size += Entries.size() * sizeof(InlineeSourceLineHeader);
70 if (HasExtraFiles) {
71 // If extra files are enabled, one count for each entry.
72 Size += Entries.size() * sizeof(uint32_t);
73
74 // And one file id for each file.
75 Size += ExtraFileCount * sizeof(uint32_t);
76 }
77 assert(Size % 4 == 0);
78 return Size;
79}
80
Zachary Turner8c099fe2017-05-30 16:36:15 +000081Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) {
Zachary Turneredef1452017-05-02 16:56:09 +000082 InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
83 if (HasExtraFiles)
84 Sig = InlineeLinesSignature::ExtraFiles;
85
86 if (auto EC = Writer.writeEnum(Sig))
87 return EC;
88
89 for (const auto &E : Entries) {
90 if (auto EC = Writer.writeObject(E.Header))
91 return EC;
92
93 if (!HasExtraFiles)
94 continue;
95
96 if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
97 return EC;
98 if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles)))
99 return EC;
100 }
101
102 return Error::success();
103}
104
Zachary Turner8c099fe2017-05-30 16:36:15 +0000105void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) {
Zachary Turnercf468d82017-05-03 17:11:40 +0000106 uint32_t Offset = Checksums.mapChecksumOffset(FileName);
107
Zachary Turneredef1452017-05-02 16:56:09 +0000108 auto &Entry = Entries.back();
Zachary Turnercf468d82017-05-03 17:11:40 +0000109 Entry.ExtraFiles.push_back(ulittle32_t(Offset));
Zachary Turneredef1452017-05-02 16:56:09 +0000110 ++ExtraFileCount;
111}
112
Zachary Turner8c099fe2017-05-30 16:36:15 +0000113void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId,
114 StringRef FileName,
115 uint32_t SourceLine) {
Zachary Turnercf468d82017-05-03 17:11:40 +0000116 uint32_t Offset = Checksums.mapChecksumOffset(FileName);
117
Zachary Turneredef1452017-05-02 16:56:09 +0000118 Entries.emplace_back();
119 auto &Entry = Entries.back();
Zachary Turnercf468d82017-05-03 17:11:40 +0000120 Entry.Header.FileID = Offset;
Zachary Turneredef1452017-05-02 16:56:09 +0000121 Entry.Header.SourceLineNum = SourceLine;
122 Entry.Header.Inlinee = FuncId;
123}