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