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