File indexing completed on 2026-05-10 08:43:40
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLDESERIALIZER_H
0010 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDESERIALIZER_H
0011
0012 #include "llvm/ADT/ArrayRef.h"
0013 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
0014 #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
0015 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
0016 #include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h"
0017 #include "llvm/Support/BinaryByteStream.h"
0018 #include "llvm/Support/BinaryStreamReader.h"
0019 #include "llvm/Support/Error.h"
0020
0021 namespace llvm {
0022 namespace codeview {
0023 class SymbolVisitorDelegate;
0024 class SymbolDeserializer : public SymbolVisitorCallbacks {
0025 struct MappingInfo {
0026 MappingInfo(ArrayRef<uint8_t> RecordData, CodeViewContainer Container)
0027 : Stream(RecordData, llvm::endianness::little), Reader(Stream),
0028 Mapping(Reader, Container) {}
0029
0030 BinaryByteStream Stream;
0031 BinaryStreamReader Reader;
0032 SymbolRecordMapping Mapping;
0033 };
0034
0035 public:
0036 template <typename T> static Error deserializeAs(CVSymbol Symbol, T &Record) {
0037
0038
0039 SymbolDeserializer S(nullptr, CodeViewContainer::ObjectFile);
0040 if (auto EC = S.visitSymbolBegin(Symbol))
0041 return EC;
0042 if (auto EC = S.visitKnownRecord(Symbol, Record))
0043 return EC;
0044 if (auto EC = S.visitSymbolEnd(Symbol))
0045 return EC;
0046 return Error::success();
0047 }
0048 template <typename T> static Expected<T> deserializeAs(CVSymbol Symbol) {
0049 T Record(static_cast<SymbolRecordKind>(Symbol.kind()));
0050 if (auto EC = deserializeAs<T>(Symbol, Record))
0051 return std::move(EC);
0052 return Record;
0053 }
0054
0055 explicit SymbolDeserializer(SymbolVisitorDelegate *Delegate,
0056 CodeViewContainer Container)
0057 : Delegate(Delegate), Container(Container) {}
0058
0059 Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override {
0060 return visitSymbolBegin(Record);
0061 }
0062
0063 Error visitSymbolBegin(CVSymbol &Record) override {
0064 assert(!Mapping && "Already in a symbol mapping!");
0065 Mapping = std::make_unique<MappingInfo>(Record.content(), Container);
0066 return Mapping->Mapping.visitSymbolBegin(Record);
0067 }
0068 Error visitSymbolEnd(CVSymbol &Record) override {
0069 assert(Mapping && "Not in a symbol mapping!");
0070 auto EC = Mapping->Mapping.visitSymbolEnd(Record);
0071 Mapping.reset();
0072 return EC;
0073 }
0074
0075 #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
0076 Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
0077 return visitKnownRecordImpl(CVR, Record); \
0078 }
0079 #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
0080 #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
0081
0082 private:
0083 template <typename T> Error visitKnownRecordImpl(CVSymbol &CVR, T &Record) {
0084
0085 Record.RecordOffset =
0086 Delegate ? Delegate->getRecordOffset(Mapping->Reader) : 0;
0087 if (auto EC = Mapping->Mapping.visitKnownRecord(CVR, Record))
0088 return EC;
0089 return Error::success();
0090 }
0091
0092 SymbolVisitorDelegate *Delegate;
0093 CodeViewContainer Container;
0094 std::unique_ptr<MappingInfo> Mapping;
0095 };
0096 }
0097 }
0098
0099 #endif