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