diff options
| -rw-r--r-- | src/citra/citra.cpp | 3 | ||||
| -rw-r--r-- | src/citra_qt/main.cpp | 3 | ||||
| -rw-r--r-- | src/core/gdbstub/gdbstub.cpp | 95 |
3 files changed, 36 insertions, 65 deletions
diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp index bfbb21199..c96fc1374 100644 --- a/src/citra/citra.cpp +++ b/src/citra/citra.cpp | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "core/settings.h" | 23 | #include "core/settings.h" |
| 24 | #include "core/system.h" | 24 | #include "core/system.h" |
| 25 | #include "core/core.h" | 25 | #include "core/core.h" |
| 26 | #include "core/gdbstub/gdbstub.h" | ||
| 26 | #include "core/loader/loader.h" | 27 | #include "core/loader/loader.h" |
| 27 | 28 | ||
| 28 | #include "citra/config.h" | 29 | #include "citra/config.h" |
| @@ -30,8 +31,6 @@ | |||
| 30 | 31 | ||
| 31 | #include "video_core/video_core.h" | 32 | #include "video_core/video_core.h" |
| 32 | 33 | ||
| 33 | #include "core/gdbstub/gdbstub.h" | ||
| 34 | |||
| 35 | 34 | ||
| 36 | static void PrintHelp() | 35 | static void PrintHelp() |
| 37 | { | 36 | { |
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index d8d17f466..e5ed01a11 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp | |||
| @@ -44,12 +44,11 @@ | |||
| 44 | #include "core/settings.h" | 44 | #include "core/settings.h" |
| 45 | #include "core/system.h" | 45 | #include "core/system.h" |
| 46 | #include "core/arm/disassembler/load_symbol_map.h" | 46 | #include "core/arm/disassembler/load_symbol_map.h" |
| 47 | #include "core/gdbstub/gdbstub.h" | ||
| 47 | #include "core/loader/loader.h" | 48 | #include "core/loader/loader.h" |
| 48 | 49 | ||
| 49 | #include "video_core/video_core.h" | 50 | #include "video_core/video_core.h" |
| 50 | 51 | ||
| 51 | #include "core/gdbstub/gdbstub.h" | ||
| 52 | |||
| 53 | GMainWindow::GMainWindow() : emu_thread(nullptr) | 52 | GMainWindow::GMainWindow() : emu_thread(nullptr) |
| 54 | { | 53 | { |
| 55 | Pica::g_debug_context = Pica::DebugContext::Construct(); | 54 | Pica::g_debug_context = Pica::DebugContext::Construct(); |
diff --git a/src/core/gdbstub/gdbstub.cpp b/src/core/gdbstub/gdbstub.cpp index 6c21b5998..6f9c8fa29 100644 --- a/src/core/gdbstub/gdbstub.cpp +++ b/src/core/gdbstub/gdbstub.cpp | |||
| @@ -20,18 +20,18 @@ | |||
| 20 | #include <iphlpapi.h> | 20 | #include <iphlpapi.h> |
| 21 | #define SHUT_RDWR 2 | 21 | #define SHUT_RDWR 2 |
| 22 | #else | 22 | #else |
| 23 | #include <unistd.h> | ||
| 23 | #include <sys/select.h> | 24 | #include <sys/select.h> |
| 24 | #include <sys/socket.h> | 25 | #include <sys/socket.h> |
| 25 | #include <sys/un.h> | 26 | #include <sys/un.h> |
| 26 | #include <netinet/in.h> | 27 | #include <netinet/in.h> |
| 27 | #include <unistd.h> | ||
| 28 | #endif | 28 | #endif |
| 29 | 29 | ||
| 30 | #include "common/logging/log.h" | 30 | #include "common/logging/log.h" |
| 31 | #include "common/string_util.h" | 31 | #include "common/string_util.h" |
| 32 | #include <core/arm/arm_interface.h> | ||
| 33 | #include "core/core.h" | 32 | #include "core/core.h" |
| 34 | #include "core/memory.h" | 33 | #include "core/memory.h" |
| 34 | #include "core/arm/arm_interface.h" | ||
| 35 | #include "gdbstub.h" | 35 | #include "gdbstub.h" |
| 36 | 36 | ||
| 37 | const int GDB_BUFFER_SIZE = 10000; | 37 | const int GDB_BUFFER_SIZE = 10000; |
| @@ -67,8 +67,7 @@ static u8 command_buffer[GDB_BUFFER_SIZE]; | |||
| 67 | static u32 command_length; | 67 | static u32 command_length; |
| 68 | 68 | ||
| 69 | static u32 latest_signal = 0; | 69 | static u32 latest_signal = 0; |
| 70 | static u32 send_signal = 0; | 70 | static bool step_break = false; |
| 71 | static u32 step_break = 0; | ||
| 72 | static bool memory_break = false; | 71 | static bool memory_break = false; |
| 73 | 72 | ||
| 74 | // Binding to a port within the reserved ports range (0-1023) requires root permissions, | 73 | // Binding to a port within the reserved ports range (0-1023) requires root permissions, |
| @@ -356,33 +355,21 @@ static void HandleSetThread() { | |||
| 356 | SendReply("E01"); | 355 | SendReply("E01"); |
| 357 | } | 356 | } |
| 358 | 357 | ||
| 359 | /// Create and send signal packet. | ||
| 360 | static void HandleSignal() { | ||
| 361 | std::string buffer = Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15, htonl(Core::g_app_core->GetPC()), 13, htonl(Core::g_app_core->GetReg(13))); | ||
| 362 | |||
| 363 | LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str()); | ||
| 364 | |||
| 365 | SendReply(buffer.c_str()); | ||
| 366 | } | ||
| 367 | |||
| 368 | /** | 358 | /** |
| 369 | * Set signal and send packet to client through HandleSignal if signal flag is set using SendSignal. | 359 | * Send signal packet to client. |
| 370 | * | 360 | * |
| 371 | * @param signal Signal to be sent to client. | 361 | * @param signal Signal to be sent to client. |
| 372 | */ | 362 | */ |
| 373 | int SendSignal(u32 signal) { | 363 | void SendSignal(u32 signal) { |
| 374 | if (gdbserver_socket == -1) { | 364 | if (gdbserver_socket == -1) { |
| 375 | return 1; | 365 | return; |
| 376 | } | 366 | } |
| 377 | 367 | ||
| 378 | latest_signal = signal; | 368 | latest_signal = signal; |
| 379 | 369 | ||
| 380 | if (send_signal) { | 370 | std::string buffer = Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15, htonl(Core::g_app_core->GetPC()), 13, htonl(Core::g_app_core->GetReg(13))); |
| 381 | HandleSignal(); | 371 | LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str()); |
| 382 | send_signal = 0; | 372 | SendReply(buffer.c_str()); |
| 383 | } | ||
| 384 | |||
| 385 | return 0; | ||
| 386 | } | 373 | } |
| 387 | 374 | ||
| 388 | /// Read command from gdb client. | 375 | /// Read command from gdb client. |
| @@ -397,7 +384,6 @@ static void ReadCommand() { | |||
| 397 | } else if (c == 0x03) { | 384 | } else if (c == 0x03) { |
| 398 | LOG_INFO(Debug_GDBStub, "gdb: found break command\n"); | 385 | LOG_INFO(Debug_GDBStub, "gdb: found break command\n"); |
| 399 | halt_loop = true; | 386 | halt_loop = true; |
| 400 | send_signal = 1; | ||
| 401 | SendSignal(SIGTRAP); | 387 | SendSignal(SIGTRAP); |
| 402 | return; | 388 | return; |
| 403 | } else if (c != GDB_STUB_START) { | 389 | } else if (c != GDB_STUB_START) { |
| @@ -566,17 +552,14 @@ static void WriteRegisters() { | |||
| 566 | static void ReadMemory() { | 552 | static void ReadMemory() { |
| 567 | static u8 reply[GDB_BUFFER_SIZE - 4]; | 553 | static u8 reply[GDB_BUFFER_SIZE - 4]; |
| 568 | 554 | ||
| 569 | int i = 1; | 555 | auto start_offset = command_buffer+1; |
| 556 | auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); | ||
| 570 | PAddr addr = 0; | 557 | PAddr addr = 0; |
| 571 | while (command_buffer[i] != ',') { | 558 | HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); |
| 572 | addr = (addr << 4) | HexCharToValue(command_buffer[i++]); | ||
| 573 | } | ||
| 574 | i++; | ||
| 575 | 559 | ||
| 560 | start_offset = addr_pos+1; | ||
| 576 | u32 len = 0; | 561 | u32 len = 0; |
| 577 | while (i < command_length) { | 562 | HexToMem((u8*)&len, start_offset, ((command_buffer + command_length) - start_offset) / 2); |
| 578 | len = (len << 4) | HexCharToValue(command_buffer[i++]); | ||
| 579 | } | ||
| 580 | 563 | ||
| 581 | if (len * 2 > sizeof(reply)) { | 564 | if (len * 2 > sizeof(reply)) { |
| 582 | SendReply("E01"); | 565 | SendReply("E01"); |
| @@ -594,31 +577,28 @@ static void ReadMemory() { | |||
| 594 | 577 | ||
| 595 | /// Modify location in memory with data received from the gdb client. | 578 | /// Modify location in memory with data received from the gdb client. |
| 596 | static void WriteMemory() { | 579 | static void WriteMemory() { |
| 597 | int i = 1; | 580 | auto start_offset = command_buffer+1; |
| 581 | auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); | ||
| 598 | PAddr addr = 0; | 582 | PAddr addr = 0; |
| 599 | while (command_buffer[i] != ',') { | 583 | HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); |
| 600 | addr = (addr << 4) | HexCharToValue(command_buffer[i++]); | ||
| 601 | } | ||
| 602 | i++; | ||
| 603 | 584 | ||
| 585 | start_offset = addr_pos+1; | ||
| 586 | auto len_pos = std::find(start_offset, command_buffer+command_length, ':'); | ||
| 604 | u32 len = 0; | 587 | u32 len = 0; |
| 605 | while (command_buffer[i] != ':') { | 588 | HexToMem((u8*)&len, start_offset, (len_pos - start_offset) / 2); |
| 606 | len = (len << 4) | HexCharToValue(command_buffer[i++]); | ||
| 607 | } | ||
| 608 | 589 | ||
| 609 | u8* dst = Memory::GetPointer(addr); | 590 | u8* dst = Memory::GetPointer(addr); |
| 610 | if (!dst) { | 591 | if (!dst) { |
| 611 | return SendReply("E00"); | 592 | return SendReply("E00"); |
| 612 | } | 593 | } |
| 613 | 594 | ||
| 614 | HexToMem(dst, command_buffer + i + 1, len); | 595 | HexToMem(dst, len_pos + 1, len); |
| 615 | SendReply("OK"); | 596 | SendReply("OK"); |
| 616 | } | 597 | } |
| 617 | 598 | ||
| 618 | void Break(bool is_memory_break) { | 599 | void Break(bool is_memory_break) { |
| 619 | if (!halt_loop) { | 600 | if (!halt_loop) { |
| 620 | halt_loop = true; | 601 | halt_loop = true; |
| 621 | send_signal = 1; | ||
| 622 | SendSignal(SIGTRAP); | 602 | SendSignal(SIGTRAP); |
| 623 | } | 603 | } |
| 624 | 604 | ||
| @@ -629,8 +609,7 @@ void Break(bool is_memory_break) { | |||
| 629 | static void Step() { | 609 | static void Step() { |
| 630 | step_loop = true; | 610 | step_loop = true; |
| 631 | halt_loop = true; | 611 | halt_loop = true; |
| 632 | send_signal = 1; | 612 | step_break = true; |
| 633 | step_break = 1; | ||
| 634 | SendSignal(SIGTRAP); | 613 | SendSignal(SIGTRAP); |
| 635 | } | 614 | } |
| 636 | 615 | ||
| @@ -645,7 +624,7 @@ bool IsMemoryBreak() { | |||
| 645 | /// Tell the CPU to continue executing. | 624 | /// Tell the CPU to continue executing. |
| 646 | static void Continue() { | 625 | static void Continue() { |
| 647 | memory_break = false; | 626 | memory_break = false; |
| 648 | step_break = 0; | 627 | step_break = false; |
| 649 | step_loop = false; | 628 | step_loop = false; |
| 650 | halt_loop = false; | 629 | halt_loop = false; |
| 651 | } | 630 | } |
| @@ -694,17 +673,14 @@ static void AddBreakpoint() { | |||
| 694 | return SendReply("E01"); | 673 | return SendReply("E01"); |
| 695 | } | 674 | } |
| 696 | 675 | ||
| 697 | int i = 3; | 676 | auto start_offset = command_buffer+3; |
| 677 | auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); | ||
| 698 | PAddr addr = 0; | 678 | PAddr addr = 0; |
| 699 | while (command_buffer[i] != ',') { | 679 | HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); |
| 700 | addr = addr << 4 | HexCharToValue(command_buffer[i++]); | ||
| 701 | } | ||
| 702 | i++; | ||
| 703 | 680 | ||
| 681 | start_offset = addr_pos+1; | ||
| 704 | u32 len = 0; | 682 | u32 len = 0; |
| 705 | while (i < command_length) { | 683 | HexToMem((u8*)&len, start_offset, ((command_buffer + command_length) - start_offset) / 2); |
| 706 | len = len << 4 | HexCharToValue(command_buffer[i++]); | ||
| 707 | } | ||
| 708 | 684 | ||
| 709 | if (type == BreakpointType::Access) { | 685 | if (type == BreakpointType::Access) { |
| 710 | // Access is made up of Read and Write types, so add both breakpoints | 686 | // Access is made up of Read and Write types, so add both breakpoints |
| @@ -747,17 +723,14 @@ static void RemoveBreakpoint() { | |||
| 747 | return SendReply("E01"); | 723 | return SendReply("E01"); |
| 748 | } | 724 | } |
| 749 | 725 | ||
| 750 | int i = 3; | 726 | auto start_offset = command_buffer+3; |
| 727 | auto addr_pos = std::find(start_offset, command_buffer+command_length, ','); | ||
| 751 | PAddr addr = 0; | 728 | PAddr addr = 0; |
| 752 | while (command_buffer[i] != ',') { | 729 | HexToMem((u8*)&addr, start_offset, (addr_pos - start_offset) / 2); |
| 753 | addr = (addr << 4) | HexCharToValue(command_buffer[i++]); | ||
| 754 | } | ||
| 755 | i++; | ||
| 756 | 730 | ||
| 731 | start_offset = addr_pos+1; | ||
| 757 | u32 len = 0; | 732 | u32 len = 0; |
| 758 | while (i < command_length) { | 733 | HexToMem((u8*)&len, start_offset, ((command_buffer + command_length) - start_offset) / 2); |
| 759 | len = (len << 4) | HexCharToValue(command_buffer[i++]); | ||
| 760 | } | ||
| 761 | 734 | ||
| 762 | if (type == BreakpointType::Access) { | 735 | if (type == BreakpointType::Access) { |
| 763 | // Access is made up of Read and Write types, so add both breakpoints | 736 | // Access is made up of Read and Write types, so add both breakpoints |
| @@ -795,7 +768,7 @@ void HandlePacket() { | |||
| 795 | HandleSetThread(); | 768 | HandleSetThread(); |
| 796 | break; | 769 | break; |
| 797 | case '?': | 770 | case '?': |
| 798 | HandleSignal(); | 771 | SendSignal(latest_signal); |
| 799 | break; | 772 | break; |
| 800 | case 'k': | 773 | case 'k': |
| 801 | Shutdown(); | 774 | Shutdown(); |