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"
14
16
#include " llvm/ADT/StringExtras.h"
15
17
18
+ using namespace lldb_dap ::protocol;
19
+
16
20
namespace lldb_dap {
17
21
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;
22
+ // / Disassembles code stored at the provided location.
23
+ // / Clients should only call this request if the corresponding capability `supportsDisassembleRequest` is true.
24
+ llvm::Expected<DisassembleResponseBody> DisassembleRequestHandler::Run (const DisassembleArguments &args) const {
25
+ std::vector<DisassembledInstruction> instructions;
107
26
108
- addr_ptr += GetInteger<int64_t >(arguments, " instructionOffset" ).value_or (0 );
27
+ auto addr_opt = DecodeMemoryReference (args.memoryReference );
28
+ if (!addr_opt.has_value ())
29
+ return llvm::make_error<DAPError>(" Malformed memory reference: " + args.memoryReference );
30
+
31
+ lldb::addr_t addr_ptr = *addr_opt;
32
+ addr_ptr += args.instructionOffset .value_or (0 );
109
33
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
- }
116
-
117
- const auto inst_count =
118
- GetInteger<int64_t >(arguments, " instructionCount" ).value_or (0 );
34
+ if (!addr.IsValid ())
35
+ return llvm::make_error<DAPError>(" Memory reference not found in the current binary." );
119
36
120
37
std::string flavor_string;
121
38
const auto target_triple = llvm::StringRef (dap.target .GetTriple ());
@@ -133,18 +50,12 @@ void DisassembleRequestHandler::operator()(
133
50
}
134
51
135
52
lldb::SBInstructionList insts =
136
- dap.target .ReadInstructions (addr, inst_count , flavor_string.c_str ());
53
+ dap.target .ReadInstructions (addr, args. instructionCount , flavor_string.c_str ());
137
54
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
- }
55
+ if (!insts.IsValid ())
56
+ return llvm::make_error<DAPError>(" Failed to find instructions for memory address." );
144
57
145
- const bool resolveSymbols =
146
- GetBoolean (arguments, " resolveSymbols" ).value_or (false );
147
- llvm::json::Array instructions;
58
+ const bool resolveSymbols = args.resolveSymbols .value_or (false );
148
59
const auto num_insts = insts.GetSize ();
149
60
for (size_t i = 0 ; i < num_insts; ++i) {
150
61
lldb::SBInstruction inst = insts.GetInstructionAtIndex (i);
@@ -165,11 +76,9 @@ void DisassembleRequestHandler::operator()(
165
76
}
166
77
}
167
78
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
- };
79
+ DisassembledInstruction disassembled_inst;
80
+ disassembled_inst.address = " 0x" + llvm::utohexstr (inst_addr);
81
+ disassembled_inst.instructionBytes = bytes.size () > 0 ? bytes.substr (0 , bytes.size () - 1 ) : " " ;
173
82
174
83
std::string instruction;
175
84
llvm::raw_string_ostream si (instruction);
@@ -185,59 +94,52 @@ void DisassembleRequestHandler::operator()(
185
94
: symbol.GetName ())
186
95
<< " : " ;
187
96
188
- if (resolveSymbols) {
189
- disassembled_inst.try_emplace (" symbol" , symbol.GetDisplayName ());
190
- }
97
+ if (resolveSymbols)
98
+ disassembled_inst.symbol = symbol.GetDisplayName ();
191
99
}
192
100
193
101
si << llvm::formatv (" {0,7} {1,12}" , m, o);
194
102
if (c && c[0 ]) {
195
103
si << " ; " << c;
196
104
}
197
105
198
- disassembled_inst.try_emplace ( " instruction" , instruction) ;
106
+ disassembled_inst.instruction = instruction;
199
107
200
108
auto line_entry = addr.GetLineEntry ();
201
109
// If the line number is 0 then the entry represents a compiler generated
202
110
// location.
203
111
if (line_entry.GetStartAddress () == addr && line_entry.IsValid () &&
204
112
line_entry.GetFileSpec ().IsValid () && line_entry.GetLine () != 0 ) {
205
113
auto source = CreateSource (line_entry);
206
- disassembled_inst.try_emplace ( " location" , source);
114
+ disassembled_inst.location = std::move ( source);
207
115
208
116
const auto line = line_entry.GetLine ();
209
- if (line && line != LLDB_INVALID_LINE_NUMBER) {
210
- disassembled_inst.try_emplace ( " line" , line) ;
211
- }
117
+ if (line != 0 && line != LLDB_INVALID_LINE_NUMBER)
118
+ disassembled_inst.line = line;
119
+
212
120
const auto column = line_entry.GetColumn ();
213
- if (column && column != LLDB_INVALID_COLUMN_NUMBER) {
214
- disassembled_inst.try_emplace (" column" , column);
215
- }
121
+ if (column != 0 && column != LLDB_INVALID_COLUMN_NUMBER)
122
+ disassembled_inst.column = column;
216
123
217
124
auto end_line_entry = line_entry.GetEndAddress ().GetLineEntry ();
218
125
if (end_line_entry.IsValid () &&
219
126
end_line_entry.GetFileSpec () == line_entry.GetFileSpec ()) {
220
127
const auto end_line = end_line_entry.GetLine ();
221
- if (end_line && end_line != LLDB_INVALID_LINE_NUMBER &&
222
- end_line != line) {
223
- disassembled_inst.try_emplace (" endLine" , end_line);
128
+ if (end_line != 0 && end_line != LLDB_INVALID_LINE_NUMBER && end_line != line) {
129
+ disassembled_inst.endLine = end_line;
224
130
225
131
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
- }
132
+ if (end_column != 0 && end_column != LLDB_INVALID_COLUMN_NUMBER &&
133
+ end_column != column)
134
+ disassembled_inst.endColumn = end_column - 1 ;
230
135
}
231
136
}
232
137
}
233
138
234
- instructions.emplace_back (std::move (disassembled_inst));
139
+ instructions.push_back (std::move (disassembled_inst));
235
140
}
236
141
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)));
142
+ return DisassembleResponseBody{std::move (instructions)};
241
143
}
242
144
243
145
} // namespace lldb_dap
0 commit comments