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 20namespace llvm { 21namespace codeview { 22 23struct LineColumnEntry { 24 support::ulittle32_t NameIndex; 25 FixedStreamArray<LineNumberEntry> LineNumbers; 26 FixedStreamArray<ColumnNumberEntry> Columns; 27}; 28 29template <> class VarStreamArrayExtractor<LineColumnEntry> { 30public: 31 VarStreamArrayExtractor(const LineSubstreamHeader *Header) : Header(Header) {} 32 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 63private: 64 const LineSubstreamHeader *Header; 65}; 66 67struct 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 73template <> class VarStreamArrayExtractor<FileChecksumEntry> { 74public: 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 90typedef VarStreamArray<LineColumnEntry> LineInfoArray; 91typedef VarStreamArray<FileChecksumEntry> FileChecksumArray; 92 93class IModuleSubstreamVisitor { 94public: 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 115Error visitModuleSubstream(const ModuleSubstream &R, 116 IModuleSubstreamVisitor &V); 117 118} // namespace codeview 119} // namespace llvm 120 121#endif // LLVM_DEBUGINFO_CODEVIEW_MODULESUBSTREAMVISITOR_H 122