Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Plugins/Protocol/MCP/Resource.cpp
213845 views
1
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2
// See https://llvm.org/LICENSE.txt for license information.
3
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
//
5
//===----------------------------------------------------------------------===//
6
7
#include "Resource.h"
8
#include "MCPError.h"
9
#include "lldb/Core/Debugger.h"
10
#include "lldb/Core/Module.h"
11
#include "lldb/Target/Platform.h"
12
13
using namespace lldb_private::mcp;
14
15
namespace {
16
struct DebuggerResource {
17
uint64_t debugger_id = 0;
18
std::string name;
19
uint64_t num_targets = 0;
20
};
21
22
llvm::json::Value toJSON(const DebuggerResource &DR) {
23
llvm::json::Object Result{{"debugger_id", DR.debugger_id},
24
{"num_targets", DR.num_targets}};
25
if (!DR.name.empty())
26
Result.insert({"name", DR.name});
27
return Result;
28
}
29
30
struct TargetResource {
31
size_t debugger_id = 0;
32
size_t target_idx = 0;
33
bool selected = false;
34
bool dummy = false;
35
std::string arch;
36
std::string path;
37
std::string platform;
38
};
39
40
llvm::json::Value toJSON(const TargetResource &TR) {
41
llvm::json::Object Result{{"debugger_id", TR.debugger_id},
42
{"target_idx", TR.target_idx},
43
{"selected", TR.selected},
44
{"dummy", TR.dummy}};
45
if (!TR.arch.empty())
46
Result.insert({"arch", TR.arch});
47
if (!TR.path.empty())
48
Result.insert({"path", TR.path});
49
if (!TR.platform.empty())
50
Result.insert({"platform", TR.platform});
51
return Result;
52
}
53
} // namespace
54
55
static constexpr llvm::StringLiteral kMimeTypeJSON = "application/json";
56
57
template <typename... Args>
58
static llvm::Error createStringError(const char *format, Args &&...args) {
59
return llvm::createStringError(
60
llvm::formatv(format, std::forward<Args>(args)...).str());
61
}
62
63
static llvm::Error createUnsupportedURIError(llvm::StringRef uri) {
64
return llvm::make_error<UnsupportedURI>(uri.str());
65
}
66
67
protocol::Resource
68
DebuggerResourceProvider::GetDebuggerResource(Debugger &debugger) {
69
const lldb::user_id_t debugger_id = debugger.GetID();
70
71
protocol::Resource resource;
72
resource.uri = llvm::formatv("lldb://debugger/{0}", debugger_id);
73
resource.name = debugger.GetInstanceName();
74
resource.description =
75
llvm::formatv("Information about debugger instance {0}: {1}", debugger_id,
76
debugger.GetInstanceName());
77
resource.mimeType = kMimeTypeJSON;
78
return resource;
79
}
80
81
protocol::Resource
82
DebuggerResourceProvider::GetTargetResource(size_t target_idx, Target &target) {
83
const size_t debugger_id = target.GetDebugger().GetID();
84
85
std::string target_name = llvm::formatv("target {0}", target_idx);
86
87
if (Module *exe_module = target.GetExecutableModulePointer())
88
target_name = exe_module->GetFileSpec().GetFilename().GetString();
89
90
protocol::Resource resource;
91
resource.uri =
92
llvm::formatv("lldb://debugger/{0}/target/{1}", debugger_id, target_idx);
93
resource.name = target_name;
94
resource.description =
95
llvm::formatv("Information about target {0} in debugger instance {1}",
96
target_idx, debugger_id);
97
resource.mimeType = kMimeTypeJSON;
98
return resource;
99
}
100
101
std::vector<protocol::Resource> DebuggerResourceProvider::GetResources() const {
102
std::vector<protocol::Resource> resources;
103
104
const size_t num_debuggers = Debugger::GetNumDebuggers();
105
for (size_t i = 0; i < num_debuggers; ++i) {
106
lldb::DebuggerSP debugger_sp = Debugger::GetDebuggerAtIndex(i);
107
if (!debugger_sp)
108
continue;
109
resources.emplace_back(GetDebuggerResource(*debugger_sp));
110
111
TargetList &target_list = debugger_sp->GetTargetList();
112
const size_t num_targets = target_list.GetNumTargets();
113
for (size_t j = 0; j < num_targets; ++j) {
114
lldb::TargetSP target_sp = target_list.GetTargetAtIndex(j);
115
if (!target_sp)
116
continue;
117
resources.emplace_back(GetTargetResource(j, *target_sp));
118
}
119
}
120
121
return resources;
122
}
123
124
llvm::Expected<protocol::ResourceResult>
125
DebuggerResourceProvider::ReadResource(llvm::StringRef uri) const {
126
127
auto [protocol, path] = uri.split("://");
128
129
if (protocol != "lldb")
130
return createUnsupportedURIError(uri);
131
132
llvm::SmallVector<llvm::StringRef, 4> components;
133
path.split(components, '/');
134
135
if (components.size() < 2)
136
return createUnsupportedURIError(uri);
137
138
if (components[0] != "debugger")
139
return createUnsupportedURIError(uri);
140
141
size_t debugger_idx;
142
if (components[1].getAsInteger(0, debugger_idx))
143
return createStringError("invalid debugger id '{0}': {1}", components[1],
144
path);
145
146
if (components.size() > 3) {
147
if (components[2] != "target")
148
return createUnsupportedURIError(uri);
149
150
size_t target_idx;
151
if (components[3].getAsInteger(0, target_idx))
152
return createStringError("invalid target id '{0}': {1}", components[3],
153
path);
154
155
return ReadTargetResource(uri, debugger_idx, target_idx);
156
}
157
158
return ReadDebuggerResource(uri, debugger_idx);
159
}
160
161
llvm::Expected<protocol::ResourceResult>
162
DebuggerResourceProvider::ReadDebuggerResource(llvm::StringRef uri,
163
lldb::user_id_t debugger_id) {
164
lldb::DebuggerSP debugger_sp = Debugger::FindDebuggerWithID(debugger_id);
165
if (!debugger_sp)
166
return createStringError("invalid debugger id: {0}", debugger_id);
167
168
DebuggerResource debugger_resource;
169
debugger_resource.debugger_id = debugger_id;
170
debugger_resource.name = debugger_sp->GetInstanceName();
171
debugger_resource.num_targets = debugger_sp->GetTargetList().GetNumTargets();
172
173
protocol::ResourceContents contents;
174
contents.uri = uri;
175
contents.mimeType = kMimeTypeJSON;
176
contents.text = llvm::formatv("{0}", toJSON(debugger_resource));
177
178
protocol::ResourceResult result;
179
result.contents.push_back(contents);
180
return result;
181
}
182
183
llvm::Expected<protocol::ResourceResult>
184
DebuggerResourceProvider::ReadTargetResource(llvm::StringRef uri,
185
lldb::user_id_t debugger_id,
186
size_t target_idx) {
187
188
lldb::DebuggerSP debugger_sp = Debugger::FindDebuggerWithID(debugger_id);
189
if (!debugger_sp)
190
return createStringError("invalid debugger id: {0}", debugger_id);
191
192
TargetList &target_list = debugger_sp->GetTargetList();
193
lldb::TargetSP target_sp = target_list.GetTargetAtIndex(target_idx);
194
if (!target_sp)
195
return createStringError("invalid target idx: {0}", target_idx);
196
197
TargetResource target_resource;
198
target_resource.debugger_id = debugger_id;
199
target_resource.target_idx = target_idx;
200
target_resource.arch = target_sp->GetArchitecture().GetTriple().str();
201
target_resource.dummy = target_sp->IsDummyTarget();
202
target_resource.selected = target_sp == debugger_sp->GetSelectedTarget();
203
204
if (Module *exe_module = target_sp->GetExecutableModulePointer())
205
target_resource.path = exe_module->GetFileSpec().GetPath();
206
if (lldb::PlatformSP platform_sp = target_sp->GetPlatform())
207
target_resource.platform = platform_sp->GetName();
208
209
protocol::ResourceContents contents;
210
contents.uri = uri;
211
contents.mimeType = kMimeTypeJSON;
212
contents.text = llvm::formatv("{0}", toJSON(target_resource));
213
214
protocol::ResourceResult result;
215
result.contents.push_back(contents);
216
return result;
217
}
218
219