PDBContext.cpp revision 283625
197403Sobrien//===-- PDBContext.cpp ------------------------------------------*- C++ -*-===// 297403Sobrien// 3169691Skan// The LLVM Compiler Infrastructure 497403Sobrien// 597403Sobrien// This file is distributed under the University of Illinois Open Source 697403Sobrien// License. See LICENSE.TXT for details. 797403Sobrien// 897403Sobrien//===----------------------------------------------------------------------===/ 997403Sobrien 1097403Sobrien#include "llvm/DebugInfo/PDB/PDBContext.h" 1197403Sobrien#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" 1297403Sobrien#include "llvm/DebugInfo/PDB/IPDBLineNumber.h" 1397403Sobrien#include "llvm/DebugInfo/PDB/IPDBSourceFile.h" 1497403Sobrien#include "llvm/DebugInfo/PDB/PDBSymbol.h" 1597403Sobrien#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" 1697403Sobrien#include "llvm/DebugInfo/PDB/PDBSymbolData.h" 1797403Sobrien#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" 18169691Skan#include "llvm/Object/COFF.h" 1997403Sobrien 2097403Sobrienusing namespace llvm; 2197403Sobrienusing namespace llvm::object; 2297403Sobrien 2397403SobrienPDBContext::PDBContext(const COFFObjectFile &Object, 2497403Sobrien std::unique_ptr<IPDBSession> PDBSession, 2597403Sobrien bool RelativeAddress) 2697403Sobrien : DIContext(CK_PDB), Session(std::move(PDBSession)) { 2797403Sobrien if (!RelativeAddress) { 2897403Sobrien uint64_t ImageBase = 0; 2997403Sobrien if (Object.is64()) { 3097403Sobrien const pe32plus_header *Header = nullptr; 3197403Sobrien Object.getPE32PlusHeader(Header); 3297403Sobrien if (Header) 3397403Sobrien ImageBase = Header->ImageBase; 3497403Sobrien } else { 3597403Sobrien const pe32_header *Header = nullptr; 3697403Sobrien Object.getPE32Header(Header); 3797403Sobrien if (Header) 3897403Sobrien ImageBase = static_cast<uint64_t>(Header->ImageBase); 3997403Sobrien } 4097403Sobrien Session->setLoadAddress(ImageBase); 4197403Sobrien } 4297403Sobrien} 4397403Sobrien 4497403Sobrienvoid PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {} 4597403Sobrien 46169691SkanDILineInfo PDBContext::getLineInfoForAddress(uint64_t Address, 4797403Sobrien DILineInfoSpecifier Specifier) { 4897403Sobrien DILineInfo Result; 49132720Skan Result.FunctionName = getFunctionName(Address, Specifier.FNKind); 50132720Skan 5197403Sobrien uint32_t Length = 1; 5297403Sobrien std::unique_ptr<PDBSymbol> Symbol = 53132720Skan Session->findSymbolByAddress(Address, PDB_SymType::None); 5497403Sobrien if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) { 5597403Sobrien Length = Func->getLength(); 5697403Sobrien } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) { 5797403Sobrien Length = Data->getLength(); 58169691Skan } 5997403Sobrien 60169691Skan // If we couldn't find a symbol, then just assume 1 byte, so that we get 61169691Skan // only the line number of the first instruction. 62169691Skan auto LineNumbers = Session->findLineNumbersByAddress(Address, Length); 63169691Skan if (!LineNumbers || LineNumbers->getChildCount() == 0) 64169691Skan return Result; 65169691Skan 66169691Skan auto LineInfo = LineNumbers->getNext(); 6797403Sobrien assert(LineInfo); 68169691Skan auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId()); 69169691Skan 70169691Skan if (SourceFile && 71169691Skan Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None) 72169691Skan Result.FileName = SourceFile->getFileName(); 73169691Skan Result.Column = LineInfo->getColumnNumber(); 74169691Skan Result.Line = LineInfo->getLineNumber(); 75169691Skan return Result; 76169691Skan} 77169691Skan 78169691SkanDILineInfoTable 79169691SkanPDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, 80169691Skan DILineInfoSpecifier Specifier) { 8197403Sobrien if (Size == 0) 82169691Skan return DILineInfoTable(); 83169691Skan 84169691Skan DILineInfoTable Table; 85169691Skan auto LineNumbers = Session->findLineNumbersByAddress(Address, Size); 86169691Skan if (!LineNumbers || LineNumbers->getChildCount() == 0) 87169691Skan return Table; 88169691Skan 89169691Skan while (auto LineInfo = LineNumbers->getNext()) { 9097403Sobrien DILineInfo LineEntry = 91169691Skan getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier); 92169691Skan Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry)); 93169691Skan } 94169691Skan return Table; 95169691Skan} 96169691Skan 97169691SkanDIInliningInfo 98169691SkanPDBContext::getInliningInfoForAddress(uint64_t Address, 9997403Sobrien DILineInfoSpecifier Specifier) { 100169691Skan DIInliningInfo InlineInfo; 101169691Skan DILineInfo Frame = getLineInfoForAddress(Address, Specifier); 102169691Skan InlineInfo.addFrame(Frame); 103169691Skan return InlineInfo; 104169691Skan} 105169691Skan 106169691Skanstd::string PDBContext::getFunctionName(uint64_t Address, 107169691Skan DINameKind NameKind) const { 108169691Skan if (NameKind == DINameKind::None) 109169691Skan return std::string(); 110169691Skan 111169691Skan if (NameKind == DINameKind::LinkageName) { 112169691Skan // It is not possible to get the mangled linkage name through a 11397403Sobrien // PDBSymbolFunc. For that we have to specifically request a 11497403Sobrien // PDBSymbolPublicSymbol. 115169691Skan auto PublicSym = 116169691Skan Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol); 117169691Skan if (auto PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get())) 118169691Skan return PS->getName(); 119169691Skan } 120169691Skan 121169691Skan auto FuncSymbol = 122169691Skan Session->findSymbolByAddress(Address, PDB_SymType::Function); 123169691Skan 124169691Skan // This could happen either if there was no public symbol (e.g. not 125169691Skan // external) or the user requested the short name. In the former case, 12697403Sobrien // although they technically requested the linkage name, if the linkage 12797403Sobrien // name is not available we fallback to at least returning a non-empty 128169691Skan // string. 129169691Skan if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get())) 130169691Skan return Func->getName(); 131169691Skan 132169691Skan return std::string(); 133169691Skan} 134169691Skan