xref: /llvm-project/llvm/lib/DebugInfo/PDB/PDBSymbolData.cpp (revision 1af50bcf894d7e66dca8c41d9829ad68d0fa66b3)
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