Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
35293 views
1
//===- NativeFunctionSymbol.cpp - info about function symbols----*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
10
11
#include "llvm/DebugInfo/CodeView/CVRecord.h"
12
#include "llvm/DebugInfo/CodeView/CodeView.h"
13
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
14
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
15
#include "llvm/DebugInfo/PDB/Native/ModuleDebugStream.h"
16
#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
17
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
18
#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
19
#include "llvm/DebugInfo/PDB/PDBExtras.h"
20
21
using namespace llvm;
22
using namespace llvm::codeview;
23
using namespace llvm::pdb;
24
25
NativeFunctionSymbol::NativeFunctionSymbol(NativeSession &Session,
26
SymIndexId Id,
27
const codeview::ProcSym &Sym,
28
uint32_t Offset)
29
: NativeRawSymbol(Session, PDB_SymType::Function, Id), Sym(Sym),
30
RecordOffset(Offset) {}
31
32
NativeFunctionSymbol::~NativeFunctionSymbol() = default;
33
34
void NativeFunctionSymbol::dump(raw_ostream &OS, int Indent,
35
PdbSymbolIdField ShowIdFields,
36
PdbSymbolIdField RecurseIdFields) const {
37
NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
38
dumpSymbolField(OS, "name", getName(), Indent);
39
dumpSymbolField(OS, "length", getLength(), Indent);
40
dumpSymbolField(OS, "offset", getAddressOffset(), Indent);
41
dumpSymbolField(OS, "section", getAddressSection(), Indent);
42
}
43
44
uint32_t NativeFunctionSymbol::getAddressOffset() const {
45
return Sym.CodeOffset;
46
}
47
48
uint32_t NativeFunctionSymbol::getAddressSection() const { return Sym.Segment; }
49
std::string NativeFunctionSymbol::getName() const {
50
return std::string(Sym.Name);
51
}
52
53
uint64_t NativeFunctionSymbol::getLength() const { return Sym.CodeSize; }
54
55
uint32_t NativeFunctionSymbol::getRelativeVirtualAddress() const {
56
return Session.getRVAFromSectOffset(Sym.Segment, Sym.CodeOffset);
57
}
58
59
uint64_t NativeFunctionSymbol::getVirtualAddress() const {
60
return Session.getVAFromSectOffset(Sym.Segment, Sym.CodeOffset);
61
}
62
63
static bool inlineSiteContainsAddress(InlineSiteSym &IS,
64
uint32_t OffsetInFunc) {
65
// Returns true if inline site contains the offset.
66
bool Found = false;
67
uint32_t CodeOffset = 0;
68
for (auto &Annot : IS.annotations()) {
69
switch (Annot.OpCode) {
70
case BinaryAnnotationsOpCode::CodeOffset:
71
case BinaryAnnotationsOpCode::ChangeCodeOffset:
72
case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
73
CodeOffset += Annot.U1;
74
if (OffsetInFunc >= CodeOffset)
75
Found = true;
76
break;
77
case BinaryAnnotationsOpCode::ChangeCodeLength:
78
CodeOffset += Annot.U1;
79
if (Found && OffsetInFunc < CodeOffset)
80
return true;
81
Found = false;
82
break;
83
case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
84
CodeOffset += Annot.U2;
85
if (OffsetInFunc >= CodeOffset && OffsetInFunc < CodeOffset + Annot.U1)
86
return true;
87
Found = false;
88
break;
89
default:
90
break;
91
}
92
}
93
return false;
94
}
95
96
std::unique_ptr<IPDBEnumSymbols>
97
NativeFunctionSymbol::findInlineFramesByVA(uint64_t VA) const {
98
uint16_t Modi;
99
if (!Session.moduleIndexForVA(VA, Modi))
100
return nullptr;
101
102
Expected<ModuleDebugStreamRef> ModS = Session.getModuleDebugStream(Modi);
103
if (!ModS) {
104
consumeError(ModS.takeError());
105
return nullptr;
106
}
107
CVSymbolArray Syms = ModS->getSymbolArray();
108
109
// Search for inline sites. There should be one matching top level inline
110
// site. Then search in its nested inline sites.
111
std::vector<SymIndexId> Frames;
112
uint32_t CodeOffset = VA - getVirtualAddress();
113
auto Start = Syms.at(RecordOffset);
114
auto End = Syms.at(Sym.End);
115
while (Start != End) {
116
bool Found = false;
117
// Find matching inline site within Start and End.
118
for (; Start != End; ++Start) {
119
if (Start->kind() != S_INLINESITE)
120
continue;
121
122
InlineSiteSym IS =
123
cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(*Start));
124
if (inlineSiteContainsAddress(IS, CodeOffset)) {
125
// Insert frames in reverse order.
126
SymIndexId Id = Session.getSymbolCache().getOrCreateInlineSymbol(
127
IS, getVirtualAddress(), Modi, Start.offset());
128
Frames.insert(Frames.begin(), Id);
129
130
// Update offsets to search within this inline site.
131
++Start;
132
End = Syms.at(IS.End);
133
Found = true;
134
break;
135
}
136
137
Start = Syms.at(IS.End);
138
if (Start == End)
139
break;
140
}
141
142
if (!Found)
143
break;
144
}
145
146
return std::make_unique<NativeEnumSymbols>(Session, std::move(Frames));
147
}
148
149