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