mirror of
https://git.planet-casio.com/Lephenixnoir/gint.git
synced 2024-12-28 04:23:36 +01:00
gdb: support 'C' packet for resuming with signals
It's not super useful as a feature but it means that a naive "continue" after e.g. a segfault will kill the program and not confusingly go into an infinite loop.
This commit is contained in:
parent
2755596d59
commit
b4c0fc7cea
1 changed files with 39 additions and 4 deletions
|
@ -220,10 +220,14 @@ static void gdb_handle_qXfer_packet(const char* packet, const char* data, size_t
|
||||||
static const char gdb_memory_map_xml[] = "<?xml version=\"1.0\"?>"
|
static const char gdb_memory_map_xml[] = "<?xml version=\"1.0\"?>"
|
||||||
"<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"
|
"<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"
|
||||||
"<memory-map>"
|
"<memory-map>"
|
||||||
"<memory type=\"rom\" start=\"0x00300000\" length=\"0x00200000\"/>" // add-in rom
|
// P0 mapping of add-in file
|
||||||
"<memory type=\"ram\" start=\"0x08100000\" length=\"0x00080000\"/>" // add-in ram
|
"<memory type=\"rom\" start=\"0x00300000\" length=\"0x00200000\"/>"
|
||||||
"<memory type=\"ram\" start=\"0x8c000000\" length=\"0x01000000\"/>" // fx-CG50 stack
|
// P0 mapping of user RAM area
|
||||||
"<memory type=\"ram\" start=\"0x88000000\" length=\"0x01000000\"/>" // Prizm stack
|
"<memory type=\"ram\" start=\"0x08100000\" length=\"0x00080000\"/>"
|
||||||
|
// Physical mapping of RAM chip (fx-CG 50)
|
||||||
|
"<memory type=\"ram\" start=\"0x8c000000\" length=\"0x01000000\"/>"
|
||||||
|
// Physical mapping of RAM chip (fx-CG 10/20 + emulator)
|
||||||
|
"<memory type=\"ram\" start=\"0x88000000\" length=\"0x01000000\"/>"
|
||||||
"</memory-map>";
|
"</memory-map>";
|
||||||
|
|
||||||
static void gdb_handle_query_packet(const char* packet)
|
static void gdb_handle_query_packet(const char* packet)
|
||||||
|
@ -479,6 +483,33 @@ static void gdb_handle_remove_hardware_breakpoint(const char* packet)
|
||||||
gdb_send_packet("OK", 2);
|
gdb_send_packet("OK", 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void gdb_handle_continue_with_signal(gdb_cpu_state_t* cpu_state,
|
||||||
|
const char* packet)
|
||||||
|
{
|
||||||
|
packet++; // consume 'C'
|
||||||
|
int signal = gdb_unhexlify_sized(packet, 2);
|
||||||
|
char exit[4] = { 'X', packet[0], packet[1], 0 };
|
||||||
|
packet += 2;
|
||||||
|
|
||||||
|
if(*packet == ';')
|
||||||
|
cpu_state->reg.pc = gdb_unhexlify(packet + 1);
|
||||||
|
|
||||||
|
// TODO: This is a heuristic replacing the normal signal system
|
||||||
|
uint32_t kills =
|
||||||
|
(1 << 4) /* SIGILL */
|
||||||
|
+ (1 << 6) /* SIGABRT */
|
||||||
|
+ (1 << 7) /* SIGEMT */
|
||||||
|
+ (1 << 8) /* SIGFPE */
|
||||||
|
+ (1 << 9) /* SIGKILL */
|
||||||
|
+ (1 << 11) /* SIGSEGV */
|
||||||
|
+ (1 << 15); /* SIGTERM */
|
||||||
|
// Abort if the signal is kill by default
|
||||||
|
if((uint)signal < 32 && (kills >> signal) & 1) {
|
||||||
|
gdb_send_packet(exit, 3);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
bool single_stepped;
|
bool single_stepped;
|
||||||
bool channel0_used;
|
bool channel0_used;
|
||||||
|
@ -579,6 +610,10 @@ void gdb_main(gdb_cpu_state_t* cpu_state)
|
||||||
goto ret;
|
goto ret;
|
||||||
case 'c': // Continue
|
case 'c': // Continue
|
||||||
goto ret;
|
goto ret;
|
||||||
|
case 'C': // Continue with signal
|
||||||
|
gdb_handle_continue_with_signal(cpu_state, packet_buffer);
|
||||||
|
// We'll often abort() at the signal rather than continuing
|
||||||
|
goto ret;
|
||||||
|
|
||||||
default: // Unsupported packet
|
default: // Unsupported packet
|
||||||
gdb_send_packet(NULL, 0);
|
gdb_send_packet(NULL, 0);
|
||||||
|
|
Loading…
Reference in a new issue