1 //===- DebugSubsectionRecord.cpp -----------------------------*- C++-*-===// 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/DebugSubsectionRecord.h" 11 #include "llvm/DebugInfo/CodeView/DebugSubsection.h" 12 13 #include "llvm/Support/BinaryStreamReader.h" 14 15 using namespace llvm; 16 using namespace llvm::codeview; 17 18 DebugSubsectionRecord::DebugSubsectionRecord() 19 : Container(CodeViewContainer::ObjectFile), 20 Kind(DebugSubsectionKind::None) {} 21 22 DebugSubsectionRecord::DebugSubsectionRecord(DebugSubsectionKind Kind, 23 BinaryStreamRef Data, 24 CodeViewContainer Container) 25 : Container(Container), Kind(Kind), Data(Data) {} 26 27 Error DebugSubsectionRecord::initialize(BinaryStreamRef Stream, 28 DebugSubsectionRecord &Info, 29 CodeViewContainer Container) { 30 const DebugSubsectionHeader *Header; 31 BinaryStreamReader Reader(Stream); 32 if (auto EC = Reader.readObject(Header)) 33 return EC; 34 35 DebugSubsectionKind Kind = 36 static_cast<DebugSubsectionKind>(uint32_t(Header->Kind)); 37 switch (Kind) { 38 case DebugSubsectionKind::FileChecksums: 39 case DebugSubsectionKind::Lines: 40 case DebugSubsectionKind::InlineeLines: 41 break; 42 default: 43 llvm_unreachable("Unexpected debug fragment kind!"); 44 } 45 if (auto EC = Reader.readStreamRef(Info.Data, Header->Length)) 46 return EC; 47 Info.Container = Container; 48 Info.Kind = Kind; 49 return Error::success(); 50 } 51 52 uint32_t DebugSubsectionRecord::getRecordLength() const { 53 uint32_t Result = sizeof(DebugSubsectionHeader) + Data.getLength(); 54 assert(Result % alignOf(Container) == 0); 55 return Result; 56 } 57 58 DebugSubsectionKind DebugSubsectionRecord::kind() const { return Kind; } 59 60 BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; } 61 62 DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder( 63 DebugSubsectionKind Kind, DebugSubsection &Frag, 64 CodeViewContainer Container) 65 : Container(Container), Kind(Kind), Frag(Frag) {} 66 67 uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() { 68 uint32_t Size = sizeof(DebugSubsectionHeader) + 69 alignTo(Frag.calculateSerializedSize(), alignOf(Container)); 70 return Size; 71 } 72 73 Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) { 74 assert(Writer.getOffset() % alignOf(Container) == 0 && 75 "Debug Subsection not properly aligned"); 76 77 DebugSubsectionHeader Header; 78 Header.Kind = uint32_t(Kind); 79 Header.Length = calculateSerializedLength() - sizeof(DebugSubsectionHeader); 80 81 if (auto EC = Writer.writeObject(Header)) 82 return EC; 83 if (auto EC = Frag.commit(Writer)) 84 return EC; 85 if (auto EC = Writer.padToAlignment(alignOf(Container))) 86 return EC; 87 88 return Error::success(); 89 } 90