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