SymbolSerializer.h 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- SymbolSerializer.h ---------------------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
  14. #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
  15. #include "llvm/DebugInfo/CodeView/CVRecord.h"
  16. #include "llvm/DebugInfo/CodeView/CodeView.h"
  17. #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
  18. #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
  19. #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
  20. #include "llvm/Support/Allocator.h"
  21. #include "llvm/Support/BinaryByteStream.h"
  22. #include "llvm/Support/BinaryStreamWriter.h"
  23. #include "llvm/Support/Endian.h"
  24. #include "llvm/Support/Error.h"
  25. #include <array>
  26. #include <cstdint>
  27. namespace llvm {
  28. namespace codeview {
  29. class SymbolSerializer : public SymbolVisitorCallbacks {
  30. BumpPtrAllocator &Storage;
  31. // Since this is a fixed size buffer, use a stack allocated buffer. This
  32. // yields measurable performance increase over the repeated heap allocations
  33. // when serializing many independent records via writeOneSymbol.
  34. std::array<uint8_t, MaxRecordLength> RecordBuffer;
  35. MutableBinaryByteStream Stream;
  36. BinaryStreamWriter Writer;
  37. SymbolRecordMapping Mapping;
  38. std::optional<SymbolKind> CurrentSymbol;
  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. public:
  48. SymbolSerializer(BumpPtrAllocator &Storage, CodeViewContainer Container);
  49. template <typename SymType>
  50. static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage,
  51. CodeViewContainer Container) {
  52. RecordPrefix Prefix{uint16_t(Sym.Kind)};
  53. CVSymbol Result(&Prefix, sizeof(Prefix));
  54. SymbolSerializer Serializer(Storage, Container);
  55. consumeError(Serializer.visitSymbolBegin(Result));
  56. consumeError(Serializer.visitKnownRecord(Result, Sym));
  57. consumeError(Serializer.visitSymbolEnd(Result));
  58. return Result;
  59. }
  60. Error visitSymbolBegin(CVSymbol &Record) override;
  61. Error visitSymbolEnd(CVSymbol &Record) override;
  62. #define SYMBOL_RECORD(EnumName, EnumVal, Name) \
  63. Error visitKnownRecord(CVSymbol &CVR, Name &Record) override { \
  64. return visitKnownRecordImpl(CVR, Record); \
  65. }
  66. #define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
  67. #include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
  68. private:
  69. template <typename RecordKind>
  70. Error visitKnownRecordImpl(CVSymbol &CVR, RecordKind &Record) {
  71. return Mapping.visitKnownRecord(CVR, Record);
  72. }
  73. };
  74. } // end namespace codeview
  75. } // end namespace llvm
  76. #endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLSERIALIZER_H
  77. #ifdef __GNUC__
  78. #pragma GCC diagnostic pop
  79. #endif