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