1 //===- SymbolDeserializer.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_SYMBOLDESERIALIZER_H 11 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDESERIALIZER_H 12 13 #include "llvm/ADT/ArrayRef.h" 14 #include "llvm/DebugInfo/CodeView/SymbolRecord.h" 15 #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h" 16 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h" 17 #include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h" 18 #include "llvm/Support/BinaryByteStream.h" 19 #include "llvm/Support/BinaryStreamReader.h" 20 #include "llvm/Support/Error.h" 21 22 namespace llvm { 23 namespace codeview { 24 class SymbolVisitorDelegate; 25 class SymbolDeserializer : public SymbolVisitorCallbacks { 26 struct MappingInfo { 27 MappingInfo(ArrayRef<uint8_t> RecordData, CodeViewContainer Container) 28 : Stream(RecordData, llvm::support::little), Reader(Stream), 29 Mapping(Reader, Container) {} 30 31 BinaryByteStream Stream; 32 BinaryStreamReader Reader; 33 SymbolRecordMapping Mapping; 34 }; 35 36 public: 37 template <typename T> static Error deserializeAs(CVSymbol Symbol, T &Record) { 38 // If we're just deserializing one record, then don't worry about alignment 39 // as there's nothing that comes after. 40 SymbolDeserializer S(nullptr, CodeViewContainer::ObjectFile); 41 if (auto EC = S.visitSymbolBegin(Symbol)) 42 return EC; 43 if (auto EC = S.visitKnownRecord(Symbol, Record)) 44 return EC; 45 if (auto EC = S.visitSymbolEnd(Symbol)) 46 return EC; 47 return Error::success(); 48 } 49 50 explicit SymbolDeserializer(SymbolVisitorDelegate *Delegate, 51 CodeViewContainer Container) 52 : Delegate(Delegate), Container(Container) {} 53 54 Error visitSymbolBegin(CVSymbol &Record) override { 55 assert(!Mapping && "Already in a symbol mapping!"); 56 Mapping = llvm::make_unique<MappingInfo>(Record.content(), Container); 57 return Mapping->Mapping.visitSymbolBegin(Record); 58 } 59 Error visitSymbolEnd(CVSymbol &Record) override { 60 assert(Mapping && "Not in a symbol mapping!"); 61 auto EC = Mapping->Mapping.visitSymbolEnd(Record); 62 Mapping.reset(); 63 return EC; 64 } 65 66 #define SYMBOL_RECORD(EnumName, EnumVal, Name) \ 67 Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \ 68 return visitKnownRecordImpl(CVR, Record); \ 69 } 70 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) 71 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def" 72 73 private: 74 template <typename T> Error visitKnownRecordImpl(CVSymbol &CVR, T &Record) { 75 76 Record.RecordOffset = 77 Delegate ? Delegate->getRecordOffset(Mapping->Reader) : 0; 78 if (auto EC = Mapping->Mapping.visitKnownRecord(CVR, Record)) 79 return EC; 80 return Error::success(); 81 } 82 83 SymbolVisitorDelegate *Delegate; 84 CodeViewContainer Container; 85 std::unique_ptr<MappingInfo> Mapping; 86 }; 87 } 88 } 89 90 #endif 91