9
9
#include " DAP.h"
10
10
#include " EventHelper.h"
11
11
#include " JSONUtils.h"
12
+ #include " Protocol/ProtocolRequests.h"
13
+ #include " Protocol/ProtocolTypes.h"
12
14
#include " RequestHandler.h"
13
15
#include " lldb/API/SBInstruction.h"
16
+ #include " lldb/lldb-types.h"
14
17
#include " llvm/ADT/StringExtras.h"
18
+ #include < optional>
19
+
20
+ using namespace lldb_dap ::protocol;
15
21
16
22
namespace lldb_dap {
17
23
18
- // "DisassembleRequest": {
19
- // "allOf": [ { "$ref": "#/definitions/Request" }, {
20
- // "type": "object",
21
- // "description": "Disassembles code stored at the provided
22
- // location.\nClients should only call this request if the corresponding
23
- // capability `supportsDisassembleRequest` is true.", "properties": {
24
- // "command": {
25
- // "type": "string",
26
- // "enum": [ "disassemble" ]
27
- // },
28
- // "arguments": {
29
- // "$ref": "#/definitions/DisassembleArguments"
30
- // }
31
- // },
32
- // "required": [ "command", "arguments" ]
33
- // }]
34
- // },
35
- // "DisassembleArguments": {
36
- // "type": "object",
37
- // "description": "Arguments for `disassemble` request.",
38
- // "properties": {
39
- // "memoryReference": {
40
- // "type": "string",
41
- // "description": "Memory reference to the base location containing the
42
- // instructions to disassemble."
43
- // },
44
- // "offset": {
45
- // "type": "integer",
46
- // "description": "Offset (in bytes) to be applied to the reference
47
- // location before disassembling. Can be negative."
48
- // },
49
- // "instructionOffset": {
50
- // "type": "integer",
51
- // "description": "Offset (in instructions) to be applied after the byte
52
- // offset (if any) before disassembling. Can be negative."
53
- // },
54
- // "instructionCount": {
55
- // "type": "integer",
56
- // "description": "Number of instructions to disassemble starting at the
57
- // specified location and offset.\nAn adapter must return exactly this
58
- // number of instructions - any unavailable instructions should be
59
- // replaced with an implementation-defined 'invalid instruction' value."
60
- // },
61
- // "resolveSymbols": {
62
- // "type": "boolean",
63
- // "description": "If true, the adapter should attempt to resolve memory
64
- // addresses and other values to symbolic names."
65
- // }
66
- // },
67
- // "required": [ "memoryReference", "instructionCount" ]
68
- // },
69
- // "DisassembleResponse": {
70
- // "allOf": [ { "$ref": "#/definitions/Response" }, {
71
- // "type": "object",
72
- // "description": "Response to `disassemble` request.",
73
- // "properties": {
74
- // "body": {
75
- // "type": "object",
76
- // "properties": {
77
- // "instructions": {
78
- // "type": "array",
79
- // "items": {
80
- // "$ref": "#/definitions/DisassembledInstruction"
81
- // },
82
- // "description": "The list of disassembled instructions."
83
- // }
84
- // },
85
- // "required": [ "instructions" ]
86
- // }
87
- // }
88
- // }]
89
- // }
90
- void DisassembleRequestHandler::operator ()(
91
- const llvm::json::Object &request) const {
92
- llvm::json::Object response;
93
- FillResponse (request, response);
94
- auto *arguments = request.getObject (" arguments" );
95
-
96
- llvm::StringRef memoryReference =
97
- GetString (arguments, " memoryReference" ).value_or (" " );
98
- auto addr_opt = DecodeMemoryReference (memoryReference);
99
- if (!addr_opt.has_value ()) {
100
- response[" success" ] = false ;
101
- response[" message" ] =
102
- " Malformed memory reference: " + memoryReference.str ();
103
- dap.SendJSON (llvm::json::Value (std::move (response)));
104
- return ;
105
- }
106
- lldb::addr_t addr_ptr = *addr_opt;
24
+ // / Disassembles code stored at the provided location.
25
+ // / Clients should only call this request if the corresponding capability
26
+ // / `supportsDisassembleRequest` is true.
27
+ llvm::Expected<DisassembleResponseBody>
28
+ DisassembleRequestHandler::Run (const DisassembleArguments &args) const {
29
+ std::vector<DisassembledInstruction> instructions;
107
30
108
- addr_ptr += GetInteger<int64_t >(arguments, " instructionOffset" ).value_or (0 );
109
- lldb::SBAddress addr (addr_ptr, dap.target );
110
- if (!addr.IsValid ()) {
111
- response[" success" ] = false ;
112
- response[" message" ] = " Memory reference not found in the current binary." ;
113
- dap.SendJSON (llvm::json::Value (std::move (response)));
114
- return ;
115
- }
31
+ std::optional<lldb::addr_t > addr_opt =
32
+ DecodeMemoryReference (args.memoryReference );
33
+ if (!addr_opt.has_value ())
34
+ return llvm::make_error<DAPError>(" Malformed memory reference: " +
35
+ args.memoryReference );
116
36
117
- const auto inst_count =
118
- GetInteger<int64_t >(arguments, " instructionCount" ).value_or (0 );
37
+ lldb::addr_t addr_ptr = *addr_opt;
38
+ addr_ptr += args.instructionOffset .value_or (0 );
39
+ lldb::SBAddress addr (addr_ptr, dap.target );
40
+ if (!addr.IsValid ())
41
+ return llvm::make_error<DAPError>(
42
+ " Memory reference not found in the current binary." );
119
43
120
44
std::string flavor_string;
121
45
const auto target_triple = llvm::StringRef (dap.target .GetTriple ());
@@ -132,19 +56,14 @@ void DisassembleRequestHandler::operator()(
132
56
}
133
57
}
134
58
135
- lldb::SBInstructionList insts =
136
- dap. target . ReadInstructions ( addr, inst_count , flavor_string.c_str ());
59
+ lldb::SBInstructionList insts = dap. target . ReadInstructions (
60
+ addr, args. instructionCount , flavor_string.c_str ());
137
61
138
- if (!insts.IsValid ()) {
139
- response[" success" ] = false ;
140
- response[" message" ] = " Failed to find instructions for memory address." ;
141
- dap.SendJSON (llvm::json::Value (std::move (response)));
142
- return ;
143
- }
62
+ if (!insts.IsValid ())
63
+ return llvm::make_error<DAPError>(
64
+ " Failed to find instructions for memory address." );
144
65
145
- const bool resolveSymbols =
146
- GetBoolean (arguments, " resolveSymbols" ).value_or (false );
147
- llvm::json::Array instructions;
66
+ const bool resolve_symbols = args.resolveSymbols .value_or (false );
148
67
const auto num_insts = insts.GetSize ();
149
68
for (size_t i = 0 ; i < num_insts; ++i) {
150
69
lldb::SBInstruction inst = insts.GetInstructionAtIndex (i);
@@ -165,11 +84,10 @@ void DisassembleRequestHandler::operator()(
165
84
}
166
85
}
167
86
168
- llvm::json::Object disassembled_inst{
169
- {" address" , " 0x" + llvm::utohexstr (inst_addr)},
170
- {" instructionBytes" ,
171
- bytes.size () > 0 ? bytes.substr (0 , bytes.size () - 1 ) : " " },
172
- };
87
+ DisassembledInstruction disassembled_inst;
88
+ disassembled_inst.address = inst_addr;
89
+ disassembled_inst.instructionBytes =
90
+ bytes.size () > 0 ? bytes.substr (0 , bytes.size () - 1 ) : " " ;
173
91
174
92
std::string instruction;
175
93
llvm::raw_string_ostream si (instruction);
@@ -185,59 +103,53 @@ void DisassembleRequestHandler::operator()(
185
103
: symbol.GetName ())
186
104
<< " : " ;
187
105
188
- if (resolveSymbols) {
189
- disassembled_inst.try_emplace (" symbol" , symbol.GetDisplayName ());
190
- }
106
+ if (resolve_symbols)
107
+ disassembled_inst.symbol = symbol.GetDisplayName ();
191
108
}
192
109
193
110
si << llvm::formatv (" {0,7} {1,12}" , m, o);
194
111
if (c && c[0 ]) {
195
112
si << " ; " << c;
196
113
}
197
114
198
- disassembled_inst.try_emplace ( " instruction" , instruction) ;
115
+ disassembled_inst.instruction = instruction;
199
116
200
117
auto line_entry = addr.GetLineEntry ();
201
118
// If the line number is 0 then the entry represents a compiler generated
202
119
// location.
203
120
if (line_entry.GetStartAddress () == addr && line_entry.IsValid () &&
204
121
line_entry.GetFileSpec ().IsValid () && line_entry.GetLine () != 0 ) {
205
122
auto source = CreateSource (line_entry);
206
- disassembled_inst.try_emplace ( " location" , source);
123
+ disassembled_inst.location = std::move ( source);
207
124
208
125
const auto line = line_entry.GetLine ();
209
- if (line && line != LLDB_INVALID_LINE_NUMBER) {
210
- disassembled_inst.try_emplace ( " line" , line) ;
211
- }
126
+ if (line != 0 && line != LLDB_INVALID_LINE_NUMBER)
127
+ disassembled_inst.line = line;
128
+
212
129
const auto column = line_entry.GetColumn ();
213
- if (column && column != LLDB_INVALID_COLUMN_NUMBER) {
214
- disassembled_inst.try_emplace (" column" , column);
215
- }
130
+ if (column != 0 && column != LLDB_INVALID_COLUMN_NUMBER)
131
+ disassembled_inst.column = column;
216
132
217
133
auto end_line_entry = line_entry.GetEndAddress ().GetLineEntry ();
218
134
if (end_line_entry.IsValid () &&
219
135
end_line_entry.GetFileSpec () == line_entry.GetFileSpec ()) {
220
136
const auto end_line = end_line_entry.GetLine ();
221
- if (end_line && end_line != LLDB_INVALID_LINE_NUMBER &&
137
+ if (end_line != 0 && end_line != LLDB_INVALID_LINE_NUMBER &&
222
138
end_line != line) {
223
- disassembled_inst.try_emplace ( " endLine" , end_line) ;
139
+ disassembled_inst.endLine = end_line;
224
140
225
141
const auto end_column = end_line_entry.GetColumn ();
226
- if (end_column && end_column != LLDB_INVALID_COLUMN_NUMBER &&
227
- end_column != column) {
228
- disassembled_inst.try_emplace (" endColumn" , end_column - 1 );
229
- }
142
+ if (end_column != 0 && end_column != LLDB_INVALID_COLUMN_NUMBER &&
143
+ end_column != column)
144
+ disassembled_inst.endColumn = end_column - 1 ;
230
145
}
231
146
}
232
147
}
233
148
234
- instructions.emplace_back (std::move (disassembled_inst));
149
+ instructions.push_back (std::move (disassembled_inst));
235
150
}
236
151
237
- llvm::json::Object body;
238
- body.try_emplace (" instructions" , std::move (instructions));
239
- response.try_emplace (" body" , std::move (body));
240
- dap.SendJSON (llvm::json::Value (std::move (response)));
152
+ return DisassembleResponseBody{std::move (instructions)};
241
153
}
242
154
243
155
} // namespace lldb_dap
0 commit comments