1 //===- DebugSubsectionRecord.cpp ------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
10 #include "llvm/DebugInfo/CodeView/CodeView.h"
11 #include "llvm/DebugInfo/CodeView/DebugSubsection.h"
12 #include "llvm/Support/BinaryStreamReader.h"
13 #include "llvm/Support/BinaryStreamWriter.h"
14 #include "llvm/Support/Error.h"
15 #include "llvm/Support/MathExtras.h"
20 using namespace llvm::codeview
;
22 DebugSubsectionRecord::DebugSubsectionRecord() = default;
24 DebugSubsectionRecord::DebugSubsectionRecord(DebugSubsectionKind Kind
,
26 : Kind(Kind
), Data(Data
) {}
28 Error
DebugSubsectionRecord::initialize(BinaryStreamRef Stream
,
29 DebugSubsectionRecord
&Info
) {
30 const DebugSubsectionHeader
*Header
;
31 BinaryStreamReader
Reader(Stream
);
32 if (auto EC
= Reader
.readObject(Header
))
35 DebugSubsectionKind Kind
=
36 static_cast<DebugSubsectionKind
>(uint32_t(Header
->Kind
));
37 if (auto EC
= Reader
.readStreamRef(Info
.Data
, Header
->Length
))
40 return Error::success();
43 uint32_t DebugSubsectionRecord::getRecordLength() const {
44 return sizeof(DebugSubsectionHeader
) + Data
.getLength();
47 DebugSubsectionKind
DebugSubsectionRecord::kind() const { return Kind
; }
49 BinaryStreamRef
DebugSubsectionRecord::getRecordData() const { return Data
; }
51 DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
52 std::shared_ptr
<DebugSubsection
> Subsection
)
53 : Subsection(std::move(Subsection
)) {}
55 DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
56 const DebugSubsectionRecord
&Contents
)
57 : Contents(Contents
) {}
59 uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() const {
60 uint32_t DataSize
= Subsection
? Subsection
->calculateSerializedSize()
61 : Contents
.getRecordData().getLength();
62 // The length of the entire subsection is always padded to 4 bytes,
63 // regardless of the container kind.
64 return sizeof(DebugSubsectionHeader
) + alignTo(DataSize
, 4);
67 Error
DebugSubsectionRecordBuilder::commit(BinaryStreamWriter
&Writer
,
68 CodeViewContainer Container
) const {
69 assert(Writer
.getOffset() % alignOf(Container
) == 0 &&
70 "Debug Subsection not properly aligned");
72 DebugSubsectionHeader Header
;
73 Header
.Kind
= uint32_t(Subsection
? Subsection
->kind() : Contents
.kind());
74 // The value written into the Header's Length field is only padded to the
75 // container's alignment
76 uint32_t DataSize
= Subsection
? Subsection
->calculateSerializedSize()
77 : Contents
.getRecordData().getLength();
78 Header
.Length
= alignTo(DataSize
, alignOf(Container
));
80 if (auto EC
= Writer
.writeObject(Header
))
83 if (auto EC
= Subsection
->commit(Writer
))
86 if (auto EC
= Writer
.writeStreamRef(Contents
.getRecordData()))
89 if (auto EC
= Writer
.padToAlignment(4))
92 return Error::success();