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