SymbolRecordHelpers.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //===- SymbolRecordHelpers.cpp ----------------------------------*- 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. #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
  9. #include "llvm/ADT/SmallVector.h"
  10. #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
  11. using namespace llvm;
  12. using namespace llvm::codeview;
  13. template <typename RecordT> static RecordT createRecord(const CVSymbol &sym) {
  14. RecordT record(static_cast<SymbolRecordKind>(sym.kind()));
  15. cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
  16. return record;
  17. }
  18. uint32_t llvm::codeview::getScopeEndOffset(const CVSymbol &Sym) {
  19. assert(symbolOpensScope(Sym.kind()));
  20. switch (Sym.kind()) {
  21. case SymbolKind::S_GPROC32:
  22. case SymbolKind::S_LPROC32:
  23. case SymbolKind::S_GPROC32_ID:
  24. case SymbolKind::S_LPROC32_ID:
  25. case SymbolKind::S_LPROC32_DPC:
  26. case SymbolKind::S_LPROC32_DPC_ID: {
  27. ProcSym Proc = createRecord<ProcSym>(Sym);
  28. return Proc.End;
  29. }
  30. case SymbolKind::S_BLOCK32: {
  31. BlockSym Block = createRecord<BlockSym>(Sym);
  32. return Block.End;
  33. }
  34. case SymbolKind::S_THUNK32: {
  35. Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym);
  36. return Thunk.End;
  37. }
  38. case SymbolKind::S_INLINESITE: {
  39. InlineSiteSym Site = createRecord<InlineSiteSym>(Sym);
  40. return Site.End;
  41. }
  42. default:
  43. assert(false && "Unknown record type");
  44. return 0;
  45. }
  46. }
  47. uint32_t
  48. llvm::codeview::getScopeParentOffset(const llvm::codeview::CVSymbol &Sym) {
  49. assert(symbolOpensScope(Sym.kind()));
  50. switch (Sym.kind()) {
  51. case SymbolKind::S_GPROC32:
  52. case SymbolKind::S_LPROC32:
  53. case SymbolKind::S_GPROC32_ID:
  54. case SymbolKind::S_LPROC32_ID:
  55. case SymbolKind::S_LPROC32_DPC:
  56. case SymbolKind::S_LPROC32_DPC_ID: {
  57. ProcSym Proc = createRecord<ProcSym>(Sym);
  58. return Proc.Parent;
  59. }
  60. case SymbolKind::S_BLOCK32: {
  61. BlockSym Block = createRecord<BlockSym>(Sym);
  62. return Block.Parent;
  63. }
  64. case SymbolKind::S_THUNK32: {
  65. Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym);
  66. return Thunk.Parent;
  67. }
  68. case SymbolKind::S_INLINESITE: {
  69. InlineSiteSym Site = createRecord<InlineSiteSym>(Sym);
  70. return Site.Parent;
  71. }
  72. default:
  73. assert(false && "Unknown record type");
  74. return 0;
  75. }
  76. }
  77. CVSymbolArray
  78. llvm::codeview::limitSymbolArrayToScope(const CVSymbolArray &Symbols,
  79. uint32_t ScopeBegin) {
  80. CVSymbol Opener = *Symbols.at(ScopeBegin);
  81. assert(symbolOpensScope(Opener.kind()));
  82. uint32_t EndOffset = getScopeEndOffset(Opener);
  83. CVSymbol Closer = *Symbols.at(EndOffset);
  84. EndOffset += Closer.RecordData.size();
  85. return Symbols.substream(ScopeBegin, EndOffset);
  86. }