123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- SymbolDeserializer.h -------------------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLDESERIALIZER_H
- #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLDESERIALIZER_H
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
- #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
- #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
- #include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h"
- #include "llvm/Support/BinaryByteStream.h"
- #include "llvm/Support/BinaryStreamReader.h"
- #include "llvm/Support/Error.h"
- namespace llvm {
- namespace codeview {
- class SymbolVisitorDelegate;
- class SymbolDeserializer : public SymbolVisitorCallbacks {
- struct MappingInfo {
- MappingInfo(ArrayRef<uint8_t> RecordData, CodeViewContainer Container)
- : Stream(RecordData, llvm::support::little), Reader(Stream),
- Mapping(Reader, Container) {}
- BinaryByteStream Stream;
- BinaryStreamReader Reader;
- SymbolRecordMapping Mapping;
- };
- public:
- template <typename T> static Error deserializeAs(CVSymbol Symbol, T &Record) {
- // If we're just deserializing one record, then don't worry about alignment
- // as there's nothing that comes after.
- SymbolDeserializer S(nullptr, CodeViewContainer::ObjectFile);
- if (auto EC = S.visitSymbolBegin(Symbol))
- return EC;
- if (auto EC = S.visitKnownRecord(Symbol, Record))
- return EC;
- if (auto EC = S.visitSymbolEnd(Symbol))
- return EC;
- return Error::success();
- }
- template <typename T> static Expected<T> deserializeAs(CVSymbol Symbol) {
- T Record(static_cast<SymbolRecordKind>(Symbol.kind()));
- if (auto EC = deserializeAs<T>(Symbol, Record))
- return std::move(EC);
- return Record;
- }
- explicit SymbolDeserializer(SymbolVisitorDelegate *Delegate,
- CodeViewContainer Container)
- : Delegate(Delegate), Container(Container) {}
- Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override {
- return visitSymbolBegin(Record);
- }
- Error visitSymbolBegin(CVSymbol &Record) override {
- assert(!Mapping && "Already in a symbol mapping!");
- Mapping = std::make_unique<MappingInfo>(Record.content(), Container);
- return Mapping->Mapping.visitSymbolBegin(Record);
- }
- Error visitSymbolEnd(CVSymbol &Record) override {
- assert(Mapping && "Not in a symbol mapping!");
- auto EC = Mapping->Mapping.visitSymbolEnd(Record);
- Mapping.reset();
- return EC;
- }
- #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
- return visitKnownRecordImpl(CVR, Record); \
- }
- #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
- #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
- private:
- template <typename T> Error visitKnownRecordImpl(CVSymbol &CVR, T &Record) {
- Record.RecordOffset =
- Delegate ? Delegate->getRecordOffset(Mapping->Reader) : 0;
- if (auto EC = Mapping->Mapping.visitKnownRecord(CVR, Record))
- return EC;
- return Error::success();
- }
- SymbolVisitorDelegate *Delegate;
- CodeViewContainer Container;
- std::unique_ptr<MappingInfo> Mapping;
- };
- }
- }
- #endif
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|