Replaced in-house gdb stub by MIT-licensed implementation

Imported from a fork of https://github.com/mborgerson/gdbstub
This commit is contained in:
Xavier Del Campo Romero 2020-05-23 18:06:48 +02:00
parent 470da05658
commit 850010a96b
18 changed files with 215 additions and 158 deletions

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "dynstr/dynstr"]
path = dynstr/dynstr
url = https://github.com/XaviDCR92/dynstr
[submodule "gdbstub/gdbstub"]
path = gdbstub/gdbstub
url = https://github.com/XaviDCR92/gdbstub

View File

@ -52,3 +52,4 @@ add_subdirectory(gui)
add_subdirectory(plugins)
add_subdirectory(doc)
add_subdirectory(dynstr)
add_subdirectory(gdbstub)

5
gdbstub/CMakeLists.txt Normal file
View File

@ -0,0 +1,5 @@
message(STATUS "* Configuring gdbstub")
set(SRCS gdbstub/gdbstub.c gdbstub_sys.c)
include_directories(gdbstub .)
add_library(gdbstub STATIC ${SRCS})

1
gdbstub/gdbstub Submodule

@ -0,0 +1 @@
Subproject commit b00d0f815b3996a13ce87a4d9d6d7038353e77e6

132
gdbstub/gdbstub_sys.c Normal file
View File

@ -0,0 +1,132 @@
#include "gdbstub_sys.h"
#include "gdbstub.h"
#include "libpcsxcore/socket.h"
#include "libpcsxcore/r3000a.h"
#include <stdio.h>
static int server_socket, client_socket;
static void update_regs(struct dbg_state *const dbg_state)
{
dbg_state->registers[DBG_CPU_MIPS_I_REG_ZERO] = 0;
dbg_state->registers[DBG_CPU_MIPS_I_REG_AT] = psxRegs.GPR.n.at;
dbg_state->registers[DBG_CPU_MIPS_I_REG_V0] = psxRegs.GPR.n.v0;
dbg_state->registers[DBG_CPU_MIPS_I_REG_V1] = psxRegs.GPR.n.v1;
dbg_state->registers[DBG_CPU_MIPS_I_REG_A0] = psxRegs.GPR.n.a0;
dbg_state->registers[DBG_CPU_MIPS_I_REG_A1] = psxRegs.GPR.n.a1;
dbg_state->registers[DBG_CPU_MIPS_I_REG_A2] = psxRegs.GPR.n.a2;
dbg_state->registers[DBG_CPU_MIPS_I_REG_A3] = psxRegs.GPR.n.a3;
dbg_state->registers[DBG_CPU_MIPS_I_REG_T0] = psxRegs.GPR.n.t0;
dbg_state->registers[DBG_CPU_MIPS_I_REG_T1] = psxRegs.GPR.n.t1;
dbg_state->registers[DBG_CPU_MIPS_I_REG_T2] = psxRegs.GPR.n.t2;
dbg_state->registers[DBG_CPU_MIPS_I_REG_T3] = psxRegs.GPR.n.t3;
dbg_state->registers[DBG_CPU_MIPS_I_REG_T4] = psxRegs.GPR.n.t4;
dbg_state->registers[DBG_CPU_MIPS_I_REG_T5] = psxRegs.GPR.n.t5;
dbg_state->registers[DBG_CPU_MIPS_I_REG_T6] = psxRegs.GPR.n.t6;
dbg_state->registers[DBG_CPU_MIPS_I_REG_T7] = psxRegs.GPR.n.t7;
dbg_state->registers[DBG_CPU_MIPS_I_REG_S0] = psxRegs.GPR.n.s0;
dbg_state->registers[DBG_CPU_MIPS_I_REG_S1] = psxRegs.GPR.n.s1;
dbg_state->registers[DBG_CPU_MIPS_I_REG_S2] = psxRegs.GPR.n.s2;
dbg_state->registers[DBG_CPU_MIPS_I_REG_S3] = psxRegs.GPR.n.s3;
dbg_state->registers[DBG_CPU_MIPS_I_REG_S4] = psxRegs.GPR.n.s4;
dbg_state->registers[DBG_CPU_MIPS_I_REG_S5] = psxRegs.GPR.n.s5;
dbg_state->registers[DBG_CPU_MIPS_I_REG_S6] = psxRegs.GPR.n.s6;
dbg_state->registers[DBG_CPU_MIPS_I_REG_S7] = psxRegs.GPR.n.s7;
dbg_state->registers[DBG_CPU_MIPS_I_REG_T8] = psxRegs.GPR.n.t8;
dbg_state->registers[DBG_CPU_MIPS_I_REG_T9] = psxRegs.GPR.n.t9;
dbg_state->registers[DBG_CPU_MIPS_I_REG_K0] = psxRegs.GPR.n.k0;
dbg_state->registers[DBG_CPU_MIPS_I_REG_K1] = psxRegs.GPR.n.k1;
dbg_state->registers[DBG_CPU_MIPS_I_REG_GP] = psxRegs.GPR.n.gp;
dbg_state->registers[DBG_CPU_MIPS_I_REG_SP] = psxRegs.GPR.n.sp;
dbg_state->registers[DBG_CPU_MIPS_I_REG_S8] = psxRegs.GPR.n.s8;
dbg_state->registers[DBG_CPU_MIPS_I_REG_RA] = psxRegs.GPR.n.ra;
dbg_state->registers[DBG_CPU_MIPS_I_REG_SR] = psxRegs.CP0.n.Status;
dbg_state->registers[DBG_CPU_MIPS_I_REG_LO] = psxRegs.GPR.r[32];
dbg_state->registers[DBG_CPU_MIPS_I_REG_HI] = psxRegs.GPR.r[33];
dbg_state->registers[DBG_CPU_MIPS_I_REG_BAD] = psxRegs.CP0.n.BadVAddr;
dbg_state->registers[DBG_CPU_MIPS_I_REG_CAUSE] = psxRegs.CP0.n.Cause;
dbg_state->registers[DBG_CPU_MIPS_I_REG_PC] = psxRegs.pc;
}
void dbg_sys_process(void)
{
static struct dbg_state dbg_state;
update_regs(&dbg_state);
dbg_main(&dbg_state);
}
int dbg_sys_getc(void)
{
while (1) {
char packet;
size_t len = sizeof packet;
const enum read_socket_err err = ReadSocket(client_socket, &packet, &len);
switch (err) {
case READ_SOCKET_OK:
return packet;
case READ_SOCKET_SHUTDOWN:
client_socket = 0;
return EOF;
case READ_SOCKET_ERR_INVALID_ARG:
/* Fall through. */
case READ_SOCKET_ERR_RECV:
/* Fall through. */
default:
break;
}
}
}
int dbg_sys_putchar(int ch)
{
WriteSocket(client_socket, (const char *)&ch, sizeof (char));
}
int dbg_sys_mem_readb(address addr, char *val)
{
*val = psxMemRead8(addr);
return 0;
}
int dbg_sys_mem_writeb(address addr, char val)
{
psxMemWrite8(addr, val);
return 0;
}
int dbg_sys_continue(void)
{
return 0;
}
int dbg_sys_step(void)
{
return 0;
}
void dbg_start(void)
{
const unsigned short port = 3333;
if (server_socket > 0)
StopServer(server_socket);
server_socket = StartServer(port);
if (server_socket > 0)
printf("GDB server started on port %hu.\n", port);
else
fprintf(stderr, "Could not start GDB server\n");
}

58
gdbstub/gdbstub_sys.h Normal file
View File

@ -0,0 +1,58 @@
#ifndef GDBSTUB_SYS_H
#define GDBSTUB_SYS_H
typedef unsigned int address;
enum DBG_REGISTER {
DBG_CPU_MIPS_I_REG_ZERO,
DBG_CPU_MIPS_I_REG_AT,
DBG_CPU_MIPS_I_REG_V0,
DBG_CPU_MIPS_I_REG_V1,
DBG_CPU_MIPS_I_REG_A0,
DBG_CPU_MIPS_I_REG_A1,
DBG_CPU_MIPS_I_REG_A2,
DBG_CPU_MIPS_I_REG_A3,
DBG_CPU_MIPS_I_REG_T0,
DBG_CPU_MIPS_I_REG_T1,
DBG_CPU_MIPS_I_REG_T2,
DBG_CPU_MIPS_I_REG_T3,
DBG_CPU_MIPS_I_REG_T4,
DBG_CPU_MIPS_I_REG_T5,
DBG_CPU_MIPS_I_REG_T6,
DBG_CPU_MIPS_I_REG_T7,
DBG_CPU_MIPS_I_REG_S0,
DBG_CPU_MIPS_I_REG_S1,
DBG_CPU_MIPS_I_REG_S2,
DBG_CPU_MIPS_I_REG_S3,
DBG_CPU_MIPS_I_REG_S4,
DBG_CPU_MIPS_I_REG_S5,
DBG_CPU_MIPS_I_REG_S6,
DBG_CPU_MIPS_I_REG_S7,
DBG_CPU_MIPS_I_REG_T8,
DBG_CPU_MIPS_I_REG_T9,
DBG_CPU_MIPS_I_REG_K0,
DBG_CPU_MIPS_I_REG_K1,
DBG_CPU_MIPS_I_REG_GP,
DBG_CPU_MIPS_I_REG_SP,
DBG_CPU_MIPS_I_REG_S8,
DBG_CPU_MIPS_I_REG_RA,
DBG_CPU_MIPS_I_REG_SR,
DBG_CPU_MIPS_I_REG_LO,
DBG_CPU_MIPS_I_REG_HI,
DBG_CPU_MIPS_I_REG_BAD,
DBG_CPU_MIPS_I_REG_CAUSE,
DBG_CPU_MIPS_I_REG_PC,
DBG_CPU_NUM_REGISTERS
};
typedef unsigned int reg;
struct dbg_state {
int signum;
reg registers[DBG_CPU_NUM_REGISTERS];
};
void dbg_start(void);
void dbg_sys_process(void);
#endif /* GDBSTUB_SYS_H */

View File

@ -32,6 +32,7 @@
#include "ConfDlg.h"
#include "../libpcsxcore/plugins.h"
#include "../gdbstub/gdbstub_sys.h"
static void OnBiosPath_Changed(GtkWidget *wdg, gpointer data);
static void OnConf_Clicked(GtkDialog *dialog, gint arg1, gpointer user_data);
@ -929,9 +930,8 @@ void OnCpu_Clicked(GtkDialog *dialog, gint arg1, gpointer user_data) {
else StopDebugger();
}
if (Config.GdbServer) {
GdbStartServer();
}
if (Config.GdbServer)
dbg_start();
t = Config.Cpu;
Config.Cpu = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gtk_builder_get_object(builder, "GtkCheckButton_Cpu")));

View File

@ -32,6 +32,7 @@
#include <dirent.h>
#include <sys/stat.h>
#include "../libpcsxcore/sio.h"
#include "../gdbstub/gdbstub_sys.h"
#include "Linux.h"
#include "ConfDlg.h"
@ -490,13 +491,10 @@ int SysInit() {
LoadMcds(Config.Mcd1, Config.Mcd2); /* TODO Do we need to have this here, or in the calling main() function?? */
if (Config.Debug) {
if (Config.Debug)
StartDebugger();
}
if (Config.GdbServer) {
GdbStartServer();
}
else if (Config.GdbServer)
dbg_start();
return 0;
}

View File

@ -98,7 +98,6 @@ set(SRCS psxbios.c
pgxp_gte.c
pgxp_mem.c
pgxp_value.c
gdb_server.c
)
set(LIBS "-lm")
@ -117,4 +116,4 @@ endif()
set(SRCS ${SRCS} ${DYNAREC_SRC})
add_library(pcsxcore STATIC ${SRCS})
target_link_libraries(pcsxcore dynstr ${FFMPEG_LIBRARIES} ${LibArchive_LIBRARIES} ${LIBS})
target_link_libraries(pcsxcore dynstr gdbstub ${FFMPEG_LIBRARIES} ${LibArchive_LIBRARIES} ${LIBS})

View File

@ -474,7 +474,7 @@ void ProcessDebug() {
MarkMap(_Rd_, MAP_EXEC_JAL);
}
}
while (paused || GdbServerRunning()) {
while (paused) {
if (client_socket < 1)
{

View File

@ -1,128 +0,0 @@
#include "socket.h"
#include "psxcommon.h"
#include "misc.h"
#include "system.h"
#include "dynstr.h"
#include <stdio.h>
#include <string.h>
#include <stddef.h>
static int server_socket, client_socket;
static int debugger_active, resetting, reset, paused, ack_expected;
enum { PACKET_SIZE = 256 };
void GdbStartServer(void)
{
enum { PORT = 3333 };
if (server_socket > 0) {
GdbStopServer();
}
server_socket = StartServer(PORT);
if (server_socket > 0) {
printf("GDB server started on port %hu\n", PORT);
debugger_active = 1;
}
else
{
fprintf(stderr, "Could not start GDB server\n");
}
}
int GdbServerRunning(void)
{
return server_socket > 0;
}
void GdbStopServer(void)
{
}
static void ack(struct dynstr *const reply)
{
dynstr_append(reply, "OK");
}
static void nack(struct dynstr *const reply, const int err)
{
dynstr_append(reply, "E %02X", err);
}
static void HandlePacket(char *const packet, const size_t len)
{
struct dynstr reply;
const char *c = packet;
dynstr_init(&reply);
if (strstr(packet, "qSupported")) {
dynstr_append(&reply, "PacketSize=%x;swbreak+;hwbreak+", PACKET_SIZE - 1);
}
else {
fprintf(stderr, "Unexpected packet \"%s\"\n", packet);
return;
}
printf("gdb <- \"%s\"\n", reply.str);
WriteSocket(client_socket, reply.str, reply.len);
dynstr_free(&reply);
}
static void ProcessCommands(void)
{
if (HasClient(client_socket)) {
char packet[PACKET_SIZE];
size_t len = sizeof packet;
const enum read_socket_err err = ReadSocket(client_socket, packet, &len);
switch (err)
{
case READ_SOCKET_OK:
if (len && len < sizeof packet) {
/* gdb apparently does not send null-terminated strings. */
packet[len] = '\0';
printf("gdb -> \"%s\"\n", packet);
HandlePacket(packet, len);
}
break;
case READ_SOCKET_ERR_INVALID_ARG:
/* Fall through. */
case READ_SOCKET_ERR_RECV:
/* Fall through. */
case READ_SOCKET_SHUTDOWN:
/* Fall through. */
default:
return;
}
}
}
void GdbServerProcessDebug(void)
{
ProcessCommands();
}
void GdbServerVSync(void)
{
if (!debugger_active || resetting)
return;
if (reset) {
resetting = 1;
SysReset();
if (reset == 2)
LoadCdrom();
reset = resetting = 0;
return;
}
if (client_socket < 1) {
client_socket = GetClient(server_socket);
}
ProcessCommands();
}

View File

@ -1,10 +0,0 @@
#ifndef GDB_SERVER_H
#define GDB_SERVER_H
void GdbStartServer(void);
void GdbStopServer(void);
void GdbServerProcessDebug(void);
void GdbServerVSync(void);
int GdbServerRunning(void);
#endif /* GDB_SERVER_H */

View File

@ -70,7 +70,6 @@ typedef uint8_t boolean;
// Local includes
#include "system.h"
#include "debug.h"
#include "gdb_server.h"
#if defined (__linux__) || defined (__MACOSX__)
#define strnicmp strncasecmp

View File

@ -323,8 +323,7 @@ void psxRcntUpdate()
}
}
DebugVSync();
GdbServerVSync();
if (Config.Debug) DebugVSync();
}
/******************************************************************************/

View File

@ -28,6 +28,7 @@
#include "pgxp_debug.h"
#include "pgxp_cpu.h"
#include "pgxp_gte.h"
#include "../gdbstub/gdbstub_sys.h"
static int branch = 0;
static int branch2 = 0;
@ -1204,7 +1205,7 @@ static inline void execI() {
debugI();
if (Config.GdbServer) GdbServerProcessDebug();
if (Config.GdbServer) dbg_sys_process();
else if (Config.Debug) ProcessDebug();
psxRegs.pc += 4;

View File

@ -252,8 +252,8 @@ int RawReadSocket(int client_socket, char *buffer, size_t len) {
#endif
}
void WriteSocket(int client_socket, const char *buffer, size_t len) {
if (!client_socket)
void WriteSocket(int client_socket, const void *buffer, size_t len) {
if (client_socket <= 0)
return;
if (send(client_socket, buffer, len, 0) == -1) {

View File

@ -42,7 +42,7 @@ int HasClient(int client_socket);
enum read_socket_err ReadSocket(int client_socket, char *buffer, size_t *len);
int RawReadSocket(int client_socket, char *buffer, size_t len);
void WriteSocket(int client_socket, const char *buffer, size_t len);
void WriteSocket(int client_socket, const void *buffer, size_t len);
void SetsBlock(int s_socket);
void SetsNonblock(int s_socket);

View File

@ -34,7 +34,6 @@
#include "sio.h"
#include "misc.h"
#include "cheat.h"
#include "gdb_server.h"
#ifdef __MINGW32__
#ifndef LVM_GETSELECTIONMARK