Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/DebugInfo/GSYM/GsymContext.cpp
213799 views
1
//===-- GsymContext.cpp ------------------------------------------------===//
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/GSYM/GsymContext.h"
10
11
#include "llvm/DebugInfo/GSYM/GsymReader.h"
12
#include "llvm/Support/Path.h"
13
14
using namespace llvm;
15
using namespace llvm::gsym;
16
17
GsymContext::GsymContext(std::unique_ptr<GsymReader> Reader)
18
: DIContext(CK_GSYM), Reader(std::move(Reader)) {}
19
20
void GsymContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {}
21
22
static bool fillLineInfoFromLocation(const SourceLocation &Location,
23
DILineInfoSpecifier Specifier,
24
DILineInfo &LineInfo) {
25
// FIXME Demangle in case of DINameKind::ShortName
26
if (Specifier.FNKind != DINameKind::None) {
27
LineInfo.FunctionName = Location.Name.str();
28
}
29
30
switch (Specifier.FLIKind) {
31
case DILineInfoSpecifier::FileLineInfoKind::RelativeFilePath:
32
// We have no information to determine the relative path, so we fall back to
33
// returning the absolute path.
34
case DILineInfoSpecifier::FileLineInfoKind::RawValue:
35
case DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath:
36
if (Location.Dir.empty()) {
37
if (Location.Base.empty())
38
LineInfo.FileName = DILineInfo::BadString;
39
else
40
LineInfo.FileName = Location.Base.str();
41
} else {
42
SmallString<128> Path(Location.Dir);
43
sys::path::append(Path, Location.Base);
44
LineInfo.FileName = static_cast<std::string>(Path);
45
}
46
break;
47
48
case DILineInfoSpecifier::FileLineInfoKind::BaseNameOnly:
49
LineInfo.FileName = Location.Base.str();
50
break;
51
52
default:
53
return false;
54
}
55
LineInfo.Line = Location.Line;
56
57
// We don't have information in GSYM to fill any of the Source, Column,
58
// StartFileName or StartLine attributes.
59
60
return true;
61
}
62
63
std::optional<DILineInfo>
64
GsymContext::getLineInfoForAddress(object::SectionedAddress Address,
65
DILineInfoSpecifier Specifier) {
66
if (Address.SectionIndex != object::SectionedAddress::UndefSection)
67
return {};
68
69
auto ResultOrErr = Reader->lookup(Address.Address);
70
71
if (!ResultOrErr) {
72
consumeError(ResultOrErr.takeError());
73
return {};
74
}
75
76
const auto &Result = *ResultOrErr;
77
78
DILineInfo LineInfo;
79
80
if (Result.Locations.empty()) {
81
// No debug info for this, we just had a symbol from the symbol table.
82
83
// FIXME Demangle in case of DINameKind::ShortName
84
if (Specifier.FNKind != DINameKind::None)
85
LineInfo.FunctionName = Result.FuncName.str();
86
} else if (!fillLineInfoFromLocation(Result.Locations.front(), Specifier,
87
LineInfo))
88
return {};
89
90
LineInfo.StartAddress = Result.FuncRange.start();
91
92
return LineInfo;
93
}
94
95
std::optional<DILineInfo>
96
GsymContext::getLineInfoForDataAddress(object::SectionedAddress Address) {
97
// We can't implement this, there's no such information in the GSYM file.
98
99
return {};
100
}
101
102
DILineInfoTable
103
GsymContext::getLineInfoForAddressRange(object::SectionedAddress Address,
104
uint64_t Size,
105
DILineInfoSpecifier Specifier) {
106
if (Size == 0)
107
return DILineInfoTable();
108
109
if (Address.SectionIndex != llvm::object::SectionedAddress::UndefSection)
110
return DILineInfoTable();
111
112
if (auto FuncInfoOrErr = Reader->getFunctionInfo(Address.Address)) {
113
DILineInfoTable Table;
114
if (FuncInfoOrErr->OptLineTable) {
115
const gsym::LineTable &LT = *FuncInfoOrErr->OptLineTable;
116
const uint64_t StartAddr = Address.Address;
117
const uint64_t EndAddr = Address.Address + Size;
118
for (const auto &LineEntry : LT) {
119
if (StartAddr <= LineEntry.Addr && LineEntry.Addr < EndAddr) {
120
// Use LineEntry.Addr, LineEntry.File (which is a file index into the
121
// files tables from the GsymReader), and LineEntry.Line (source line
122
// number) to add stuff to the DILineInfoTable
123
}
124
}
125
}
126
return Table;
127
} else {
128
consumeError(FuncInfoOrErr.takeError());
129
return DILineInfoTable();
130
}
131
}
132
133
DIInliningInfo
134
GsymContext::getInliningInfoForAddress(object::SectionedAddress Address,
135
DILineInfoSpecifier Specifier) {
136
auto ResultOrErr = Reader->lookup(Address.Address);
137
138
if (!ResultOrErr)
139
return {};
140
141
const auto &Result = *ResultOrErr;
142
143
DIInliningInfo InlineInfo;
144
145
for (const auto &Location : Result.Locations) {
146
DILineInfo LineInfo;
147
148
if (!fillLineInfoFromLocation(Location, Specifier, LineInfo))
149
return {};
150
151
// Hm, that's probably something that should only be filled in the first or
152
// last frame?
153
LineInfo.StartAddress = Result.FuncRange.start();
154
155
InlineInfo.addFrame(LineInfo);
156
}
157
158
return InlineInfo;
159
}
160
161
std::vector<DILocal>
162
GsymContext::getLocalsForAddress(object::SectionedAddress Address) {
163
// We can't implement this, there's no such information in the GSYM file.
164
165
return {};
166
}
167
168