10b57cec5SDimitry Andric //===- SymbolRecordHelpers.cpp ----------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" 100b57cec5SDimitry Andric 1181ad6265SDimitry Andric #include "llvm/ADT/ArrayRef.h" 120b57cec5SDimitry Andric #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric using namespace llvm; 150b57cec5SDimitry Andric using namespace llvm::codeview; 160b57cec5SDimitry Andric createRecord(const CVSymbol & sym)17480093f4SDimitry Andrictemplate <typename RecordT> static RecordT createRecord(const CVSymbol &sym) { 180b57cec5SDimitry Andric RecordT record(static_cast<SymbolRecordKind>(sym.kind())); 190b57cec5SDimitry Andric cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record)); 200b57cec5SDimitry Andric return record; 210b57cec5SDimitry Andric } 220b57cec5SDimitry Andric getScopeEndOffset(const CVSymbol & Sym)230b57cec5SDimitry Andricuint32_t llvm::codeview::getScopeEndOffset(const CVSymbol &Sym) { 240b57cec5SDimitry Andric assert(symbolOpensScope(Sym.kind())); 250b57cec5SDimitry Andric switch (Sym.kind()) { 260b57cec5SDimitry Andric case SymbolKind::S_GPROC32: 270b57cec5SDimitry Andric case SymbolKind::S_LPROC32: 280b57cec5SDimitry Andric case SymbolKind::S_GPROC32_ID: 290b57cec5SDimitry Andric case SymbolKind::S_LPROC32_ID: 300b57cec5SDimitry Andric case SymbolKind::S_LPROC32_DPC: 310b57cec5SDimitry Andric case SymbolKind::S_LPROC32_DPC_ID: { 320b57cec5SDimitry Andric ProcSym Proc = createRecord<ProcSym>(Sym); 330b57cec5SDimitry Andric return Proc.End; 340b57cec5SDimitry Andric } 350b57cec5SDimitry Andric case SymbolKind::S_BLOCK32: { 360b57cec5SDimitry Andric BlockSym Block = createRecord<BlockSym>(Sym); 370b57cec5SDimitry Andric return Block.End; 380b57cec5SDimitry Andric } 390b57cec5SDimitry Andric case SymbolKind::S_THUNK32: { 400b57cec5SDimitry Andric Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym); 410b57cec5SDimitry Andric return Thunk.End; 420b57cec5SDimitry Andric } 430b57cec5SDimitry Andric case SymbolKind::S_INLINESITE: { 440b57cec5SDimitry Andric InlineSiteSym Site = createRecord<InlineSiteSym>(Sym); 450b57cec5SDimitry Andric return Site.End; 460b57cec5SDimitry Andric } 470b57cec5SDimitry Andric default: 480b57cec5SDimitry Andric assert(false && "Unknown record type"); 490b57cec5SDimitry Andric return 0; 500b57cec5SDimitry Andric } 510b57cec5SDimitry Andric } 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric uint32_t getScopeParentOffset(const llvm::codeview::CVSymbol & Sym)540b57cec5SDimitry Andricllvm::codeview::getScopeParentOffset(const llvm::codeview::CVSymbol &Sym) { 550b57cec5SDimitry Andric assert(symbolOpensScope(Sym.kind())); 560b57cec5SDimitry Andric switch (Sym.kind()) { 570b57cec5SDimitry Andric case SymbolKind::S_GPROC32: 580b57cec5SDimitry Andric case SymbolKind::S_LPROC32: 590b57cec5SDimitry Andric case SymbolKind::S_GPROC32_ID: 600b57cec5SDimitry Andric case SymbolKind::S_LPROC32_ID: 610b57cec5SDimitry Andric case SymbolKind::S_LPROC32_DPC: 620b57cec5SDimitry Andric case SymbolKind::S_LPROC32_DPC_ID: { 630b57cec5SDimitry Andric ProcSym Proc = createRecord<ProcSym>(Sym); 640b57cec5SDimitry Andric return Proc.Parent; 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric case SymbolKind::S_BLOCK32: { 670b57cec5SDimitry Andric BlockSym Block = createRecord<BlockSym>(Sym); 680b57cec5SDimitry Andric return Block.Parent; 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric case SymbolKind::S_THUNK32: { 710b57cec5SDimitry Andric Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym); 720b57cec5SDimitry Andric return Thunk.Parent; 730b57cec5SDimitry Andric } 740b57cec5SDimitry Andric case SymbolKind::S_INLINESITE: { 750b57cec5SDimitry Andric InlineSiteSym Site = createRecord<InlineSiteSym>(Sym); 760b57cec5SDimitry Andric return Site.Parent; 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric default: 790b57cec5SDimitry Andric assert(false && "Unknown record type"); 800b57cec5SDimitry Andric return 0; 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric CVSymbolArray limitSymbolArrayToScope(const CVSymbolArray & Symbols,uint32_t ScopeBegin)850b57cec5SDimitry Andricllvm::codeview::limitSymbolArrayToScope(const CVSymbolArray &Symbols, 860b57cec5SDimitry Andric uint32_t ScopeBegin) { 870b57cec5SDimitry Andric CVSymbol Opener = *Symbols.at(ScopeBegin); 880b57cec5SDimitry Andric assert(symbolOpensScope(Opener.kind())); 890b57cec5SDimitry Andric uint32_t EndOffset = getScopeEndOffset(Opener); 900b57cec5SDimitry Andric CVSymbol Closer = *Symbols.at(EndOffset); 910b57cec5SDimitry Andric EndOffset += Closer.RecordData.size(); 920b57cec5SDimitry Andric return Symbols.substream(ScopeBegin, EndOffset); 930b57cec5SDimitry Andric } 94