xref: /aosp_15_r20/external/llvm/include/llvm/DebugInfo/CodeView/ModuleSubstreamVisitor.h (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1  //===- ModuleSubstreamVisitor.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_MODULESUBSTREAMVISITOR_H
11  #define LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
12  
13  #include "llvm/DebugInfo/CodeView/CodeView.h"
14  #include "llvm/DebugInfo/CodeView/CodeViewError.h"
15  #include "llvm/DebugInfo/CodeView/Line.h"
16  #include "llvm/DebugInfo/CodeView/ModuleSubstream.h"
17  #include "llvm/DebugInfo/CodeView/StreamReader.h"
18  #include "llvm/DebugInfo/CodeView/StreamRef.h"
19  
20  namespace llvm {
21  namespace codeview {
22  
23  struct LineColumnEntry {
24    support::ulittle32_t NameIndex;
25    FixedStreamArray<LineNumberEntry> LineNumbers;
26    FixedStreamArray<ColumnNumberEntry> Columns;
27  };
28  
29  template <> class VarStreamArrayExtractor<LineColumnEntry> {
30  public:
VarStreamArrayExtractor(const LineSubstreamHeader * Header)31    VarStreamArrayExtractor(const LineSubstreamHeader *Header) : Header(Header) {}
32  
operator()33    Error operator()(StreamRef Stream, uint32_t &Len,
34                     LineColumnEntry &Item) const {
35      const LineFileBlockHeader *BlockHeader;
36      StreamReader Reader(Stream);
37      if (auto EC = Reader.readObject(BlockHeader))
38        return EC;
39      bool HasColumn = Header->Flags & LineFlags::HaveColumns;
40      uint32_t LineInfoSize =
41          BlockHeader->NumLines *
42          (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
43      if (BlockHeader->BlockSize < sizeof(LineFileBlockHeader))
44        return make_error<CodeViewError>(cv_error_code::corrupt_record,
45                                         "Invalid line block record size");
46      uint32_t Size = BlockHeader->BlockSize - sizeof(LineFileBlockHeader);
47      if (LineInfoSize > Size)
48        return make_error<CodeViewError>(cv_error_code::corrupt_record,
49                                         "Invalid line block record size");
50      // The value recorded in BlockHeader->BlockSize includes the size of
51      // LineFileBlockHeader.
52      Len = BlockHeader->BlockSize;
53      Item.NameIndex = BlockHeader->NameIndex;
54      if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
55        return EC;
56      if (HasColumn) {
57        if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines))
58          return EC;
59      }
60      return Error::success();
61    }
62  
63  private:
64    const LineSubstreamHeader *Header;
65  };
66  
67  struct FileChecksumEntry {
68    uint32_t FileNameOffset;    // Byte offset of filename in global stringtable.
69    FileChecksumKind Kind;      // The type of checksum.
70    ArrayRef<uint8_t> Checksum; // The bytes of the checksum.
71  };
72  
73  template <> class VarStreamArrayExtractor<FileChecksumEntry> {
74  public:
operator()75    Error operator()(StreamRef Stream, uint32_t &Len,
76                     FileChecksumEntry &Item) const {
77      const FileChecksum *Header;
78      StreamReader Reader(Stream);
79      if (auto EC = Reader.readObject(Header))
80        return EC;
81      Item.FileNameOffset = Header->FileNameOffset;
82      Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);
83      if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))
84        return EC;
85      Len = sizeof(FileChecksum) + Header->ChecksumSize;
86      return Error::success();
87    }
88  };
89  
90  typedef VarStreamArray<LineColumnEntry> LineInfoArray;
91  typedef VarStreamArray<FileChecksumEntry> FileChecksumArray;
92  
93  class IModuleSubstreamVisitor {
94  public:
~IModuleSubstreamVisitor()95    virtual ~IModuleSubstreamVisitor() {}
96  
97    virtual Error visitUnknown(ModuleSubstreamKind Kind, StreamRef Data) = 0;
98    virtual Error visitSymbols(StreamRef Data);
99    virtual Error visitLines(StreamRef Data, const LineSubstreamHeader *Header,
100                             const LineInfoArray &Lines);
101    virtual Error visitStringTable(StreamRef Data);
102    virtual Error visitFileChecksums(StreamRef Data,
103                                     const FileChecksumArray &Checksums);
104    virtual Error visitFrameData(StreamRef Data);
105    virtual Error visitInlineeLines(StreamRef Data);
106    virtual Error visitCrossScopeImports(StreamRef Data);
107    virtual Error visitCrossScopeExports(StreamRef Data);
108    virtual Error visitILLines(StreamRef Data);
109    virtual Error visitFuncMDTokenMap(StreamRef Data);
110    virtual Error visitTypeMDTokenMap(StreamRef Data);
111    virtual Error visitMergedAssemblyInput(StreamRef Data);
112    virtual Error visitCoffSymbolRVA(StreamRef Data);
113  };
114  
115  Error visitModuleSubstream(const ModuleSubstream &R,
116                             IModuleSubstreamVisitor &V);
117  
118  } // namespace codeview
119  } // namespace llvm
120  
121  #endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H
122