99#include " DAP.h"
1010#include " EventHelper.h"
1111#include " JSONUtils.h"
12+ #include " Protocol/ProtocolRequests.h"
13+ #include " Protocol/ProtocolTypes.h"
1214#include " RequestHandler.h"
1315#include " lldb/API/SBInstruction.h"
1416#include " llvm/ADT/StringExtras.h"
1517
18+ using namespace lldb_dap ::protocol;
19+
1620namespace lldb_dap {
1721
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
24+ // / `supportsDisassembleRequest` is true.
25+ llvm::Expected<DisassembleResponseBody>
26+ DisassembleRequestHandler::Run (const DisassembleArguments &args) const {
27+ std::vector<DisassembledInstruction> instructions;
10728
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- }
29+ auto addr_opt = DecodeMemoryReference (args.memoryReference );
30+ if (!addr_opt.has_value ())
31+ return llvm::make_error<DAPError>(" Malformed memory reference: " +
32+ args.memoryReference );
11633
117- const auto inst_count =
118- GetInteger<int64_t >(arguments, " instructionCount" ).value_or (0 );
34+ lldb::addr_t addr_ptr = *addr_opt;
35+ addr_ptr += args.instructionOffset .value_or (0 );
36+ lldb::SBAddress addr (addr_ptr, dap.target );
37+ if (!addr.IsValid ())
38+ return llvm::make_error<DAPError>(
39+ " Memory reference not found in the current binary." );
11940
12041 std::string flavor_string;
12142 const auto target_triple = llvm::StringRef (dap.target .GetTriple ());
@@ -132,19 +53,14 @@ void DisassembleRequestHandler::operator()(
13253 }
13354 }
13455
135- lldb::SBInstructionList insts =
136- dap. target . ReadInstructions ( addr, inst_count , flavor_string.c_str ());
56+ lldb::SBInstructionList insts = dap. target . ReadInstructions (
57+ addr, args. instructionCount , flavor_string.c_str ());
13758
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- }
59+ if (!insts.IsValid ())
60+ return llvm::make_error<DAPError>(
61+ " Failed to find instructions for memory address." );
14462
145- const bool resolveSymbols =
146- GetBoolean (arguments, " resolveSymbols" ).value_or (false );
147- llvm::json::Array instructions;
63+ const bool resolveSymbols = args.resolveSymbols .value_or (false );
14864 const auto num_insts = insts.GetSize ();
14965 for (size_t i = 0 ; i < num_insts; ++i) {
15066 lldb::SBInstruction inst = insts.GetInstructionAtIndex (i);
@@ -165,11 +81,10 @@ void DisassembleRequestHandler::operator()(
16581 }
16682 }
16783
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- };
84+ DisassembledInstruction disassembled_inst;
85+ disassembled_inst.address = " 0x" + llvm::utohexstr (inst_addr);
86+ disassembled_inst.instructionBytes =
87+ bytes.size () > 0 ? bytes.substr (0 , bytes.size () - 1 ) : " " ;
17388
17489 std::string instruction;
17590 llvm::raw_string_ostream si (instruction);
@@ -185,59 +100,53 @@ void DisassembleRequestHandler::operator()(
185100 : symbol.GetName ())
186101 << " : " ;
187102
188- if (resolveSymbols) {
189- disassembled_inst.try_emplace (" symbol" , symbol.GetDisplayName ());
190- }
103+ if (resolveSymbols)
104+ disassembled_inst.symbol = symbol.GetDisplayName ();
191105 }
192106
193107 si << llvm::formatv (" {0,7} {1,12}" , m, o);
194108 if (c && c[0 ]) {
195109 si << " ; " << c;
196110 }
197111
198- disassembled_inst.try_emplace ( " instruction" , instruction) ;
112+ disassembled_inst.instruction = instruction;
199113
200114 auto line_entry = addr.GetLineEntry ();
201115 // If the line number is 0 then the entry represents a compiler generated
202116 // location.
203117 if (line_entry.GetStartAddress () == addr && line_entry.IsValid () &&
204118 line_entry.GetFileSpec ().IsValid () && line_entry.GetLine () != 0 ) {
205119 auto source = CreateSource (line_entry);
206- disassembled_inst.try_emplace ( " location" , source);
120+ disassembled_inst.location = std::move ( source);
207121
208122 const auto line = line_entry.GetLine ();
209- if (line && line != LLDB_INVALID_LINE_NUMBER) {
210- disassembled_inst.try_emplace ( " line" , line) ;
211- }
123+ if (line != 0 && line != LLDB_INVALID_LINE_NUMBER)
124+ disassembled_inst.line = line;
125+
212126 const auto column = line_entry.GetColumn ();
213- if (column && column != LLDB_INVALID_COLUMN_NUMBER) {
214- disassembled_inst.try_emplace (" column" , column);
215- }
127+ if (column != 0 && column != LLDB_INVALID_COLUMN_NUMBER)
128+ disassembled_inst.column = column;
216129
217130 auto end_line_entry = line_entry.GetEndAddress ().GetLineEntry ();
218131 if (end_line_entry.IsValid () &&
219132 end_line_entry.GetFileSpec () == line_entry.GetFileSpec ()) {
220133 const auto end_line = end_line_entry.GetLine ();
221- if (end_line && end_line != LLDB_INVALID_LINE_NUMBER &&
134+ if (end_line != 0 && end_line != LLDB_INVALID_LINE_NUMBER &&
222135 end_line != line) {
223- disassembled_inst.try_emplace ( " endLine" , end_line) ;
136+ disassembled_inst.endLine = end_line;
224137
225138 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- }
139+ if (end_column != 0 && end_column != LLDB_INVALID_COLUMN_NUMBER &&
140+ end_column != column)
141+ disassembled_inst.endColumn = end_column - 1 ;
230142 }
231143 }
232144 }
233145
234- instructions.emplace_back (std::move (disassembled_inst));
146+ instructions.push_back (std::move (disassembled_inst));
235147 }
236148
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)));
149+ return DisassembleResponseBody{std::move (instructions)};
241150}
242151
243152} // namespace lldb_dap
0 commit comments