1 //===- PDBSymbolData.cpp - PDB data (e.g. variable) accessors ---*- 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/PDB/PDBSymbolData.h" 10 #include "llvm/DebugInfo/PDB/IPDBSectionContrib.h" 11 #include "llvm/DebugInfo/PDB/IPDBSession.h" 12 #include "llvm/DebugInfo/PDB/PDBSymDumper.h" 13 14 #include <utility> 15 16 using namespace llvm; 17 using namespace llvm::pdb; 18 19 void PDBSymbolData::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); } 20 21 std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolData::getLineNumbers() const { 22 auto Len = RawSymbol->getLength(); 23 Len = Len ? Len : 1; 24 if (auto RVA = RawSymbol->getRelativeVirtualAddress()) 25 return Session.findLineNumbersByRVA(RVA, Len); 26 27 if (auto Section = RawSymbol->getAddressSection()) 28 return Session.findLineNumbersBySectOffset( 29 Section, RawSymbol->getAddressOffset(), Len); 30 31 return nullptr; 32 } 33 34 uint32_t PDBSymbolData::getCompilandId() const { 35 if (auto Lines = getLineNumbers()) { 36 if (auto FirstLine = Lines->getNext()) 37 return FirstLine->getCompilandId(); 38 } 39 40 uint32_t DataSection = RawSymbol->getAddressSection(); 41 uint32_t DataOffset = RawSymbol->getAddressOffset(); 42 if (DataSection == 0) { 43 if (auto RVA = RawSymbol->getRelativeVirtualAddress()) 44 Session.addressForRVA(RVA, DataSection, DataOffset); 45 } 46 47 if (DataSection) { 48 if (auto SecContribs = Session.getSectionContribs()) { 49 while (auto Section = SecContribs->getNext()) { 50 if (Section->getAddressSection() == DataSection && 51 Section->getAddressOffset() <= DataOffset && 52 (Section->getAddressOffset() + Section->getLength()) > DataOffset) 53 return Section->getCompilandId(); 54 } 55 } 56 } else { 57 auto LexParentId = RawSymbol->getLexicalParentId(); 58 while (auto LexParent = Session.getSymbolById(LexParentId)) { 59 if (LexParent->getSymTag() == PDB_SymType::Exe) 60 break; 61 if (LexParent->getSymTag() == PDB_SymType::Compiland) 62 return LexParentId; 63 LexParentId = LexParent->getRawSymbol().getLexicalParentId(); 64 } 65 } 66 67 return 0; 68 } 69