Skip to content

Commit ecd39d6

Browse files
Maxim Levitskybonzini
Maxim Levitsky
authored andcommitted
gdbstub: reject unsupported flags in handle_set_qemu_sstep
handle_query_qemu_sstepbits is reporting NOIRQ and NOTIMER bits even if they are not supported (as is the case with record/replay). Instead, store the supported singlestep flags and reject any unsupported bits in handle_set_qemu_sstep. This removes the need for the get_sstep_flags() wrapper. While at it, move the variables in GDBState, instead of using global variables. Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com> [Extracted from Maxim's patch into a separate commit. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Message-Id: <20211111110604.207376-4-pbonzini@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 43709a0 commit ecd39d6

File tree

1 file changed

+49
-26
lines changed

1 file changed

+49
-26
lines changed

gdbstub.c

+49-26
Original file line numberDiff line numberDiff line change
@@ -368,27 +368,10 @@ typedef struct GDBState {
368368
gdb_syscall_complete_cb current_syscall_cb;
369369
GString *str_buf;
370370
GByteArray *mem_buf;
371+
int sstep_flags;
372+
int supported_sstep_flags;
371373
} GDBState;
372374

373-
/* By default use no IRQs and no timers while single stepping so as to
374-
* make single stepping like an ICE HW step.
375-
*/
376-
static int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
377-
378-
/* Retrieves flags for single step mode. */
379-
static int get_sstep_flags(void)
380-
{
381-
/*
382-
* In replay mode all events written into the log should be replayed.
383-
* That is why NOIRQ flag is removed in this mode.
384-
*/
385-
if (replay_mode != REPLAY_MODE_NONE) {
386-
return SSTEP_ENABLE;
387-
} else {
388-
return sstep_flags;
389-
}
390-
}
391-
392375
static GDBState gdbserver_state;
393376

394377
static void init_gdbserver_state(void)
@@ -399,6 +382,26 @@ static void init_gdbserver_state(void)
399382
gdbserver_state.str_buf = g_string_new(NULL);
400383
gdbserver_state.mem_buf = g_byte_array_sized_new(MAX_PACKET_LENGTH);
401384
gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4);
385+
386+
/*
387+
* In replay mode all events will come from the log and can't be
388+
* suppressed otherwise we would break determinism. However as those
389+
* events are tied to the number of executed instructions we won't see
390+
* them occurring every time we single step.
391+
*/
392+
if (replay_mode != REPLAY_MODE_NONE) {
393+
gdbserver_state.supported_sstep_flags = SSTEP_ENABLE;
394+
} else {
395+
gdbserver_state.supported_sstep_flags =
396+
SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
397+
}
398+
399+
/*
400+
* By default use no IRQs and no timers while single stepping so as to
401+
* make single stepping like an ICE HW step.
402+
*/
403+
gdbserver_state.sstep_flags = gdbserver_state.supported_sstep_flags;
404+
402405
}
403406

404407
#ifndef CONFIG_USER_ONLY
@@ -505,7 +508,7 @@ static int gdb_continue_partial(char *newstates)
505508
CPU_FOREACH(cpu) {
506509
if (newstates[cpu->cpu_index] == 's') {
507510
trace_gdbstub_op_stepping(cpu->cpu_index);
508-
cpu_single_step(cpu, sstep_flags);
511+
cpu_single_step(cpu, gdbserver_state.sstep_flags);
509512
}
510513
}
511514
gdbserver_state.running_state = 1;
@@ -524,7 +527,7 @@ static int gdb_continue_partial(char *newstates)
524527
break; /* nothing to do here */
525528
case 's':
526529
trace_gdbstub_op_stepping(cpu->cpu_index);
527-
cpu_single_step(cpu, get_sstep_flags());
530+
cpu_single_step(cpu, gdbserver_state.sstep_flags);
528531
cpu_resume(cpu);
529532
flag = 1;
530533
break;
@@ -1883,7 +1886,7 @@ static void handle_step(GArray *params, void *user_ctx)
18831886
gdb_set_cpu_pc((target_ulong)get_param(params, 0)->val_ull);
18841887
}
18851888

1886-
cpu_single_step(gdbserver_state.c_cpu, get_sstep_flags());
1889+
cpu_single_step(gdbserver_state.c_cpu, gdbserver_state.sstep_flags);
18871890
gdb_continue();
18881891
}
18891892

@@ -2017,24 +2020,44 @@ static void handle_v_commands(GArray *params, void *user_ctx)
20172020

20182021
static void handle_query_qemu_sstepbits(GArray *params, void *user_ctx)
20192022
{
2020-
g_string_printf(gdbserver_state.str_buf, "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
2021-
SSTEP_ENABLE, SSTEP_NOIRQ, SSTEP_NOTIMER);
2023+
g_string_printf(gdbserver_state.str_buf, "ENABLE=%x", SSTEP_ENABLE);
2024+
2025+
if (gdbserver_state.supported_sstep_flags & SSTEP_NOIRQ) {
2026+
g_string_append_printf(gdbserver_state.str_buf, ",NOIRQ=%x",
2027+
SSTEP_NOIRQ);
2028+
}
2029+
2030+
if (gdbserver_state.supported_sstep_flags & SSTEP_NOTIMER) {
2031+
g_string_append_printf(gdbserver_state.str_buf, ",NOTIMER=%x",
2032+
SSTEP_NOTIMER);
2033+
}
2034+
20222035
put_strbuf();
20232036
}
20242037

20252038
static void handle_set_qemu_sstep(GArray *params, void *user_ctx)
20262039
{
2040+
int new_sstep_flags;
2041+
20272042
if (!params->len) {
20282043
return;
20292044
}
20302045

2031-
sstep_flags = get_param(params, 0)->val_ul;
2046+
new_sstep_flags = get_param(params, 0)->val_ul;
2047+
2048+
if (new_sstep_flags & ~gdbserver_state.supported_sstep_flags) {
2049+
put_packet("E22");
2050+
return;
2051+
}
2052+
2053+
gdbserver_state.sstep_flags = new_sstep_flags;
20322054
put_packet("OK");
20332055
}
20342056

20352057
static void handle_query_qemu_sstep(GArray *params, void *user_ctx)
20362058
{
2037-
g_string_printf(gdbserver_state.str_buf, "0x%x", sstep_flags);
2059+
g_string_printf(gdbserver_state.str_buf, "0x%x",
2060+
gdbserver_state.sstep_flags);
20382061
put_strbuf();
20392062
}
20402063

0 commit comments

Comments
 (0)