brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · adc6cab Raw
94 lines · cpp
1//===- DebugSubsectionRecord.cpp ------------------------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 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"16#include <cassert>17#include <cstdint>18 19using namespace llvm;20using namespace llvm::codeview;21 22DebugSubsectionRecord::DebugSubsectionRecord() = default;23 24DebugSubsectionRecord::DebugSubsectionRecord(DebugSubsectionKind Kind,25                                             BinaryStreamRef Data)26    : Kind(Kind), Data(Data) {}27 28Error DebugSubsectionRecord::initialize(BinaryStreamRef Stream,29                                        DebugSubsectionRecord &Info) {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  if (auto EC = Reader.readStreamRef(Info.Data, Header->Length))38    return EC;39  Info.Kind = Kind;40  return Error::success();41}42 43uint32_t DebugSubsectionRecord::getRecordLength() const {44  return sizeof(DebugSubsectionHeader) + Data.getLength();45}46 47DebugSubsectionKind DebugSubsectionRecord::kind() const { return Kind; }48 49BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; }50 51DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(52    std::shared_ptr<DebugSubsection> Subsection)53    : Subsection(std::move(Subsection)) {}54 55DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(56    const DebugSubsectionRecord &Contents)57    : Contents(Contents) {}58 59uint32_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);65}66 67Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer,68                                           CodeViewContainer Container) const {69  assert(Writer.getOffset() % alignOf(Container) == 0 &&70         "Debug Subsection not properly aligned");71 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 the75  // container's alignment76  uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()77                                 : Contents.getRecordData().getLength();78  Header.Length = alignTo(DataSize, alignOf(Container));79 80  if (auto EC = Writer.writeObject(Header))81    return EC;82  if (Subsection) {83    if (auto EC = Subsection->commit(Writer))84      return EC;85  } else {86    if (auto EC = Writer.writeStreamRef(Contents.getRecordData()))87      return EC;88  }89  if (auto EC = Writer.padToAlignment(4))90    return EC;91 92  return Error::success();93}94