1*06f32e7eSjoerg //===- SymbolRecordHelpers.cpp ----------------------------------*- C++ -*-===// 2*06f32e7eSjoerg // 3*06f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*06f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information. 5*06f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*06f32e7eSjoerg // 7*06f32e7eSjoerg //===----------------------------------------------------------------------===// 8*06f32e7eSjoerg 9*06f32e7eSjoerg #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" 10*06f32e7eSjoerg 11*06f32e7eSjoerg #include "llvm/ADT/SmallVector.h" 12*06f32e7eSjoerg #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 13*06f32e7eSjoerg 14*06f32e7eSjoerg using namespace llvm; 15*06f32e7eSjoerg using namespace llvm::codeview; 16*06f32e7eSjoerg createRecord(const CVSymbol & sym)17*06f32e7eSjoergtemplate <typename RecordT> static RecordT createRecord(const CVSymbol &sym) { 18*06f32e7eSjoerg RecordT record(static_cast<SymbolRecordKind>(sym.kind())); 19*06f32e7eSjoerg cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record)); 20*06f32e7eSjoerg return record; 21*06f32e7eSjoerg } 22*06f32e7eSjoerg getScopeEndOffset(const CVSymbol & Sym)23*06f32e7eSjoerguint32_t llvm::codeview::getScopeEndOffset(const CVSymbol &Sym) { 24*06f32e7eSjoerg assert(symbolOpensScope(Sym.kind())); 25*06f32e7eSjoerg switch (Sym.kind()) { 26*06f32e7eSjoerg case SymbolKind::S_GPROC32: 27*06f32e7eSjoerg case SymbolKind::S_LPROC32: 28*06f32e7eSjoerg case SymbolKind::S_GPROC32_ID: 29*06f32e7eSjoerg case SymbolKind::S_LPROC32_ID: 30*06f32e7eSjoerg case SymbolKind::S_LPROC32_DPC: 31*06f32e7eSjoerg case SymbolKind::S_LPROC32_DPC_ID: { 32*06f32e7eSjoerg ProcSym Proc = createRecord<ProcSym>(Sym); 33*06f32e7eSjoerg return Proc.End; 34*06f32e7eSjoerg } 35*06f32e7eSjoerg case SymbolKind::S_BLOCK32: { 36*06f32e7eSjoerg BlockSym Block = createRecord<BlockSym>(Sym); 37*06f32e7eSjoerg return Block.End; 38*06f32e7eSjoerg } 39*06f32e7eSjoerg case SymbolKind::S_THUNK32: { 40*06f32e7eSjoerg Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym); 41*06f32e7eSjoerg return Thunk.End; 42*06f32e7eSjoerg } 43*06f32e7eSjoerg case SymbolKind::S_INLINESITE: { 44*06f32e7eSjoerg InlineSiteSym Site = createRecord<InlineSiteSym>(Sym); 45*06f32e7eSjoerg return Site.End; 46*06f32e7eSjoerg } 47*06f32e7eSjoerg default: 48*06f32e7eSjoerg assert(false && "Unknown record type"); 49*06f32e7eSjoerg return 0; 50*06f32e7eSjoerg } 51*06f32e7eSjoerg } 52*06f32e7eSjoerg 53*06f32e7eSjoerg uint32_t getScopeParentOffset(const llvm::codeview::CVSymbol & Sym)54*06f32e7eSjoergllvm::codeview::getScopeParentOffset(const llvm::codeview::CVSymbol &Sym) { 55*06f32e7eSjoerg assert(symbolOpensScope(Sym.kind())); 56*06f32e7eSjoerg switch (Sym.kind()) { 57*06f32e7eSjoerg case SymbolKind::S_GPROC32: 58*06f32e7eSjoerg case SymbolKind::S_LPROC32: 59*06f32e7eSjoerg case SymbolKind::S_GPROC32_ID: 60*06f32e7eSjoerg case SymbolKind::S_LPROC32_ID: 61*06f32e7eSjoerg case SymbolKind::S_LPROC32_DPC: 62*06f32e7eSjoerg case SymbolKind::S_LPROC32_DPC_ID: { 63*06f32e7eSjoerg ProcSym Proc = createRecord<ProcSym>(Sym); 64*06f32e7eSjoerg return Proc.Parent; 65*06f32e7eSjoerg } 66*06f32e7eSjoerg case SymbolKind::S_BLOCK32: { 67*06f32e7eSjoerg BlockSym Block = createRecord<BlockSym>(Sym); 68*06f32e7eSjoerg return Block.Parent; 69*06f32e7eSjoerg } 70*06f32e7eSjoerg case SymbolKind::S_THUNK32: { 71*06f32e7eSjoerg Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym); 72*06f32e7eSjoerg return Thunk.Parent; 73*06f32e7eSjoerg } 74*06f32e7eSjoerg case SymbolKind::S_INLINESITE: { 75*06f32e7eSjoerg InlineSiteSym Site = createRecord<InlineSiteSym>(Sym); 76*06f32e7eSjoerg return Site.Parent; 77*06f32e7eSjoerg } 78*06f32e7eSjoerg default: 79*06f32e7eSjoerg assert(false && "Unknown record type"); 80*06f32e7eSjoerg return 0; 81*06f32e7eSjoerg } 82*06f32e7eSjoerg } 83*06f32e7eSjoerg 84*06f32e7eSjoerg CVSymbolArray limitSymbolArrayToScope(const CVSymbolArray & Symbols,uint32_t ScopeBegin)85*06f32e7eSjoergllvm::codeview::limitSymbolArrayToScope(const CVSymbolArray &Symbols, 86*06f32e7eSjoerg uint32_t ScopeBegin) { 87*06f32e7eSjoerg CVSymbol Opener = *Symbols.at(ScopeBegin); 88*06f32e7eSjoerg assert(symbolOpensScope(Opener.kind())); 89*06f32e7eSjoerg uint32_t EndOffset = getScopeEndOffset(Opener); 90*06f32e7eSjoerg CVSymbol Closer = *Symbols.at(EndOffset); 91*06f32e7eSjoerg EndOffset += Closer.RecordData.size(); 92*06f32e7eSjoerg return Symbols.substream(ScopeBegin, EndOffset); 93*06f32e7eSjoerg } 94