gdbstub: split out softmmu/user specifics for syscall handling
Most of the syscall code is config agnostic aside from the size of target_ulong. In preparation for the next patch move the final bits of specialisation into the appropriate user and softmmu helpers. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230302190846.2593720-26-alex.bennee@linaro.org> Message-Id: <20230303025805.625589-26-richard.henderson@linaro.org>
This commit is contained in:
parent
4692a86f1c
commit
131f387d74
@ -195,6 +195,9 @@ bool gdb_handled_syscall(void);
|
||||
void gdb_disable_syscalls(void);
|
||||
void gdb_syscall_reset(void);
|
||||
|
||||
/* user/softmmu specific syscall handling */
|
||||
void gdb_syscall_handling(const char *syscall_packet);
|
||||
|
||||
/*
|
||||
* Break/Watch point support - there is an implementation for softmmu
|
||||
* and user mode.
|
||||
|
@ -103,6 +103,20 @@ static void gdb_chr_event(void *opaque, QEMUChrEvent event)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* In softmmu mode we stop the VM and wait to send the syscall packet
|
||||
* until notification that the CPU has stopped. This must be done
|
||||
* because if the packet is sent now the reply from the syscall
|
||||
* request could be received while the CPU is still in the running
|
||||
* state, which can cause packets to be dropped and state transition
|
||||
* 'T' packets to be sent while the syscall is still being processed.
|
||||
*/
|
||||
void gdb_syscall_handling(const char *syscall_packet)
|
||||
{
|
||||
vm_stop(RUN_STATE_DEBUG);
|
||||
qemu_cpu_kick(gdbserver_state.c_cpu);
|
||||
}
|
||||
|
||||
static void gdb_vm_state_change(void *opaque, bool running, RunState state)
|
||||
{
|
||||
CPUState *cpu = gdbserver_state.c_cpu;
|
||||
|
@ -105,9 +105,7 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
|
||||
}
|
||||
|
||||
gdbserver_syscall_state.current_syscall_cb = cb;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
vm_stop(RUN_STATE_DEBUG);
|
||||
#endif
|
||||
|
||||
p = &gdbserver_syscall_state.syscall_buf[0];
|
||||
p_end = &gdbserver_syscall_state.syscall_buf[sizeof(gdbserver_syscall_state.syscall_buf)];
|
||||
*(p++) = 'F';
|
||||
@ -142,27 +140,8 @@ void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va)
|
||||
}
|
||||
}
|
||||
*p = 0;
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
gdb_put_packet(gdbserver_syscall_state.syscall_buf);
|
||||
/*
|
||||
* Return control to gdb for it to process the syscall request.
|
||||
* Since the protocol requires that gdb hands control back to us
|
||||
* using a "here are the results" F packet, we don't need to check
|
||||
* gdb_handlesig's return value (which is the signal to deliver if
|
||||
* execution was resumed via a continue packet).
|
||||
*/
|
||||
gdb_handlesig(gdbserver_state.c_cpu, 0);
|
||||
#else
|
||||
/*
|
||||
* In this case wait to send the syscall packet until notification that
|
||||
* the CPU has stopped. This must be done because if the packet is sent
|
||||
* now the reply from the syscall request could be received while the CPU
|
||||
* is still in the running state, which can cause packets to be dropped
|
||||
* and state transition 'T' packets to be sent while the syscall is still
|
||||
* being processed.
|
||||
*/
|
||||
qemu_cpu_kick(gdbserver_state.c_cpu);
|
||||
#endif
|
||||
|
||||
gdb_syscall_handling(gdbserver_syscall_state.syscall_buf);
|
||||
}
|
||||
|
||||
void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
|
||||
|
@ -472,3 +472,17 @@ void gdb_breakpoint_remove_all(CPUState *cs)
|
||||
{
|
||||
cpu_breakpoint_remove_all(cs, BP_GDB);
|
||||
}
|
||||
|
||||
/*
|
||||
* For user-mode syscall support we send the system call immediately
|
||||
* and then return control to gdb for it to process the syscall request.
|
||||
* Since the protocol requires that gdb hands control back to us
|
||||
* using a "here are the results" F packet, we don't need to check
|
||||
* gdb_handlesig's return value (which is the signal to deliver if
|
||||
* execution was resumed via a continue packet).
|
||||
*/
|
||||
void gdb_syscall_handling(const char *syscall_packet)
|
||||
{
|
||||
gdb_put_packet(syscall_packet);
|
||||
gdb_handlesig(gdbserver_state.c_cpu, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user