~pali/+junk/llvm-toolchain-3.7

« back to all changes in this revision

Viewing changes to lib/DebugInfo/PDB/PDBContext.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2015-07-15 17:51:08 UTC
  • Revision ID: package-import@ubuntu.com-20150715175108-l8mynwovkx4zx697
Tags: upstream-3.7~+rc2
ImportĀ upstreamĀ versionĀ 3.7~+rc2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
23
PDBContext::PDBContext(const COFFObjectFile &Object,
 
24
                       std::unique_ptr<IPDBSession> PDBSession,
 
25
                       bool RelativeAddress)
 
26
    : DIContext(CK_PDB), Session(std::move(PDBSession)) {
 
27
  if (!RelativeAddress) {
 
28
    uint64_t ImageBase = 0;
 
29
    if (Object.is64()) {
 
30
      const pe32plus_header *Header = nullptr;
 
31
      Object.getPE32PlusHeader(Header);
 
32
      if (Header)
 
33
        ImageBase = Header->ImageBase;
 
34
    } else {
 
35
      const pe32_header *Header = nullptr;
 
36
      Object.getPE32Header(Header);
 
37
      if (Header)
 
38
        ImageBase = static_cast<uint64_t>(Header->ImageBase);
 
39
    }
 
40
    Session->setLoadAddress(ImageBase);
 
41
  }
 
42
}
 
43
 
 
44
void PDBContext::dump(raw_ostream &OS, DIDumpType DumpType) {}
 
45
 
 
46
DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address,
 
47
                                             DILineInfoSpecifier Specifier) {
 
48
  DILineInfo Result;
 
49
  Result.FunctionName = getFunctionName(Address, Specifier.FNKind);
 
50
 
 
51
  uint32_t Length = 1;
 
52
  std::unique_ptr<PDBSymbol> Symbol =
 
53
      Session->findSymbolByAddress(Address, PDB_SymType::None);
 
54
  if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) {
 
55
    Length = Func->getLength();
 
56
  } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) {
 
57
    Length = Data->getLength();
 
58
  }
 
59
 
 
60
  // If we couldn't find a symbol, then just assume 1 byte, so that we get
 
61
  // only the line number of the first instruction.
 
62
  auto LineNumbers = Session->findLineNumbersByAddress(Address, Length);
 
63
  if (!LineNumbers || LineNumbers->getChildCount() == 0)
 
64
    return Result;
 
65
 
 
66
  auto LineInfo = LineNumbers->getNext();
 
67
  assert(LineInfo);
 
68
  auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
 
69
 
 
70
  if (SourceFile &&
 
71
      Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
 
72
    Result.FileName = SourceFile->getFileName();
 
73
  Result.Column = LineInfo->getColumnNumber();
 
74
  Result.Line = LineInfo->getLineNumber();
 
75
  return Result;
 
76
}
 
77
 
 
78
DILineInfoTable
 
79
PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
 
80
                                       DILineInfoSpecifier Specifier) {
 
81
  if (Size == 0)
 
82
    return DILineInfoTable();
 
83
 
 
84
  DILineInfoTable Table;
 
85
  auto LineNumbers = Session->findLineNumbersByAddress(Address, Size);
 
86
  if (!LineNumbers || LineNumbers->getChildCount() == 0)
 
87
    return Table;
 
88
 
 
89
  while (auto LineInfo = LineNumbers->getNext()) {
 
90
    DILineInfo LineEntry =
 
91
        getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier);
 
92
    Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
 
93
  }
 
94
  return Table;
 
95
}
 
96
 
 
97
DIInliningInfo
 
98
PDBContext::getInliningInfoForAddress(uint64_t Address,
 
99
                                      DILineInfoSpecifier Specifier) {
 
100
  DIInliningInfo InlineInfo;
 
101
  DILineInfo Frame = getLineInfoForAddress(Address, Specifier);
 
102
  InlineInfo.addFrame(Frame);
 
103
  return InlineInfo;
 
104
}
 
105
 
 
106
std::string PDBContext::getFunctionName(uint64_t Address,
 
107
                                        DINameKind NameKind) const {
 
108
  if (NameKind == DINameKind::None)
 
109
    return std::string();
 
110
 
 
111
  if (NameKind == DINameKind::LinkageName) {
 
112
    // It is not possible to get the mangled linkage name through a
 
113
    // PDBSymbolFunc.  For that we have to specifically request a
 
114
    // PDBSymbolPublicSymbol.
 
115
    auto PublicSym =
 
116
        Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);
 
117
    if (auto PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get()))
 
118
      return PS->getName();
 
119
  }
 
120
 
 
121
  auto FuncSymbol =
 
122
      Session->findSymbolByAddress(Address, PDB_SymType::Function);
 
123
 
 
124
  // This could happen either if there was no public symbol (e.g. not
 
125
  // external) or the user requested the short name.  In the former case,
 
126
  // although they technically requested the linkage name, if the linkage
 
127
  // name is not available we fallback to at least returning a non-empty
 
128
  // string.
 
129
  if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get()))
 
130
      return Func->getName();
 
131
 
 
132
  return std::string();
 
133
}