1515
1616namespace lldb_dap {
1717
18- // "WriteMemoryRequest": {
19- // "allOf": [ { "$ref": "#/definitions/Request" }, {
20- // "type": "object",
21- // "description": "Writes bytes to memory at the provided location.\n
22- // Clients should only call this request if the corresponding
23- // capability `supportsWriteMemoryRequest` is true.",
24- // "properties": {
25- // "command": {
26- // "type": "string",
27- // "enum": [ "writeMemory" ]
28- // },
29- // "arguments": {
30- // "$ref": "#/definitions/WriteMemoryArguments"
31- // }
32- // },
33- // "required": [ "command", "arguments" ]
34- // }]
35- // },
36- // "WriteMemoryArguments": {
37- // "type": "object",
38- // "description": "Arguments for `writeMemory` request.",
39- // "properties": {
40- // "memoryReference": {
41- // "type": "string",
42- // "description": "Memory reference to the base location to which
43- // data should be written."
44- // },
45- // "offset": {
46- // "type": "integer",
47- // "description": "Offset (in bytes) to be applied to the reference
48- // location before writing data. Can be negative."
49- // },
50- // "allowPartial": {
51- // "type": "boolean",
52- // "description": "Property to control partial writes. If true, the
53- // debug adapter should attempt to write memory even if the entire
54- // memory region is not writable. In such a case the debug adapter
55- // should stop after hitting the first byte of memory that cannot be
56- // written and return the number of bytes written in the response
57- // via the `offset` and `bytesWritten` properties.\nIf false or
58- // missing, a debug adapter should attempt to verify the region is
59- // writable before writing, and fail the response if it is not."
60- // },
61- // "data": {
62- // "type": "string",
63- // "description": "Bytes to write, encoded using base64."
64- // }
65- // },
66- // "required": [ "memoryReference", "data" ]
67- // },
68- // "WriteMemoryResponse": {
69- // "allOf": [ { "$ref": "#/definitions/Response" }, {
70- // "type": "object",
71- // "description": "Response to `writeMemory` request.",
72- // "properties": {
73- // "body": {
74- // "type": "object",
75- // "properties": {
76- // "offset": {
77- // "type": "integer",
78- // "description": "Property that should be returned when
79- // `allowPartial` is true to indicate the offset of the first
80- // byte of data successfully written. Can be negative."
81- // },
82- // "bytesWritten": {
83- // "type": "integer",
84- // "description": "Property that should be returned when
85- // `allowPartial` is true to indicate the number of bytes
86- // starting from address that were successfully written."
87- // }
88- // }
89- // }
90- // }
91- // }]
92- // },
93- void WriteMemoryRequestHandler::operator ()(
94- const llvm::json::Object &request) const {
95- llvm::json::Object response;
96- FillResponse (request, response);
97-
98- auto arguments = request.getObject (" arguments" );
99- llvm::StringRef memory_reference =
100- GetString (arguments, " memoryReference" ).value_or (" " );
101-
102- auto addr_opt = DecodeMemoryReference (memory_reference);
103- if (!addr_opt.has_value ()) {
104- dap.SendErrorResponse (response, " Malformed memory reference: " +
105- memory_reference.str ());
106- return ;
107- }
108- lldb::addr_t address =
109- *addr_opt + GetInteger<uint64_t >(arguments, " offset" ).value_or (0 );
110-
111- llvm::StringRef data64 = GetString (arguments, " data" ).value_or (" " );
112- if (data64.empty ()) {
113- dap.SendErrorResponse (response,
114- " Data cannot be empty value. Provide valid data" );
115- return ;
18+ // Writes bytes to memory at the provided location.
19+ //
20+ // Clients should only call this request if the corresponding capability
21+ // supportsWriteMemoryRequest is true.
22+ llvm::Expected<protocol::WriteMemoryResponseBody>
23+ WriteMemoryRequestHandler::Run (
24+ const protocol::WriteMemoryArguments &args) const {
25+ const lldb::addr_t address = args.memoryReference + args.offset .value_or (0 );
26+ ;
27+
28+ lldb::SBProcess process = dap.target .GetProcess ();
29+ if (!lldb::SBDebugger::StateIsStoppedState (process.GetState ()))
30+ return llvm::make_error<NotStoppedError>();
31+
32+ if (args.data .empty ()) {
33+ return llvm::make_error<DAPError>(
34+ " Data cannot be empty value. Provide valid data" );
11635 }
11736
11837 // The VSCode IDE or other DAP clients send memory data as a Base64 string.
11938 // This function decodes it into raw binary before writing it to the target
12039 // process memory.
12140 std::vector<char > output;
122- auto decode_error = llvm::decodeBase64 (data64 , output);
41+ auto decode_error = llvm::decodeBase64 (args. data , output);
12342
12443 if (decode_error) {
125- dap.SendErrorResponse (response,
126- llvm::toString (std::move (decode_error)).c_str ());
127- return ;
44+ return llvm::make_error<DAPError>(
45+ llvm::toString (std::move (decode_error)).c_str ());
12846 }
12947
130- bool allow_partial = GetBoolean (arguments, " allowPartial" ).value_or (true );
13148 lldb::SBError write_error;
13249 uint64_t bytes_written = 0 ;
13350
@@ -137,7 +54,7 @@ void WriteMemoryRequestHandler::operator()(
13754 // If 'allowPartial' is false or missing, a debug adapter should attempt to
13855 // verify the region is writable before writing, and fail the response if it
13956 // is not.
140- if (!allow_partial ) {
57+ if (!args. allowPartial . value_or ( false ) ) {
14158 // Start checking from the initial write address.
14259 lldb::addr_t start_address = address;
14360 // Compute the end of the write range.
@@ -153,10 +70,9 @@ void WriteMemoryRequestHandler::operator()(
15370 // Fail if the region info retrieval fails, is not writable, or the
15471 // range exceeds the region.
15572 if (!error.Success () || !region_info.IsWritable ()) {
156- dap.SendErrorResponse (response, " Memory 0x" +
157- llvm::utohexstr (address) +
158- " region is not writable" );
159- return ;
73+ return llvm::make_error<DAPError>(
74+ " Memory 0x" + llvm::utohexstr (args.memoryReference ) +
75+ " region is not writable" );
16076 }
16177 // If the current region covers the full requested range, stop futher
16278 // iterations.
@@ -174,15 +90,11 @@ void WriteMemoryRequestHandler::operator()(
17490 }
17591
17692 if (bytes_written == 0 ) {
177- dap.SendErrorResponse (response, write_error.GetCString ());
178- return ;
93+ return llvm::make_error<DAPError>(write_error.GetCString ());
17994 }
180-
181- llvm::json::Object body;
182- body.try_emplace (" bytesWritten" , std::move (bytes_written));
183-
184- response.try_emplace (" body" , std::move (body));
185- dap.SendJSON (llvm::json::Value (std::move (response)));
95+ protocol::WriteMemoryResponseBody response;
96+ response.bytesWritten = bytes_written;
97+ return response;
18698}
18799
188100} // namespace lldb_dap
0 commit comments