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