summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/citra/citra.cpp3
-rw-r--r--src/citra_qt/main.cpp3
-rw-r--r--src/core/gdbstub/gdbstub.cpp95
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
36static void PrintHelp() 35static 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
53GMainWindow::GMainWindow() : emu_thread(nullptr) 52GMainWindow::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
37const int GDB_BUFFER_SIZE = 10000; 37const int GDB_BUFFER_SIZE = 10000;
@@ -67,8 +67,7 @@ static u8 command_buffer[GDB_BUFFER_SIZE];
67static u32 command_length; 67static u32 command_length;
68 68
69static u32 latest_signal = 0; 69static u32 latest_signal = 0;
70static u32 send_signal = 0; 70static bool step_break = false;
71static u32 step_break = 0;
72static bool memory_break = false; 71static 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.
360static 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 */
373int SendSignal(u32 signal) { 363void 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() {
566static void ReadMemory() { 552static 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.
596static void WriteMemory() { 579static 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
618void Break(bool is_memory_break) { 599void 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) {
629static void Step() { 609static 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.
646static void Continue() { 625static 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();