xref: /haiku/src/kits/debugger/debugger_interface/remote/RemoteDebugRequest.cpp (revision 6c2abee2f5e73c3fc81c33da51ac610f8bf1117a)
1 /*
2  * Copyright 2016, Rene Gollent, rene@gollent.com.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "RemoteDebugRequest.h"
8 
9 #include "Architecture.h"
10 #include "CpuState.h"
11 
12 #include <AutoDeleter.h>
13 
14 #include <Message.h>
15 
16 #include <stdlib.h>
17 
18 
19 // #pragma mark - RemoteDebugRequest
20 
21 
22 RemoteDebugRequest::RemoteDebugRequest()
23 	:
24 	BReferenceable(),
25 	fArchitecture(NULL)
26 {
27 }
28 
29 
30 RemoteDebugRequest::~RemoteDebugRequest()
31 {
32 	if (fArchitecture != NULL)
33 		fArchitecture->ReleaseReference();
34 }
35 
36 
37 status_t
38 RemoteDebugRequest::LoadFromMessage(const BMessage& data)
39 {
40 	if (data.FindInt32("type") != Type())
41 		return B_BAD_VALUE;
42 
43 	return LoadSpecificInfoFromMessage(data);
44 }
45 
46 
47 status_t
48 RemoteDebugRequest::SaveToMessage(BMessage& _output) const
49 {
50 	_output.MakeEmpty();
51 
52 	status_t error = _output.AddInt32("type", Type());
53 	if (error != B_OK)
54 		return error;
55 
56 	return SaveSpecificInfoToMessage(_output);
57 }
58 
59 
60 void
61 RemoteDebugRequest::SetArchitecture(Architecture* architecture)
62 {
63 	fArchitecture = architecture;
64 	fArchitecture->AcquireReference();
65 }
66 
67 
68 // #pragma mark - RemoteDebugResponse
69 
70 
71 RemoteDebugResponse::RemoteDebugResponse()
72 	:
73 	BReferenceable(),
74 	fRequest(NULL),
75 	fResult(B_OK)
76 {
77 }
78 
79 
80 RemoteDebugResponse::~RemoteDebugResponse()
81 {
82 	if (fRequest != NULL)
83 		fRequest->ReleaseReference();
84 }
85 
86 
87 void
88 RemoteDebugResponse::SetRequestInfo(RemoteDebugRequest* request,
89 	status_t result)
90 {
91 	fRequest = request;
92 	fRequest->AcquireReference();
93 	fResult = result;
94 }
95 
96 
97 status_t
98 RemoteDebugResponse::LoadFromMessage(const BMessage& data)
99 {
100 	if (data.FindInt32("type") != Request()->Type())
101 		return B_BAD_VALUE;
102 
103 	if (!Succeeded())
104 		return B_OK;
105 
106 	return LoadSpecificInfoFromMessage(data);
107 }
108 
109 
110 status_t
111 RemoteDebugResponse::SaveToMessage(BMessage& _output) const
112 {
113 	_output.MakeEmpty();
114 
115 	status_t error = _output.AddInt32("type", Request()->Type());
116 	if (error != B_OK)
117 		return error;
118 
119 	error = _output.AddInt32("result", Result());
120 	if (error != B_OK)
121 		return error;
122 
123 	if (!Succeeded())
124 		return B_OK;
125 
126 	return SaveSpecificInfoToMessage(_output);
127 }
128 
129 
130 status_t
131 RemoteDebugResponse::LoadSpecificInfoFromMessage(const BMessage& data)
132 {
133 	return B_OK;
134 }
135 
136 
137 status_t
138 RemoteDebugResponse::SaveSpecificInfoToMessage(BMessage& _output) const
139 {
140 	return B_OK;
141 }
142 
143 
144 // #pragma mark - RemoteDebugReadMemoryRequest
145 
146 
147 RemoteDebugReadMemoryRequest::RemoteDebugReadMemoryRequest()
148 	:
149 	RemoteDebugRequest(),
150 	fAddress(0),
151 	fSize(0)
152 {
153 }
154 
155 
156 RemoteDebugReadMemoryRequest::~RemoteDebugReadMemoryRequest()
157 {
158 }
159 
160 
161 void
162 RemoteDebugReadMemoryRequest::SetTo(target_addr_t address, target_size_t size)
163 {
164 	fAddress = address;
165 	fSize = size;
166 }
167 
168 
169 remote_request_type
170 RemoteDebugReadMemoryRequest::Type() const
171 {
172 	return REMOTE_REQUEST_TYPE_READ_MEMORY;
173 }
174 
175 
176 status_t
177 RemoteDebugReadMemoryRequest::LoadSpecificInfoFromMessage(const BMessage& data)
178 {
179 	if (data.FindUInt64("address", &fAddress) != B_OK)
180 		return B_BAD_VALUE;
181 
182 	if (data.FindUInt64("size", &fSize) != B_OK)
183 		return B_BAD_VALUE;
184 
185 	return B_OK;
186 }
187 
188 
189 status_t
190 RemoteDebugReadMemoryRequest::SaveSpecificInfoToMessage(
191 	BMessage& _output) const
192 {
193 	status_t error = _output.AddUInt64("address", fAddress);
194 	if (error != B_OK)
195 		return error;
196 
197 	return _output.AddUInt64("size", fSize);
198 }
199 
200 
201 // #pragma mark - RemoteDebugWriteMemoryRequest
202 
203 
204 RemoteDebugWriteMemoryRequest::RemoteDebugWriteMemoryRequest()
205 	:
206 	RemoteDebugRequest(),
207 	fAddress(0),
208 	fData(NULL),
209 	fSize(0)
210 {
211 }
212 
213 
214 RemoteDebugWriteMemoryRequest::~RemoteDebugWriteMemoryRequest()
215 {
216 	if (fData != NULL)
217 		free(fData);
218 }
219 
220 
221 status_t
222 RemoteDebugWriteMemoryRequest::SetTo(target_addr_t address, const void* data,
223 	target_size_t size)
224 {
225 	if (size == 0 || data == NULL)
226 		return B_BAD_VALUE;
227 
228 	fAddress = address;
229 	fSize = size;
230 	fData = malloc(fSize);
231 	if (fData == NULL)
232 		return B_NO_MEMORY;
233 
234 
235 	memcpy(fData, data, fSize);
236 	return B_OK;
237 }
238 
239 
240 remote_request_type
241 RemoteDebugWriteMemoryRequest::Type() const
242 {
243 	return REMOTE_REQUEST_TYPE_WRITE_MEMORY;
244 }
245 
246 
247 status_t
248 RemoteDebugWriteMemoryRequest::LoadSpecificInfoFromMessage(
249 	const BMessage& data)
250 {
251 	if (data.FindUInt64("address", &fAddress) != B_OK)
252 		return B_BAD_VALUE;
253 
254 	if (data.FindUInt64("size", &fSize) != B_OK)
255 		return B_BAD_VALUE;
256 
257 	fData = malloc(fSize);
258 	if (fData == NULL)
259 		return B_NO_MEMORY;
260 
261 	const void* messageData = NULL;
262 	ssize_t numBytes = -1;
263 	status_t error = data.FindData("data", B_RAW_TYPE, &messageData,
264 		&numBytes);
265 	if (error != B_OK)
266 		return error;
267 
268 	if ((size_t)numBytes != fSize)
269 		return B_MISMATCHED_VALUES;
270 
271 	memcpy(fData, messageData, numBytes);
272 
273 	return B_OK;
274 }
275 
276 
277 status_t
278 RemoteDebugWriteMemoryRequest::SaveSpecificInfoToMessage(
279 	BMessage& _output) const
280 {
281 	status_t error = _output.AddUInt64("address", fAddress);
282 	if (error != B_OK)
283 		return error;
284 
285 	error = _output.AddUInt64("size", fSize);
286 	if (error != B_OK)
287 		return error;
288 
289 	return _output.AddData("data", B_RAW_TYPE, fData, (ssize_t)fSize);
290 }
291 
292 
293 // #pragma mark - RemoteDebugSetTeamFlagsRequest
294 
295 
296 RemoteDebugSetTeamFlagsRequest::RemoteDebugSetTeamFlagsRequest()
297 	:
298 	RemoteDebugRequest(),
299 	fFlags(0)
300 {
301 }
302 
303 
304 RemoteDebugSetTeamFlagsRequest::~RemoteDebugSetTeamFlagsRequest()
305 {
306 }
307 
308 
309 void
310 RemoteDebugSetTeamFlagsRequest::SetTo(int32 flags)
311 {
312 	fFlags = flags;
313 }
314 
315 
316 remote_request_type
317 RemoteDebugSetTeamFlagsRequest::Type() const
318 {
319 	return REMOTE_REQUEST_TYPE_SET_TEAM_FLAGS;
320 }
321 
322 
323 status_t
324 RemoteDebugSetTeamFlagsRequest::LoadSpecificInfoFromMessage(
325 	const BMessage& data)
326 {
327 	if (data.FindInt32("flags", &fFlags) != B_OK)
328 		return B_BAD_VALUE;
329 
330 	return B_OK;
331 }
332 
333 
334 status_t
335 RemoteDebugSetTeamFlagsRequest::SaveSpecificInfoToMessage(
336 	BMessage& _output) const
337 {
338 	return _output.AddInt32("flags", fFlags);
339 }
340 
341 
342 // #pragma mark - RemoteDebugSetThreadFlagsRequest
343 
344 
345 RemoteDebugSetThreadFlagsRequest::RemoteDebugSetThreadFlagsRequest()
346 	:
347 	RemoteDebugRequest(),
348 	fThread(-1),
349 	fFlags(0)
350 {
351 }
352 
353 
354 RemoteDebugSetThreadFlagsRequest::~RemoteDebugSetThreadFlagsRequest()
355 {
356 }
357 
358 
359 void
360 RemoteDebugSetThreadFlagsRequest::SetTo(thread_id thread, int32 flags)
361 {
362 	fThread = thread;
363 	fFlags = flags;
364 }
365 
366 
367 remote_request_type
368 RemoteDebugSetThreadFlagsRequest::Type() const
369 {
370 	return REMOTE_REQUEST_TYPE_SET_THREAD_FLAGS;
371 }
372 
373 
374 status_t
375 RemoteDebugSetThreadFlagsRequest::LoadSpecificInfoFromMessage(
376 	const BMessage& data)
377 {
378 	if (data.FindInt32("thread", &fThread) != B_OK)
379 		return B_BAD_VALUE;
380 
381 	if (data.FindInt32("flags", &fFlags) != B_OK)
382 		return B_BAD_VALUE;
383 
384 	return B_OK;
385 }
386 
387 
388 status_t
389 RemoteDebugSetThreadFlagsRequest::SaveSpecificInfoToMessage(
390 	BMessage& _output) const
391 {
392 	status_t error = _output.AddInt32("thread", fThread);
393 	if (error != B_OK)
394 		return error;
395 
396 	return _output.AddInt32("flags", fFlags);
397 }
398 
399 
400 // #pragma mark - RemoteDebugThreadActionRequest
401 
402 
403 RemoteDebugThreadActionRequest::RemoteDebugThreadActionRequest()
404 	:
405 	RemoteDebugRequest(),
406 	fThread(-1)
407 {
408 }
409 
410 
411 RemoteDebugThreadActionRequest::~RemoteDebugThreadActionRequest()
412 {
413 }
414 
415 
416 void
417 RemoteDebugThreadActionRequest::SetTo(thread_id thread)
418 {
419 	fThread = thread;
420 }
421 
422 
423 status_t
424 RemoteDebugThreadActionRequest::LoadSpecificInfoFromMessage(
425 	const BMessage& data)
426 {
427 	if (data.FindInt32("thread", &fThread) != B_OK)
428 		return B_BAD_VALUE;
429 
430 	return B_OK;
431 }
432 
433 
434 status_t
435 RemoteDebugThreadActionRequest::SaveSpecificInfoToMessage(
436 	BMessage& _output) const
437 {
438 	return _output.AddInt32("thread", fThread);
439 }
440 
441 
442 // #pragma mark - RemoteDebugContinueThreadRequest
443 
444 
445 RemoteDebugContinueThreadRequest::RemoteDebugContinueThreadRequest()
446 	:
447 	RemoteDebugThreadActionRequest()
448 {
449 }
450 
451 
452 RemoteDebugContinueThreadRequest::~RemoteDebugContinueThreadRequest()
453 {
454 }
455 
456 remote_request_type
457 RemoteDebugContinueThreadRequest::Type() const
458 {
459 	return REMOTE_REQUEST_TYPE_CONTINUE_THREAD;
460 }
461 
462 
463 // #pragma mark - RemoteDebugStopThreadRequest
464 
465 
466 RemoteDebugStopThreadRequest::RemoteDebugStopThreadRequest()
467 	:
468 	RemoteDebugThreadActionRequest()
469 {
470 }
471 
472 
473 RemoteDebugStopThreadRequest::~RemoteDebugStopThreadRequest()
474 {
475 }
476 
477 remote_request_type
478 RemoteDebugStopThreadRequest::Type() const
479 {
480 	return REMOTE_REQUEST_TYPE_STOP_THREAD;
481 }
482 
483 
484 // #pragma mark - RemoteDebugSingleStepThreadRequest
485 
486 
487 RemoteDebugSingleStepThreadRequest::RemoteDebugSingleStepThreadRequest()
488 	:
489 	RemoteDebugThreadActionRequest()
490 {
491 }
492 
493 
494 RemoteDebugSingleStepThreadRequest::~RemoteDebugSingleStepThreadRequest()
495 {
496 }
497 
498 remote_request_type
499 RemoteDebugSingleStepThreadRequest::Type() const
500 {
501 	return REMOTE_REQUEST_TYPE_SINGLE_STEP_THREAD;
502 }
503 
504 
505 // #pragma mark - RemoteDebugGetCpuStateRequest
506 
507 
508 RemoteDebugGetCpuStateRequest::RemoteDebugGetCpuStateRequest()
509 	:
510 	RemoteDebugThreadActionRequest()
511 {
512 }
513 
514 
515 RemoteDebugGetCpuStateRequest::~RemoteDebugGetCpuStateRequest()
516 {
517 }
518 
519 
520 remote_request_type
521 RemoteDebugGetCpuStateRequest::Type() const
522 {
523 	return REMOTE_REQUEST_TYPE_GET_CPU_STATE;
524 }
525 
526 
527 // #pragma mark - RemoteDebugSetCpuStateRequest
528 
529 
530 RemoteDebugSetCpuStateRequest::RemoteDebugSetCpuStateRequest()
531 	:
532 	RemoteDebugRequest(),
533 	fThread(-1),
534 	fCpuState(NULL)
535 {
536 }
537 
538 
539 RemoteDebugSetCpuStateRequest::~RemoteDebugSetCpuStateRequest()
540 {
541 	if (fCpuState != NULL)
542 		fCpuState->ReleaseReference();
543 }
544 
545 
546 void
547 RemoteDebugSetCpuStateRequest::SetTo(thread_id thread, CpuState* state)
548 {
549 	fThread = thread;
550 	fCpuState = state;
551 	if (fCpuState != NULL)
552 		fCpuState->AcquireReference();
553 }
554 
555 
556 remote_request_type
557 RemoteDebugSetCpuStateRequest::Type() const
558 {
559 	return REMOTE_REQUEST_TYPE_SET_CPU_STATE;
560 }
561 
562 
563 status_t
564 RemoteDebugSetCpuStateRequest::LoadSpecificInfoFromMessage(
565 	const BMessage& data)
566 {
567 	if (data.FindInt32("thread", &fThread) != B_OK)
568 		return B_BAD_VALUE;
569 
570 	if (fCpuState != NULL) {
571 		fCpuState->ReleaseReference();
572 		fCpuState = NULL;
573 	}
574 
575 	const uint8* buffer = NULL;
576 	ssize_t numBytes = 0;
577 	size_t stateSize = GetArchitecture()->DebugCpuStateSize();
578 	status_t error = data.FindData("state", B_RAW_TYPE, (const void**)&buffer,
579 		&numBytes);
580 	if (error != B_OK || (size_t)numBytes != stateSize)
581 		return B_BAD_VALUE;
582 
583 	return GetArchitecture()->CreateCpuState(buffer, stateSize, fCpuState);
584 }
585 
586 
587 status_t
588 RemoteDebugSetCpuStateRequest::SaveSpecificInfoToMessage(
589 	BMessage& _output) const
590 {
591 	status_t error = _output.AddInt32("thread", fThread);
592 	if (error != B_OK)
593 		return error;
594 
595 	size_t stateSize = GetArchitecture()->DebugCpuStateSize();
596 	uint8* buffer = new(std::nothrow) uint8[stateSize];
597 	if (buffer == NULL)
598 		return B_NO_MEMORY;
599 
600 	ArrayDeleter<uint8> deleter(buffer);
601 	error = fCpuState->UpdateDebugState(buffer, stateSize);
602 	if (error != B_OK)
603 		return error;
604 
605 	return _output.AddData("state", B_RAW_TYPE, buffer, (ssize_t)stateSize);
606 }
607 
608 
609 // #pragma mark - RemoteDebugReadMemoryResponse
610 
611 
612 RemoteDebugReadMemoryResponse::RemoteDebugReadMemoryResponse()
613 	:
614 	RemoteDebugResponse(),
615 	fData(NULL),
616 	fSize(0)
617 {
618 }
619 
620 
621 RemoteDebugReadMemoryResponse::~RemoteDebugReadMemoryResponse()
622 {
623 	if (fData != NULL)
624 		free(fData);
625 }
626 
627 
628 void
629 RemoteDebugReadMemoryResponse::SetTo(void* data, target_size_t size)
630 {
631 	fData = data;
632 	fSize = size;
633 }
634 
635 
636 status_t
637 RemoteDebugReadMemoryResponse::LoadSpecificInfoFromMessage(
638 	const BMessage& data)
639 {
640 	status_t error = data.FindUInt64("size", &fSize);
641 	if (error != B_OK)
642 		return error;
643 
644 	fData = malloc(fSize);
645 	if (fData == NULL)
646 		return B_NO_MEMORY;
647 
648 	const void* messageData = NULL;
649 	ssize_t numBytes = -1;
650 	error = data.FindData("data", B_RAW_TYPE, &messageData, &numBytes);
651 	if (error != B_OK)
652 		return error;
653 
654 	if ((size_t)numBytes != fSize)
655 		return B_MISMATCHED_VALUES;
656 
657 	memcpy(fData, messageData, numBytes);
658 	return B_OK;
659 }
660 
661 
662 status_t
663 RemoteDebugReadMemoryResponse::SaveSpecificInfoToMessage(
664 	BMessage& _output) const
665 {
666 	if (fData == NULL)
667 		return B_OK;
668 
669 	status_t error = _output.AddUInt64("size", fSize);
670 	if (error != B_OK)
671 		return error;
672 
673 	return _output.AddData("data", B_RAW_TYPE, fData, (ssize_t)fSize);
674 }
675 
676 
677 // #pragma mark - RemoteDebugGetCpuStateResponse
678 
679 
680 RemoteDebugGetCpuStateResponse::RemoteDebugGetCpuStateResponse()
681 	:
682 	RemoteDebugResponse(),
683 	fCpuState(NULL)
684 {
685 }
686 
687 
688 RemoteDebugGetCpuStateResponse::~RemoteDebugGetCpuStateResponse()
689 {
690 	if (fCpuState != NULL)
691 		fCpuState->ReleaseReference();
692 }
693 
694 
695 void
696 RemoteDebugGetCpuStateResponse::SetTo(CpuState* state)
697 {
698 	fCpuState = state;
699 	if (fCpuState != NULL)
700 		fCpuState->AcquireReference();
701 }
702 
703 
704 status_t
705 RemoteDebugGetCpuStateResponse::LoadSpecificInfoFromMessage(
706 	const BMessage& data)
707 {
708 	if (fCpuState != NULL) {
709 		fCpuState->ReleaseReference();
710 		fCpuState = NULL;
711 	}
712 
713 	const uint8* buffer = NULL;
714 	ssize_t numBytes = 0;
715 	size_t stateSize = GetArchitecture()->DebugCpuStateSize();
716 	status_t error = data.FindData("state", B_RAW_TYPE, (const void**)&buffer,
717 		&numBytes);
718 	if (error != B_OK || (size_t)numBytes != stateSize)
719 		return B_BAD_VALUE;
720 
721 	return GetArchitecture()->CreateCpuState(buffer, stateSize, fCpuState);
722 }
723 
724 
725 status_t
726 RemoteDebugGetCpuStateResponse::SaveSpecificInfoToMessage(
727 	BMessage& _output) const
728 {
729 	size_t stateSize = GetArchitecture()->DebugCpuStateSize();
730 	uint8* buffer = new(std::nothrow) uint8[stateSize];
731 	if (buffer == NULL)
732 		return B_NO_MEMORY;
733 
734 	ArrayDeleter<uint8> deleter(buffer);
735 	status_t error = fCpuState->UpdateDebugState(buffer, stateSize);
736 	if (error != B_OK)
737 		return error;
738 
739 	return _output.AddData("state", B_RAW_TYPE, buffer, (ssize_t)stateSize);
740 }
741