1*8c099fe0SZachary Turner //===- DebugSubsectionRecord.cpp -----------------------------*- C++-*-===//
2*8c099fe0SZachary Turner //
3*8c099fe0SZachary Turner //                     The LLVM Compiler Infrastructure
4*8c099fe0SZachary Turner //
5*8c099fe0SZachary Turner // This file is distributed under the University of Illinois Open Source
6*8c099fe0SZachary Turner // License. See LICENSE.TXT for details.
7*8c099fe0SZachary Turner //
8*8c099fe0SZachary Turner //===----------------------------------------------------------------------===//
9*8c099fe0SZachary Turner 
10*8c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
11*8c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSubsection.h"
12*8c099fe0SZachary Turner 
13*8c099fe0SZachary Turner #include "llvm/Support/BinaryStreamReader.h"
14*8c099fe0SZachary Turner 
15*8c099fe0SZachary Turner using namespace llvm;
16*8c099fe0SZachary Turner using namespace llvm::codeview;
17*8c099fe0SZachary Turner 
18*8c099fe0SZachary Turner DebugSubsectionRecord::DebugSubsectionRecord()
19*8c099fe0SZachary Turner     : Kind(DebugSubsectionKind::None) {}
20*8c099fe0SZachary Turner 
21*8c099fe0SZachary Turner DebugSubsectionRecord::DebugSubsectionRecord(DebugSubsectionKind Kind,
22*8c099fe0SZachary Turner                                              BinaryStreamRef Data)
23*8c099fe0SZachary Turner     : Kind(Kind), Data(Data) {}
24*8c099fe0SZachary Turner 
25*8c099fe0SZachary Turner Error DebugSubsectionRecord::initialize(BinaryStreamRef Stream,
26*8c099fe0SZachary Turner                                         DebugSubsectionRecord &Info) {
27*8c099fe0SZachary Turner   const DebugSubsectionHeader *Header;
28*8c099fe0SZachary Turner   BinaryStreamReader Reader(Stream);
29*8c099fe0SZachary Turner   if (auto EC = Reader.readObject(Header))
30*8c099fe0SZachary Turner     return EC;
31*8c099fe0SZachary Turner 
32*8c099fe0SZachary Turner   DebugSubsectionKind Kind =
33*8c099fe0SZachary Turner       static_cast<DebugSubsectionKind>(uint32_t(Header->Kind));
34*8c099fe0SZachary Turner   switch (Kind) {
35*8c099fe0SZachary Turner   case DebugSubsectionKind::FileChecksums:
36*8c099fe0SZachary Turner   case DebugSubsectionKind::Lines:
37*8c099fe0SZachary Turner   case DebugSubsectionKind::InlineeLines:
38*8c099fe0SZachary Turner     break;
39*8c099fe0SZachary Turner   default:
40*8c099fe0SZachary Turner     llvm_unreachable("Unexpected debug fragment kind!");
41*8c099fe0SZachary Turner   }
42*8c099fe0SZachary Turner   if (auto EC = Reader.readStreamRef(Info.Data, Header->Length))
43*8c099fe0SZachary Turner     return EC;
44*8c099fe0SZachary Turner   Info.Kind = Kind;
45*8c099fe0SZachary Turner   return Error::success();
46*8c099fe0SZachary Turner }
47*8c099fe0SZachary Turner 
48*8c099fe0SZachary Turner uint32_t DebugSubsectionRecord::getRecordLength() const {
49*8c099fe0SZachary Turner   uint32_t Result = sizeof(DebugSubsectionHeader) + Data.getLength();
50*8c099fe0SZachary Turner   assert(Result % 4 == 0);
51*8c099fe0SZachary Turner   return Result;
52*8c099fe0SZachary Turner }
53*8c099fe0SZachary Turner 
54*8c099fe0SZachary Turner DebugSubsectionKind DebugSubsectionRecord::kind() const { return Kind; }
55*8c099fe0SZachary Turner 
56*8c099fe0SZachary Turner BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; }
57*8c099fe0SZachary Turner 
58*8c099fe0SZachary Turner DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
59*8c099fe0SZachary Turner     DebugSubsectionKind Kind, DebugSubsection &Frag)
60*8c099fe0SZachary Turner     : Kind(Kind), Frag(Frag) {}
61*8c099fe0SZachary Turner 
62*8c099fe0SZachary Turner uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() {
63*8c099fe0SZachary Turner   uint32_t Size = sizeof(DebugSubsectionHeader) +
64*8c099fe0SZachary Turner                   alignTo(Frag.calculateSerializedLength(), 4);
65*8c099fe0SZachary Turner   return Size;
66*8c099fe0SZachary Turner }
67*8c099fe0SZachary Turner 
68*8c099fe0SZachary Turner Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) {
69*8c099fe0SZachary Turner   DebugSubsectionHeader Header;
70*8c099fe0SZachary Turner   Header.Kind = uint32_t(Kind);
71*8c099fe0SZachary Turner   Header.Length = calculateSerializedLength() - sizeof(DebugSubsectionHeader);
72*8c099fe0SZachary Turner 
73*8c099fe0SZachary Turner   if (auto EC = Writer.writeObject(Header))
74*8c099fe0SZachary Turner     return EC;
75*8c099fe0SZachary Turner   if (auto EC = Frag.commit(Writer))
76*8c099fe0SZachary Turner     return EC;
77*8c099fe0SZachary Turner   if (auto EC = Writer.padToAlignment(4))
78*8c099fe0SZachary Turner     return EC;
79*8c099fe0SZachary Turner 
80*8c099fe0SZachary Turner   return Error::success();
81*8c099fe0SZachary Turner }
82