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
24RemoteDebugRequest::RemoteDebugRequest()
25	:
26	BReferenceable(),
27	fArchitecture(NULL)
28{
29}
30
31
32RemoteDebugRequest::~RemoteDebugRequest()
33{
34	if (fArchitecture != NULL)
35		fArchitecture->ReleaseReference();
36}
37
38
39status_t
40RemoteDebugRequest::LoadFromMessage(const BMessage& data)
41{
42	if (data.FindInt32("type") != Type())
43		return B_BAD_VALUE;
44
45	return LoadSpecificInfoFromMessage(data);
46}
47
48
49status_t
50RemoteDebugRequest::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
62void
63RemoteDebugRequest::SetArchitecture(Architecture* architecture)
64{
65	fArchitecture = architecture;
66	fArchitecture->AcquireReference();
67}
68
69
70// #pragma mark - RemoteDebugResponse
71
72
73RemoteDebugResponse::RemoteDebugResponse()
74	:
75	BReferenceable(),
76	fRequest(NULL),
77	fResult(B_OK)
78{
79}
80
81
82RemoteDebugResponse::~RemoteDebugResponse()
83{
84	if (fRequest != NULL)
85		fRequest->ReleaseReference();
86}
87
88
89void
90RemoteDebugResponse::SetRequestInfo(RemoteDebugRequest* request,
91	status_t result)
92{
93	fRequest = request;
94	fRequest->AcquireReference();
95	fResult = result;
96}
97
98
99status_t
100RemoteDebugResponse::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
112status_t
113RemoteDebugResponse::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
132status_t
133RemoteDebugResponse::LoadSpecificInfoFromMessage(const BMessage& data)
134{
135	return B_OK;
136}
137
138
139status_t
140RemoteDebugResponse::SaveSpecificInfoToMessage(BMessage& _output) const
141{
142	return B_OK;
143}
144
145
146// #pragma mark - RemoteDebugReadMemoryRequest
147
148
149RemoteDebugReadMemoryRequest::RemoteDebugReadMemoryRequest()
150	:
151	RemoteDebugRequest(),
152	fAddress(0),
153	fSize(0)
154{
155}
156
157
158RemoteDebugReadMemoryRequest::~RemoteDebugReadMemoryRequest()
159{
160}
161
162
163void
164RemoteDebugReadMemoryRequest::SetTo(target_addr_t address, target_size_t size)
165{
166	fAddress = address;
167	fSize = size;
168}
169
170
171remote_request_type
172RemoteDebugReadMemoryRequest::Type() const
173{
174	return REMOTE_REQUEST_TYPE_READ_MEMORY;
175}
176
177
178status_t
179RemoteDebugReadMemoryRequest::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
191status_t
192RemoteDebugReadMemoryRequest::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
206RemoteDebugWriteMemoryRequest::RemoteDebugWriteMemoryRequest()
207	:
208	RemoteDebugRequest(),
209	fAddress(0),
210	fData(NULL),
211	fSize(0)
212{
213}
214
215
216RemoteDebugWriteMemoryRequest::~RemoteDebugWriteMemoryRequest()
217{
218	if (fData != NULL)
219		free(fData);
220}
221
222
223status_t
224RemoteDebugWriteMemoryRequest::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
242remote_request_type
243RemoteDebugWriteMemoryRequest::Type() const
244{
245	return REMOTE_REQUEST_TYPE_WRITE_MEMORY;
246}
247
248
249status_t
250RemoteDebugWriteMemoryRequest::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
279status_t
280RemoteDebugWriteMemoryRequest::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
298RemoteDebugSetTeamFlagsRequest::RemoteDebugSetTeamFlagsRequest()
299	:
300	RemoteDebugRequest(),
301	fFlags(0)
302{
303}
304
305
306RemoteDebugSetTeamFlagsRequest::~RemoteDebugSetTeamFlagsRequest()
307{
308}
309
310
311void
312RemoteDebugSetTeamFlagsRequest::SetTo(int32 flags)
313{
314	fFlags = flags;
315}
316
317
318remote_request_type
319RemoteDebugSetTeamFlagsRequest::Type() const
320{
321	return REMOTE_REQUEST_TYPE_SET_TEAM_FLAGS;
322}
323
324
325status_t
326RemoteDebugSetTeamFlagsRequest::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
336status_t
337RemoteDebugSetTeamFlagsRequest::SaveSpecificInfoToMessage(
338	BMessage& _output) const
339{
340	return _output.AddInt32("flags", fFlags);
341}
342
343
344// #pragma mark - RemoteDebugSetThreadFlagsRequest
345
346
347RemoteDebugSetThreadFlagsRequest::RemoteDebugSetThreadFlagsRequest()
348	:
349	RemoteDebugRequest(),
350	fThread(-1),
351	fFlags(0)
352{
353}
354
355
356RemoteDebugSetThreadFlagsRequest::~RemoteDebugSetThreadFlagsRequest()
357{
358}
359
360
361void
362RemoteDebugSetThreadFlagsRequest::SetTo(thread_id thread, int32 flags)
363{
364	fThread = thread;
365	fFlags = flags;
366}
367
368
369remote_request_type
370RemoteDebugSetThreadFlagsRequest::Type() const
371{
372	return REMOTE_REQUEST_TYPE_SET_THREAD_FLAGS;
373}
374
375
376status_t
377RemoteDebugSetThreadFlagsRequest::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
390status_t
391RemoteDebugSetThreadFlagsRequest::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
405RemoteDebugThreadActionRequest::RemoteDebugThreadActionRequest()
406	:
407	RemoteDebugRequest(),
408	fThread(-1)
409{
410}
411
412
413RemoteDebugThreadActionRequest::~RemoteDebugThreadActionRequest()
414{
415}
416
417
418void
419RemoteDebugThreadActionRequest::SetTo(thread_id thread)
420{
421	fThread = thread;
422}
423
424
425status_t
426RemoteDebugThreadActionRequest::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
436status_t
437RemoteDebugThreadActionRequest::SaveSpecificInfoToMessage(
438	BMessage& _output) const
439{
440	return _output.AddInt32("thread", fThread);
441}
442
443
444// #pragma mark - RemoteDebugContinueThreadRequest
445
446
447RemoteDebugContinueThreadRequest::RemoteDebugContinueThreadRequest()
448	:
449	RemoteDebugThreadActionRequest()
450{
451}
452
453
454RemoteDebugContinueThreadRequest::~RemoteDebugContinueThreadRequest()
455{
456}
457
458remote_request_type
459RemoteDebugContinueThreadRequest::Type() const
460{
461	return REMOTE_REQUEST_TYPE_CONTINUE_THREAD;
462}
463
464
465// #pragma mark - RemoteDebugStopThreadRequest
466
467
468RemoteDebugStopThreadRequest::RemoteDebugStopThreadRequest()
469	:
470	RemoteDebugThreadActionRequest()
471{
472}
473
474
475RemoteDebugStopThreadRequest::~RemoteDebugStopThreadRequest()
476{
477}
478
479remote_request_type
480RemoteDebugStopThreadRequest::Type() const
481{
482	return REMOTE_REQUEST_TYPE_STOP_THREAD;
483}
484
485
486// #pragma mark - RemoteDebugSingleStepThreadRequest
487
488
489RemoteDebugSingleStepThreadRequest::RemoteDebugSingleStepThreadRequest()
490	:
491	RemoteDebugThreadActionRequest()
492{
493}
494
495
496RemoteDebugSingleStepThreadRequest::~RemoteDebugSingleStepThreadRequest()
497{
498}
499
500remote_request_type
501RemoteDebugSingleStepThreadRequest::Type() const
502{
503	return REMOTE_REQUEST_TYPE_SINGLE_STEP_THREAD;
504}
505
506
507// #pragma mark - RemoteDebugGetCpuStateRequest
508
509
510RemoteDebugGetCpuStateRequest::RemoteDebugGetCpuStateRequest()
511	:
512	RemoteDebugThreadActionRequest()
513{
514}
515
516
517RemoteDebugGetCpuStateRequest::~RemoteDebugGetCpuStateRequest()
518{
519}
520
521
522remote_request_type
523RemoteDebugGetCpuStateRequest::Type() const
524{
525	return REMOTE_REQUEST_TYPE_GET_CPU_STATE;
526}
527
528
529// #pragma mark - RemoteDebugSetCpuStateRequest
530
531
532RemoteDebugSetCpuStateRequest::RemoteDebugSetCpuStateRequest()
533	:
534	RemoteDebugRequest(),
535	fThread(-1),
536	fCpuState(NULL)
537{
538}
539
540
541RemoteDebugSetCpuStateRequest::~RemoteDebugSetCpuStateRequest()
542{
543	if (fCpuState != NULL)
544		fCpuState->ReleaseReference();
545}
546
547
548void
549RemoteDebugSetCpuStateRequest::SetTo(thread_id thread, CpuState* state)
550{
551	fThread = thread;
552	fCpuState = state;
553	if (fCpuState != NULL)
554		fCpuState->AcquireReference();
555}
556
557
558remote_request_type
559RemoteDebugSetCpuStateRequest::Type() const
560{
561	return REMOTE_REQUEST_TYPE_SET_CPU_STATE;
562}
563
564
565status_t
566RemoteDebugSetCpuStateRequest::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
589status_t
590RemoteDebugSetCpuStateRequest::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
614RemoteDebugAddressActionRequest::RemoteDebugAddressActionRequest()
615	:
616	RemoteDebugRequest(),
617	fAddress(0)
618{
619}
620
621
622RemoteDebugAddressActionRequest::~RemoteDebugAddressActionRequest()
623{
624}
625
626
627void
628RemoteDebugAddressActionRequest::SetTo(target_addr_t address)
629{
630	fAddress = address;
631}
632
633
634status_t
635RemoteDebugAddressActionRequest::LoadSpecificInfoFromMessage(
636	const BMessage& data)
637{
638	return data.FindUInt64("address", &fAddress);
639}
640
641
642status_t
643RemoteDebugAddressActionRequest::SaveSpecificInfoToMessage(
644	BMessage& _output) const
645{
646	return _output.AddUInt64("address", fAddress);
647}
648
649
650// #pragma mark - RemoteDebugInstallBreakpointRequest
651
652
653RemoteDebugInstallBreakpointRequest::RemoteDebugInstallBreakpointRequest()
654	:
655	RemoteDebugAddressActionRequest()
656{
657}
658
659
660RemoteDebugInstallBreakpointRequest::~RemoteDebugInstallBreakpointRequest()
661{
662}
663
664
665remote_request_type
666RemoteDebugInstallBreakpointRequest::Type() const
667{
668	return REMOTE_REQUEST_TYPE_INSTALL_BREAKPOINT;
669}
670
671
672// #pragma mark - RemoteDebugUninstallBreakpointRequest
673
674
675RemoteDebugUninstallBreakpointRequest::RemoteDebugUninstallBreakpointRequest()
676	:
677	RemoteDebugAddressActionRequest()
678{
679}
680
681
682RemoteDebugUninstallBreakpointRequest::~RemoteDebugUninstallBreakpointRequest()
683{
684}
685
686remote_request_type
687RemoteDebugUninstallBreakpointRequest::Type() const
688{
689	return REMOTE_REQUEST_TYPE_UNINSTALL_BREAKPOINT;
690}
691
692
693// #pragma mark - RemoteDebugInstallWatchpointRequest
694
695
696RemoteDebugInstallWatchpointRequest::RemoteDebugInstallWatchpointRequest()
697	:
698	RemoteDebugRequest(),
699	fAddress(0),
700	fWatchType(B_DATA_READ_WATCHPOINT),
701	fLength(0)
702{
703}
704
705
706RemoteDebugInstallWatchpointRequest::~RemoteDebugInstallWatchpointRequest()
707{
708}
709
710
711void
712RemoteDebugInstallWatchpointRequest::SetTo(target_addr_t address, uint32 type,
713	int32 length)
714{
715	fAddress = address;
716	fWatchType = type;
717	fLength = length;
718}
719
720
721remote_request_type
722RemoteDebugInstallWatchpointRequest::Type() const
723{
724	return REMOTE_REQUEST_TYPE_INSTALL_WATCHPOINT;
725}
726
727
728status_t
729RemoteDebugInstallWatchpointRequest::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
744status_t
745RemoteDebugInstallWatchpointRequest::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
763RemoteDebugUninstallWatchpointRequest::RemoteDebugUninstallWatchpointRequest()
764	:
765	RemoteDebugAddressActionRequest()
766{
767}
768
769
770RemoteDebugUninstallWatchpointRequest::~RemoteDebugUninstallWatchpointRequest()
771{
772}
773
774
775remote_request_type
776RemoteDebugUninstallWatchpointRequest::Type() const
777{
778	return REMOTE_REQUEST_TYPE_UNINSTALL_WATCHPOINT;
779}
780
781
782// #pragma mark - RemoteDebugReadMemoryResponse
783
784
785RemoteDebugReadMemoryResponse::RemoteDebugReadMemoryResponse()
786	:
787	RemoteDebugResponse(),
788	fData(NULL),
789	fSize(0)
790{
791}
792
793
794RemoteDebugReadMemoryResponse::~RemoteDebugReadMemoryResponse()
795{
796	if (fData != NULL)
797		free(fData);
798}
799
800
801void
802RemoteDebugReadMemoryResponse::SetTo(void* data, target_size_t size)
803{
804	fData = data;
805	fSize = size;
806}
807
808
809status_t
810RemoteDebugReadMemoryResponse::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
835status_t
836RemoteDebugReadMemoryResponse::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
853RemoteDebugGetCpuStateResponse::RemoteDebugGetCpuStateResponse()
854	:
855	RemoteDebugResponse(),
856	fCpuState(NULL)
857{
858}
859
860
861RemoteDebugGetCpuStateResponse::~RemoteDebugGetCpuStateResponse()
862{
863	if (fCpuState != NULL)
864		fCpuState->ReleaseReference();
865}
866
867
868void
869RemoteDebugGetCpuStateResponse::SetTo(CpuState* state)
870{
871	fCpuState = state;
872	if (fCpuState != NULL)
873		fCpuState->AcquireReference();
874}
875
876
877status_t
878RemoteDebugGetCpuStateResponse::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
898status_t
899RemoteDebugGetCpuStateResponse::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