xref: /aosp_15_r20/external/llvm/lib/DebugInfo/PDB/PDBContext.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- PDBContext.cpp ------------------------------------------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===/
9*9880d681SAndroid Build Coastguard Worker 
10*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBContext.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
13*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
14*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBSymbol.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBSymbolData.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/Object/COFF.h"
19*9880d681SAndroid Build Coastguard Worker 
20*9880d681SAndroid Build Coastguard Worker using namespace llvm;
21*9880d681SAndroid Build Coastguard Worker using namespace llvm::object;
22*9880d681SAndroid Build Coastguard Worker using namespace llvm::pdb;
23*9880d681SAndroid Build Coastguard Worker 
PDBContext(const COFFObjectFile & Object,std::unique_ptr<IPDBSession> PDBSession)24*9880d681SAndroid Build Coastguard Worker PDBContext::PDBContext(const COFFObjectFile &Object,
25*9880d681SAndroid Build Coastguard Worker                        std::unique_ptr<IPDBSession> PDBSession)
26*9880d681SAndroid Build Coastguard Worker     : DIContext(CK_PDB), Session(std::move(PDBSession)) {
27*9880d681SAndroid Build Coastguard Worker   ErrorOr<uint64_t> ImageBase = Object.getImageBase();
28*9880d681SAndroid Build Coastguard Worker   if (ImageBase)
29*9880d681SAndroid Build Coastguard Worker     Session->setLoadAddress(ImageBase.get());
30*9880d681SAndroid Build Coastguard Worker }
31*9880d681SAndroid Build Coastguard Worker 
dump(raw_ostream & OS,DIDumpType DumpType,bool DumpEH)32*9880d681SAndroid Build Coastguard Worker void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType,
33*9880d681SAndroid Build Coastguard Worker                       bool DumpEH) {}
34*9880d681SAndroid Build Coastguard Worker 
getLineInfoForAddress(uint64_t Address,DILineInfoSpecifier Specifier)35*9880d681SAndroid Build Coastguard Worker DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
36*9880d681SAndroid Build Coastguard Worker                                              DILineInfoSpecifier Specifier) {
37*9880d681SAndroid Build Coastguard Worker   DILineInfo Result;
38*9880d681SAndroid Build Coastguard Worker   Result.FunctionName = getFunctionName(Address, Specifier.FNKind);
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker   uint32_t Length = 1;
41*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<PDBSymbol> Symbol =
42*9880d681SAndroid Build Coastguard Worker       Session->findSymbolByAddress(Address, PDB_SymType::None);
43*9880d681SAndroid Build Coastguard Worker   if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {
44*9880d681SAndroid Build Coastguard Worker     Length = Func->getLength();
45*9880d681SAndroid Build Coastguard Worker   } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
46*9880d681SAndroid Build Coastguard Worker     Length = Data->getLength();
47*9880d681SAndroid Build Coastguard Worker   }
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker   // If we couldn't find a symbol, then just assume 1 byte, so that we get
50*9880d681SAndroid Build Coastguard Worker   // only the line number of the first instruction.
51*9880d681SAndroid Build Coastguard Worker   auto LineNumbers = Session->findLineNumbersByAddress(Address, Length);
52*9880d681SAndroid Build Coastguard Worker   if (!LineNumbers || LineNumbers->getChildCount() == 0)
53*9880d681SAndroid Build Coastguard Worker     return Result;
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker   auto LineInfo = LineNumbers->getNext();
56*9880d681SAndroid Build Coastguard Worker   assert(LineInfo);
57*9880d681SAndroid Build Coastguard Worker   auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
58*9880d681SAndroid Build Coastguard Worker 
59*9880d681SAndroid Build Coastguard Worker   if (SourceFile &&
60*9880d681SAndroid Build Coastguard Worker       Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
61*9880d681SAndroid Build Coastguard Worker     Result.FileName = SourceFile->getFileName();
62*9880d681SAndroid Build Coastguard Worker   Result.Column = LineInfo->getColumnNumber();
63*9880d681SAndroid Build Coastguard Worker   Result.Line = LineInfo->getLineNumber();
64*9880d681SAndroid Build Coastguard Worker   return Result;
65*9880d681SAndroid Build Coastguard Worker }
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker DILineInfoTable
getLineInfoForAddressRange(uint64_t Address,uint64_t Size,DILineInfoSpecifier Specifier)68*9880d681SAndroid Build Coastguard Worker PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
69*9880d681SAndroid Build Coastguard Worker                                        DILineInfoSpecifier Specifier) {
70*9880d681SAndroid Build Coastguard Worker   if (Size == 0)
71*9880d681SAndroid Build Coastguard Worker     return DILineInfoTable();
72*9880d681SAndroid Build Coastguard Worker 
73*9880d681SAndroid Build Coastguard Worker   DILineInfoTable Table;
74*9880d681SAndroid Build Coastguard Worker   auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
75*9880d681SAndroid Build Coastguard Worker   if (!LineNumbers || LineNumbers->getChildCount() == 0)
76*9880d681SAndroid Build Coastguard Worker     return Table;
77*9880d681SAndroid Build Coastguard Worker 
78*9880d681SAndroid Build Coastguard Worker   while (auto LineInfo = LineNumbers->getNext()) {
79*9880d681SAndroid Build Coastguard Worker     DILineInfo LineEntry =
80*9880d681SAndroid Build Coastguard Worker         getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
81*9880d681SAndroid Build Coastguard Worker     Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
82*9880d681SAndroid Build Coastguard Worker   }
83*9880d681SAndroid Build Coastguard Worker   return Table;
84*9880d681SAndroid Build Coastguard Worker }
85*9880d681SAndroid Build Coastguard Worker 
86*9880d681SAndroid Build Coastguard Worker DIInliningInfo
getInliningInfoForAddress(uint64_t Address,DILineInfoSpecifier Specifier)87*9880d681SAndroid Build Coastguard Worker PDBContext::getInliningInfoForAddress(uint64_t Address,
88*9880d681SAndroid Build Coastguard Worker                                       DILineInfoSpecifier Specifier) {
89*9880d681SAndroid Build Coastguard Worker   DIInliningInfo InlineInfo;
90*9880d681SAndroid Build Coastguard Worker   DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
91*9880d681SAndroid Build Coastguard Worker   InlineInfo.addFrame(Frame);
92*9880d681SAndroid Build Coastguard Worker   return InlineInfo;
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker 
getFunctionName(uint64_t Address,DINameKind NameKind) const95*9880d681SAndroid Build Coastguard Worker std::string PDBContext::getFunctionName(uint64_t Address,
96*9880d681SAndroid Build Coastguard Worker                                         DINameKind NameKind) const {
97*9880d681SAndroid Build Coastguard Worker   if (NameKind == DINameKind::None)
98*9880d681SAndroid Build Coastguard Worker     return std::string();
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker   std::unique_ptr<PDBSymbol> FuncSymbol =
101*9880d681SAndroid Build Coastguard Worker       Session->findSymbolByAddress(Address, PDB_SymType::Function);
102*9880d681SAndroid Build Coastguard Worker   auto *Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get());
103*9880d681SAndroid Build Coastguard Worker 
104*9880d681SAndroid Build Coastguard Worker   if (NameKind == DINameKind::LinkageName) {
105*9880d681SAndroid Build Coastguard Worker     // It is not possible to get the mangled linkage name through a
106*9880d681SAndroid Build Coastguard Worker     // PDBSymbolFunc.  For that we have to specifically request a
107*9880d681SAndroid Build Coastguard Worker     // PDBSymbolPublicSymbol.
108*9880d681SAndroid Build Coastguard Worker     auto PublicSym =
109*9880d681SAndroid Build Coastguard Worker         Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);
110*9880d681SAndroid Build Coastguard Worker     if (auto *PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get())) {
111*9880d681SAndroid Build Coastguard Worker       // If we also have a function symbol, prefer the use of public symbol name
112*9880d681SAndroid Build Coastguard Worker       // only if it refers to the same address. The public symbol uses the
113*9880d681SAndroid Build Coastguard Worker       // linkage name while the function does not.
114*9880d681SAndroid Build Coastguard Worker       if (!Func || Func->getVirtualAddress() == PS->getVirtualAddress())
115*9880d681SAndroid Build Coastguard Worker         return PS->getName();
116*9880d681SAndroid Build Coastguard Worker     }
117*9880d681SAndroid Build Coastguard Worker   }
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker   return Func ? Func->getName() : std::string();
120*9880d681SAndroid Build Coastguard Worker }
121