18c099fe0SZachary Turner //===- DebugSubsectionRecord.cpp -----------------------------*- C++-*-===// 28c099fe0SZachary Turner // 38c099fe0SZachary Turner // The LLVM Compiler Infrastructure 48c099fe0SZachary Turner // 58c099fe0SZachary Turner // This file is distributed under the University of Illinois Open Source 68c099fe0SZachary Turner // License. See LICENSE.TXT for details. 78c099fe0SZachary Turner // 88c099fe0SZachary Turner //===----------------------------------------------------------------------===// 98c099fe0SZachary Turner 108c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h" 118c099fe0SZachary Turner #include "llvm/DebugInfo/CodeView/DebugSubsection.h" 128c099fe0SZachary Turner 138c099fe0SZachary Turner #include "llvm/Support/BinaryStreamReader.h" 148c099fe0SZachary Turner 158c099fe0SZachary Turner using namespace llvm; 168c099fe0SZachary Turner using namespace llvm::codeview; 178c099fe0SZachary Turner 188c099fe0SZachary Turner DebugSubsectionRecord::DebugSubsectionRecord() 19afb81a83SZachary Turner : Container(CodeViewContainer::ObjectFile), 20afb81a83SZachary Turner Kind(DebugSubsectionKind::None) {} 218c099fe0SZachary Turner 228c099fe0SZachary Turner DebugSubsectionRecord::DebugSubsectionRecord(DebugSubsectionKind Kind, 23ebd3ae83SZachary Turner BinaryStreamRef Data, 24ebd3ae83SZachary Turner CodeViewContainer Container) 25afb81a83SZachary Turner : Container(Container), Kind(Kind), Data(Data) {} 268c099fe0SZachary Turner 278c099fe0SZachary Turner Error DebugSubsectionRecord::initialize(BinaryStreamRef Stream, 28ebd3ae83SZachary Turner DebugSubsectionRecord &Info, 29ebd3ae83SZachary Turner CodeViewContainer Container) { 308c099fe0SZachary Turner const DebugSubsectionHeader *Header; 318c099fe0SZachary Turner BinaryStreamReader Reader(Stream); 328c099fe0SZachary Turner if (auto EC = Reader.readObject(Header)) 338c099fe0SZachary Turner return EC; 348c099fe0SZachary Turner 358c099fe0SZachary Turner DebugSubsectionKind Kind = 368c099fe0SZachary Turner static_cast<DebugSubsectionKind>(uint32_t(Header->Kind)); 378c099fe0SZachary Turner switch (Kind) { 388c099fe0SZachary Turner case DebugSubsectionKind::FileChecksums: 398c099fe0SZachary Turner case DebugSubsectionKind::Lines: 408c099fe0SZachary Turner case DebugSubsectionKind::InlineeLines: 41349c18f8SZachary Turner case DebugSubsectionKind::CrossScopeExports: 42349c18f8SZachary Turner case DebugSubsectionKind::CrossScopeImports: 43*deb39130SZachary Turner case DebugSubsectionKind::Symbols: 44*deb39130SZachary Turner case DebugSubsectionKind::StringTable: 45*deb39130SZachary Turner case DebugSubsectionKind::FrameData: 468c099fe0SZachary Turner break; 478c099fe0SZachary Turner default: 488c099fe0SZachary Turner llvm_unreachable("Unexpected debug fragment kind!"); 498c099fe0SZachary Turner } 508c099fe0SZachary Turner if (auto EC = Reader.readStreamRef(Info.Data, Header->Length)) 518c099fe0SZachary Turner return EC; 52ebd3ae83SZachary Turner Info.Container = Container; 538c099fe0SZachary Turner Info.Kind = Kind; 548c099fe0SZachary Turner return Error::success(); 558c099fe0SZachary Turner } 568c099fe0SZachary Turner 578c099fe0SZachary Turner uint32_t DebugSubsectionRecord::getRecordLength() const { 58*deb39130SZachary Turner return sizeof(DebugSubsectionHeader) + Data.getLength(); 598c099fe0SZachary Turner } 608c099fe0SZachary Turner 618c099fe0SZachary Turner DebugSubsectionKind DebugSubsectionRecord::kind() const { return Kind; } 628c099fe0SZachary Turner 638c099fe0SZachary Turner BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; } 648c099fe0SZachary Turner 658c099fe0SZachary Turner DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder( 6692dcdda6SZachary Turner std::unique_ptr<DebugSubsection> Subsection, CodeViewContainer Container) 6792dcdda6SZachary Turner : Subsection(std::move(Subsection)), Container(Container) {} 688c099fe0SZachary Turner 698c099fe0SZachary Turner uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() { 70*deb39130SZachary Turner // The length of the entire subsection is always padded to 4 bytes, regardless 71*deb39130SZachary Turner // of the container kind. 72*deb39130SZachary Turner uint32_t Size = sizeof(DebugSubsectionHeader) + 73*deb39130SZachary Turner alignTo(Subsection->calculateSerializedSize(), 4); 748c099fe0SZachary Turner return Size; 758c099fe0SZachary Turner } 768c099fe0SZachary Turner 77*deb39130SZachary Turner Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer) const { 78ebd3ae83SZachary Turner assert(Writer.getOffset() % alignOf(Container) == 0 && 79ebd3ae83SZachary Turner "Debug Subsection not properly aligned"); 80ebd3ae83SZachary Turner 818c099fe0SZachary Turner DebugSubsectionHeader Header; 8292dcdda6SZachary Turner Header.Kind = uint32_t(Subsection->kind()); 83*deb39130SZachary Turner // The value written into the Header's Length field is only padded to the 84*deb39130SZachary Turner // container's alignment 85*deb39130SZachary Turner Header.Length = 86*deb39130SZachary Turner alignTo(Subsection->calculateSerializedSize(), alignOf(Container)); 878c099fe0SZachary Turner 888c099fe0SZachary Turner if (auto EC = Writer.writeObject(Header)) 898c099fe0SZachary Turner return EC; 9092dcdda6SZachary Turner if (auto EC = Subsection->commit(Writer)) 918c099fe0SZachary Turner return EC; 92*deb39130SZachary Turner if (auto EC = Writer.padToAlignment(4)) 938c099fe0SZachary Turner return EC; 948c099fe0SZachary Turner 958c099fe0SZachary Turner return Error::success(); 968c099fe0SZachary Turner } 97