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