xref: /freebsd/contrib/llvm-project/llvm/include/llvm/DebugInfo/CodeView/SymbolSerializer.h (revision a90b9d0159070121c221b966469c3e36d912bf82)
1 //===- SymbolSerializer.h ---------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
10 #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
11 
12 #include "llvm/DebugInfo/CodeView/CVRecord.h"
13 #include "llvm/DebugInfo/CodeView/CodeView.h"
14 #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
15 #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
16 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
17 #include "llvm/Support/Allocator.h"
18 #include "llvm/Support/BinaryByteStream.h"
19 #include "llvm/Support/BinaryStreamWriter.h"
20 #include "llvm/Support/Endian.h"
21 #include "llvm/Support/Error.h"
22 #include <array>
23 #include <cstdint>
24 
25 namespace llvm {
26 namespace codeview {
27 
28 class SymbolSerializer : public SymbolVisitorCallbacks {
29   BumpPtrAllocator &Storage;
30   // Since this is a fixed size buffer, use a stack allocated buffer.  This
31   // yields measurable performance increase over the repeated heap allocations
32   // when serializing many independent records via writeOneSymbol.
33   std::array<uint8_t, MaxRecordLength> RecordBuffer;
34   MutableBinaryByteStream Stream;
35   BinaryStreamWriter Writer;
36   SymbolRecordMapping Mapping;
37   std::optional<SymbolKind> CurrentSymbol;
38 
39   Error writeRecordPrefix(SymbolKind Kind) {
40     RecordPrefix Prefix;
41     Prefix.RecordKind = Kind;
42     Prefix.RecordLen = 0;
43     if (auto EC = Writer.writeObject(Prefix))
44       return EC;
45     return Error::success();
46   }
47 
48 public:
49   SymbolSerializer(BumpPtrAllocator &Storage, CodeViewContainer Container);
50 
51   template <typename SymType>
52   static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage,
53                                  CodeViewContainer Container) {
54     RecordPrefix Prefix{uint16_t(Sym.Kind)};
55     CVSymbol Result(&Prefix, sizeof(Prefix));
56     SymbolSerializer Serializer(Storage, Container);
57     consumeError(Serializer.visitSymbolBegin(Result));
58     consumeError(Serializer.visitKnownRecord(Result, Sym));
59     consumeError(Serializer.visitSymbolEnd(Result));
60     return Result;
61   }
62 
63   Error visitSymbolBegin(CVSymbol &Record) override;
64   Error visitSymbolEnd(CVSymbol &Record) override;
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 RecordKind>
75   Error visitKnownRecordImpl(CVSymbol &CVR, RecordKind &Record) {
76     return Mapping.visitKnownRecord(CVR, Record);
77   }
78 };
79 
80 } // end namespace codeview
81 } // end namespace llvm
82 
83 #endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
84