1 //===- PDBSymbolData.cpp - PDB data (e.g. variable) accessors ---*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/DebugInfo/PDB/PDBSymbolData.h" 11 #include "llvm/DebugInfo/PDB/IPDBSectionContrib.h" 12 #include "llvm/DebugInfo/PDB/IPDBSession.h" 13 #include "llvm/DebugInfo/PDB/PDBSymDumper.h" 14 15 #include <utility> 16 17 using namespace llvm; 18 using namespace llvm::pdb; 19 20 PDBSymbolData::PDBSymbolData(const IPDBSession &PDBSession, 21 std::unique_ptr<IPDBRawSymbol> DataSymbol) 22 : PDBSymbol(PDBSession, std::move(DataSymbol)) { 23 assert(RawSymbol->getSymTag() == PDB_SymType::Data); 24 } 25 26 void PDBSymbolData::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); } 27 28 std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolData::getLineNumbers() const { 29 auto Len = RawSymbol->getLength(); 30 Len = Len ? Len : 1; 31 if (auto RVA = RawSymbol->getRelativeVirtualAddress()) 32 return Session.findLineNumbersByRVA(RVA, Len); 33 34 if (auto Section = RawSymbol->getAddressSection()) 35 return Session.findLineNumbersBySectOffset( 36 Section, RawSymbol->getAddressOffset(), Len); 37 38 return nullptr; 39 } 40 41 uint32_t PDBSymbolData::getCompilandId() const { 42 if (auto Lines = getLineNumbers()) { 43 if (auto FirstLine = Lines->getNext()) 44 return FirstLine->getCompilandId(); 45 } 46 47 uint32_t DataSection = RawSymbol->getAddressSection(); 48 uint32_t DataOffset = RawSymbol->getAddressOffset(); 49 if (DataSection == 0) { 50 if (auto RVA = RawSymbol->getRelativeVirtualAddress()) 51 Session.addressForRVA(RVA, DataSection, DataOffset); 52 } 53 54 if (DataSection) { 55 if (auto SecContribs = Session.getSectionContribs()) { 56 while (auto Section = SecContribs->getNext()) { 57 if (Section->getAddressSection() == DataSection && 58 Section->getAddressOffset() <= DataOffset && 59 (Section->getAddressOffset() + Section->getLength()) > DataOffset) 60 return Section->getCompilandId(); 61 } 62 } 63 } else { 64 auto LexParentId = RawSymbol->getLexicalParentId(); 65 while (auto LexParent = Session.getSymbolById(LexParentId)) { 66 if (LexParent->getSymTag() == PDB_SymType::Exe) 67 break; 68 if (LexParent->getSymTag() == PDB_SymType::Compiland) 69 return LexParentId; 70 LexParentId = LexParent->getRawSymbol().getLexicalParentId(); 71 } 72 } 73 74 return 0; 75 } 76