Line data Source code
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 1120 : class SymbolDeserializer : public SymbolVisitorCallbacks {
26 : struct MappingInfo {
27 : MappingInfo(ArrayRef<uint8_t> RecordData, CodeViewContainer Container)
28 0 : : Stream(RecordData, llvm::support::little), Reader(Stream),
29 0 : Mapping(Reader, Container) {}
30 :
31 : BinaryByteStream Stream;
32 : BinaryStreamReader Reader;
33 : SymbolRecordMapping Mapping;
34 : };
35 :
36 : public:
37 653 : 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 1306 : if (auto EC = S.visitSymbolBegin(Symbol))
42 : return EC;
43 653 : if (auto EC = S.visitKnownRecord(Symbol, Record))
44 : return EC;
45 1306 : if (auto EC = S.visitSymbolEnd(Symbol))
46 : return EC;
47 : return Error::success();
48 : }
49 341 : template <typename T> static Expected<T> deserializeAs(CVSymbol Symbol) {
50 341 : T Record(Symbol.kind());
51 341 : if (auto EC = deserializeAs<T>(Symbol, Record))
52 : return std::move(EC);
53 0 : return Record;
54 : }
55 0 :
56 : explicit SymbolDeserializer(SymbolVisitorDelegate *Delegate,
57 0 : CodeViewContainer Container)
58 808 : : Delegate(Delegate), Container(Container) {}
59 :
60 327 : Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override {
61 327 : return visitSymbolBegin(Record);
62 : }
63 :
64 737 : Error visitSymbolBegin(CVSymbol &Record) override {
65 0 : assert(!Mapping && "Already in a symbol mapping!");
66 737 : Mapping = llvm::make_unique<MappingInfo>(Record.content(), Container);
67 737 : return Mapping->Mapping.visitSymbolBegin(Record);
68 : }
69 743 : Error visitSymbolEnd(CVSymbol &Record) override {
70 : assert(Mapping && "Not in a symbol mapping!");
71 743 : auto EC = Mapping->Mapping.visitSymbolEnd(Record);
72 : Mapping.reset();
73 750 : return EC;
74 : }
75 :
76 : #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
77 14 : Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
78 : return visitKnownRecordImpl(CVR, Record); \
79 7 : }
80 : #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
81 14 : #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
82 :
83 : private:
84 737 : template <typename T> Error visitKnownRecordImpl(CVSymbol &CVR, T &Record) {
85 0 :
86 1474 : Record.RecordOffset =
87 737 : Delegate ? Delegate->getRecordOffset(Mapping->Reader) : 0;
88 1474 : if (auto EC = Mapping->Mapping.visitKnownRecord(CVR, Record))
89 0 : return EC;
90 : return Error::success();
91 0 : }
92 :
93 0 : SymbolVisitorDelegate *Delegate;
94 : CodeViewContainer Container;
95 : std::unique_ptr<MappingInfo> Mapping;
96 : };
97 0 : }
98 : }
99 :
100 : #endif
|