Home | History | Annotate | Download | only in CodeView
      1 //===- DebugSubsectionRecord.h ----------------------------------*- 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 #ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
     11 #define LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
     12 
     13 #include "llvm/DebugInfo/CodeView/CodeView.h"
     14 #include "llvm/Support/BinaryStreamArray.h"
     15 #include "llvm/Support/BinaryStreamRef.h"
     16 #include "llvm/Support/Endian.h"
     17 #include "llvm/Support/Error.h"
     18 #include "llvm/Support/MathExtras.h"
     19 #include <cstdint>
     20 #include <memory>
     21 
     22 namespace llvm {
     23 
     24 class BinaryStreamWriter;
     25 
     26 namespace codeview {
     27 
     28 class DebugSubsection;
     29 
     30 // Corresponds to the `CV_DebugSSubsectionHeader_t` structure.
     31 struct DebugSubsectionHeader {
     32   support::ulittle32_t Kind;   // codeview::DebugSubsectionKind enum
     33   support::ulittle32_t Length; // number of bytes occupied by this record.
     34 };
     35 
     36 class DebugSubsectionRecord {
     37 public:
     38   DebugSubsectionRecord();
     39   DebugSubsectionRecord(DebugSubsectionKind Kind, BinaryStreamRef Data,
     40                         CodeViewContainer Container);
     41 
     42   static Error initialize(BinaryStreamRef Stream, DebugSubsectionRecord &Info,
     43                           CodeViewContainer Container);
     44 
     45   uint32_t getRecordLength() const;
     46   DebugSubsectionKind kind() const;
     47   BinaryStreamRef getRecordData() const;
     48 
     49 private:
     50   CodeViewContainer Container = CodeViewContainer::ObjectFile;
     51   DebugSubsectionKind Kind = DebugSubsectionKind::None;
     52   BinaryStreamRef Data;
     53 };
     54 
     55 class DebugSubsectionRecordBuilder {
     56 public:
     57   DebugSubsectionRecordBuilder(std::shared_ptr<DebugSubsection> Subsection,
     58                                CodeViewContainer Container);
     59 
     60   /// Use this to copy existing subsections directly from source to destination.
     61   /// For example, line table subsections in an object file only need to be
     62   /// relocated before being copied into the PDB.
     63   DebugSubsectionRecordBuilder(const DebugSubsectionRecord &Contents,
     64                                CodeViewContainer Container);
     65 
     66   uint32_t calculateSerializedLength();
     67   Error commit(BinaryStreamWriter &Writer) const;
     68 
     69 private:
     70   /// The subsection to build. Will be null if Contents is non-empty.
     71   std::shared_ptr<DebugSubsection> Subsection;
     72 
     73   /// The bytes of the subsection. Only non-empty if Subsection is null.
     74   DebugSubsectionRecord Contents;
     75 
     76   CodeViewContainer Container;
     77 };
     78 
     79 } // end namespace codeview
     80 
     81 template <> struct VarStreamArrayExtractor<codeview::DebugSubsectionRecord> {
     82   Error operator()(BinaryStreamRef Stream, uint32_t &Length,
     83                    codeview::DebugSubsectionRecord &Info) {
     84     // FIXME: We need to pass the container type through to this function.  In
     85     // practice this isn't super important since the subsection header describes
     86     // its length and we can just skip it.  It's more important when writing.
     87     if (auto EC = codeview::DebugSubsectionRecord::initialize(
     88             Stream, Info, codeview::CodeViewContainer::Pdb))
     89       return EC;
     90     Length = alignTo(Info.getRecordLength(), 4);
     91     return Error::success();
     92   }
     93 };
     94 
     95 namespace codeview {
     96 
     97 using DebugSubsectionArray = VarStreamArray<DebugSubsectionRecord>;
     98 
     99 } // end namespace codeview
    100 
    101 } // end namespace llvm
    102 
    103 #endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGSUBSECTIONRECORD_H
    104