gdbstub: move str_buf to GDBState and use GString
Rather than having a static buffer replace str_buf with a GString which we know can grow on demand. Convert the internal functions to take a GString instead of a char * and length. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Damien Hedde <damien.hedde@greensocs.com> Tested-by: Damien Hedde <damien.hedde@greensocs.com> Message-Id: <20200316172155.971-9-alex.bennee@linaro.org>
This commit is contained in:
parent
a346af3e35
commit
308f9e88b2
197
gdbstub.c
197
gdbstub.c
@ -366,6 +366,7 @@ typedef struct GDBState {
|
||||
int process_num;
|
||||
char syscall_buf[256];
|
||||
gdb_syscall_complete_cb current_syscall_cb;
|
||||
GString *str_buf;
|
||||
} GDBState;
|
||||
|
||||
/* By default use no IRQs and no timers while single stepping so as to
|
||||
@ -380,6 +381,7 @@ static void init_gdbserver_state(void)
|
||||
g_assert(!gdbserver_state.init);
|
||||
memset(&gdbserver_state, 0, sizeof(GDBState));
|
||||
gdbserver_state.init = true;
|
||||
gdbserver_state.str_buf = g_string_new(NULL);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
@ -563,17 +565,15 @@ static inline int tohex(int v)
|
||||
}
|
||||
|
||||
/* writes 2*len+1 bytes in buf */
|
||||
static void memtohex(char *buf, const uint8_t *mem, int len)
|
||||
static void memtohex(GString *buf, const uint8_t *mem, int len)
|
||||
{
|
||||
int i, c;
|
||||
char *q;
|
||||
q = buf;
|
||||
for(i = 0; i < len; i++) {
|
||||
c = mem[i];
|
||||
*q++ = tohex(c >> 4);
|
||||
*q++ = tohex(c & 0xf);
|
||||
g_string_append_c(buf, tohex(c >> 4));
|
||||
g_string_append_c(buf, tohex(c & 0xf));
|
||||
}
|
||||
*q = '\0';
|
||||
g_string_append_c(buf, '\0');
|
||||
}
|
||||
|
||||
static void hextomem(uint8_t *mem, const char *buf, int len)
|
||||
@ -667,25 +667,28 @@ static int put_packet(const char *buf)
|
||||
return put_packet_binary(buf, strlen(buf), false);
|
||||
}
|
||||
|
||||
/* Encode data using the encoding for 'x' packets. */
|
||||
static int memtox(char *buf, const char *mem, int len)
|
||||
static void put_strbuf(void)
|
||||
{
|
||||
put_packet(gdbserver_state.str_buf->str);
|
||||
}
|
||||
|
||||
/* Encode data using the encoding for 'x' packets. */
|
||||
static void memtox(GString *buf, const char *mem, int len)
|
||||
{
|
||||
char *p = buf;
|
||||
char c;
|
||||
|
||||
while (len--) {
|
||||
c = *(mem++);
|
||||
switch (c) {
|
||||
case '#': case '$': case '*': case '}':
|
||||
*(p++) = '}';
|
||||
*(p++) = c ^ 0x20;
|
||||
g_string_append_c(buf, '}');
|
||||
g_string_append_c(buf, c ^ 0x20);
|
||||
break;
|
||||
default:
|
||||
*(p++) = c;
|
||||
g_string_append_c(buf, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return p - buf;
|
||||
}
|
||||
|
||||
static uint32_t gdb_get_cpu_pid(CPUState *cpu)
|
||||
@ -1109,16 +1112,14 @@ static void gdb_set_cpu_pc(target_ulong pc)
|
||||
cpu_set_pc(cpu, pc);
|
||||
}
|
||||
|
||||
static char *gdb_fmt_thread_id(CPUState *cpu, char *buf, size_t buf_size)
|
||||
static void gdb_append_thread_id(CPUState *cpu, GString *buf)
|
||||
{
|
||||
if (gdbserver_state.multiprocess) {
|
||||
snprintf(buf, buf_size, "p%02x.%02x",
|
||||
gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
|
||||
g_string_append_printf(buf, "p%02x.%02x",
|
||||
gdb_get_cpu_pid(cpu), cpu_gdb_index(cpu));
|
||||
} else {
|
||||
snprintf(buf, buf_size, "%02x", cpu_gdb_index(cpu));
|
||||
g_string_append_printf(buf, "%02x", cpu_gdb_index(cpu));
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
typedef enum GDBThreadIdKind {
|
||||
@ -1412,7 +1413,6 @@ typedef struct GdbCmdContext {
|
||||
GdbCmdVariant *params;
|
||||
int num_params;
|
||||
uint8_t mem_buf[MAX_PACKET_LENGTH];
|
||||
char str_buf[MAX_PACKET_LENGTH + 1];
|
||||
} GdbCmdContext;
|
||||
|
||||
typedef void (*GdbCmdHandler)(GdbCmdContext *gdb_ctx, void *user_ctx);
|
||||
@ -1502,6 +1502,8 @@ static void run_cmd_parser(const char *data, const GdbCmdParseEntry *cmd)
|
||||
return;
|
||||
}
|
||||
|
||||
g_string_set_size(gdbserver_state.str_buf, 0);
|
||||
|
||||
/* In case there was an error during the command parsing we must
|
||||
* send a NULL packet to indicate the command is not supported */
|
||||
if (process_string_cmd(NULL, data, cmd, 1)) {
|
||||
@ -1740,8 +1742,8 @@ static void handle_get_reg(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
memtohex(gdb_ctx->str_buf, gdb_ctx->mem_buf, reg_size);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
memtohex(gdbserver_state.str_buf, gdb_ctx->mem_buf, reg_size);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
static void handle_write_mem(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
@ -1789,8 +1791,8 @@ static void handle_read_mem(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
return;
|
||||
}
|
||||
|
||||
memtohex(gdb_ctx->str_buf, gdb_ctx->mem_buf, gdb_ctx->params[1].val_ull);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
memtohex(gdbserver_state.str_buf, gdb_ctx->mem_buf, gdb_ctx->params[1].val_ull);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
static void handle_write_all_regs(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
@ -1827,8 +1829,8 @@ static void handle_read_all_regs(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
addr);
|
||||
}
|
||||
|
||||
memtohex(gdb_ctx->str_buf, gdb_ctx->mem_buf, len);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
memtohex(gdbserver_state.str_buf, gdb_ctx->mem_buf, len);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
static void handle_file_io(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
@ -1889,9 +1891,8 @@ static void handle_v_attach(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
{
|
||||
GDBProcess *process;
|
||||
CPUState *cpu;
|
||||
char thread_id[16];
|
||||
|
||||
pstrcpy(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "E22");
|
||||
g_string_assign(gdbserver_state.str_buf, "E22");
|
||||
if (!gdb_ctx->num_params) {
|
||||
goto cleanup;
|
||||
}
|
||||
@ -1910,11 +1911,11 @@ static void handle_v_attach(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
gdbserver_state.g_cpu = cpu;
|
||||
gdbserver_state.c_cpu = cpu;
|
||||
|
||||
gdb_fmt_thread_id(cpu, thread_id, sizeof(thread_id));
|
||||
snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "T%02xthread:%s;",
|
||||
GDB_SIGNAL_TRAP, thread_id);
|
||||
g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
|
||||
gdb_append_thread_id(cpu, gdbserver_state.str_buf);
|
||||
g_string_append_c(gdbserver_state.str_buf, ';');
|
||||
cleanup:
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
static void handle_v_kill(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
@ -1966,10 +1967,9 @@ static void handle_v_commands(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
|
||||
static void handle_query_qemu_sstepbits(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
{
|
||||
snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
|
||||
"ENABLE=%x,NOIRQ=%x,NOTIMER=%x", SSTEP_ENABLE,
|
||||
SSTEP_NOIRQ, SSTEP_NOTIMER);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
g_string_printf(gdbserver_state.str_buf, "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
|
||||
SSTEP_ENABLE, SSTEP_NOIRQ, SSTEP_NOTIMER);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
static void handle_set_qemu_sstep(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
@ -1984,15 +1984,14 @@ static void handle_set_qemu_sstep(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
|
||||
static void handle_query_qemu_sstep(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
{
|
||||
snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "0x%x", sstep_flags);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
g_string_printf(gdbserver_state.str_buf, "0x%x", sstep_flags);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
static void handle_query_curr_tid(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
{
|
||||
CPUState *cpu;
|
||||
GDBProcess *process;
|
||||
char thread_id[16];
|
||||
|
||||
/*
|
||||
* "Current thread" remains vague in the spec, so always return
|
||||
@ -2001,24 +2000,21 @@ static void handle_query_curr_tid(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
*/
|
||||
process = gdb_get_cpu_process(gdbserver_state.g_cpu);
|
||||
cpu = get_first_cpu_in_process(process);
|
||||
gdb_fmt_thread_id(cpu, thread_id, sizeof(thread_id));
|
||||
snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "QC%s", thread_id);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
g_string_assign(gdbserver_state.str_buf, "QC");
|
||||
gdb_append_thread_id(cpu, gdbserver_state.str_buf);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
static void handle_query_threads(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
{
|
||||
char thread_id[16];
|
||||
|
||||
if (!gdbserver_state.query_cpu) {
|
||||
put_packet("l");
|
||||
return;
|
||||
}
|
||||
|
||||
gdb_fmt_thread_id(gdbserver_state.query_cpu, thread_id,
|
||||
sizeof(thread_id));
|
||||
snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "m%s", thread_id);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
g_string_assign(gdbserver_state.str_buf, "m");
|
||||
gdb_append_thread_id(gdbserver_state.query_cpu, gdbserver_state.str_buf);
|
||||
put_strbuf();
|
||||
gdbserver_state.query_cpu = gdb_next_attached_cpu(gdbserver_state.query_cpu);
|
||||
}
|
||||
|
||||
@ -2030,8 +2026,8 @@ static void handle_query_first_threads(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
|
||||
static void handle_query_thread_extra(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
{
|
||||
g_autoptr(GString) rs = g_string_new(NULL);
|
||||
CPUState *cpu;
|
||||
int len;
|
||||
|
||||
if (!gdb_ctx->num_params ||
|
||||
gdb_ctx->params[0].thread_id.kind == GDB_READ_THREAD_ERR) {
|
||||
@ -2051,20 +2047,17 @@ static void handle_query_thread_extra(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
/* Print the CPU model and name in multiprocess mode */
|
||||
ObjectClass *oc = object_get_class(OBJECT(cpu));
|
||||
const char *cpu_model = object_class_get_name(oc);
|
||||
char *cpu_name = object_get_canonical_path_component(OBJECT(cpu));
|
||||
len = snprintf((char *)gdb_ctx->mem_buf, sizeof(gdb_ctx->str_buf) / 2,
|
||||
"%s %s [%s]", cpu_model, cpu_name,
|
||||
cpu->halted ? "halted " : "running");
|
||||
g_free(cpu_name);
|
||||
g_autofree char *cpu_name;
|
||||
cpu_name = object_get_canonical_path_component(OBJECT(cpu));
|
||||
g_string_printf(rs, "%s %s [%s]", cpu_model, cpu_name,
|
||||
cpu->halted ? "halted " : "running");
|
||||
} else {
|
||||
/* memtohex() doubles the required space */
|
||||
len = snprintf((char *)gdb_ctx->mem_buf, sizeof(gdb_ctx->str_buf) / 2,
|
||||
"CPU#%d [%s]", cpu->cpu_index,
|
||||
g_string_printf(rs, "CPU#%d [%s]", cpu->cpu_index,
|
||||
cpu->halted ? "halted " : "running");
|
||||
}
|
||||
trace_gdbstub_op_extra_info((char *)gdb_ctx->mem_buf);
|
||||
memtohex(gdb_ctx->str_buf, gdb_ctx->mem_buf, len);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
trace_gdbstub_op_extra_info(rs->str);
|
||||
memtohex(gdbserver_state.str_buf, (uint8_t *)rs->str, rs->len);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
@ -2073,13 +2066,14 @@ static void handle_query_offsets(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
TaskState *ts;
|
||||
|
||||
ts = gdbserver_state.c_cpu->opaque;
|
||||
snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
|
||||
"Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
|
||||
";Bss=" TARGET_ABI_FMT_lx,
|
||||
ts->info->code_offset,
|
||||
ts->info->data_offset,
|
||||
ts->info->data_offset);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
g_string_printf(gdbserver_state.str_buf,
|
||||
"Text=" TARGET_ABI_FMT_lx
|
||||
";Data=" TARGET_ABI_FMT_lx
|
||||
";Bss=" TARGET_ABI_FMT_lx,
|
||||
ts->info->code_offset,
|
||||
ts->info->data_offset,
|
||||
ts->info->data_offset);
|
||||
put_strbuf();
|
||||
}
|
||||
#else
|
||||
static void handle_query_rcmd(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
@ -2110,12 +2104,10 @@ static void handle_query_supported(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
{
|
||||
CPUClass *cc;
|
||||
|
||||
snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "PacketSize=%x",
|
||||
MAX_PACKET_LENGTH);
|
||||
g_string_printf(gdbserver_state.str_buf, "PacketSize=%x", MAX_PACKET_LENGTH);
|
||||
cc = CPU_GET_CLASS(first_cpu);
|
||||
if (cc->gdb_core_xml_file) {
|
||||
pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf),
|
||||
";qXfer:features:read+");
|
||||
g_string_append(gdbserver_state.str_buf, ";qXfer:features:read+");
|
||||
}
|
||||
|
||||
if (gdb_ctx->num_params &&
|
||||
@ -2123,8 +2115,8 @@ static void handle_query_supported(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
gdbserver_state.multiprocess = true;
|
||||
}
|
||||
|
||||
pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";multiprocess+");
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
g_string_append(gdbserver_state.str_buf, ";multiprocess+");
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
static void handle_query_xfer_features(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
@ -2168,14 +2160,15 @@ static void handle_query_xfer_features(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
}
|
||||
|
||||
if (len < total_len - addr) {
|
||||
gdb_ctx->str_buf[0] = 'm';
|
||||
len = memtox(gdb_ctx->str_buf + 1, xml + addr, len);
|
||||
g_string_assign(gdbserver_state.str_buf, "m");
|
||||
memtox(gdbserver_state.str_buf, xml + addr, len);
|
||||
} else {
|
||||
gdb_ctx->str_buf[0] = 'l';
|
||||
len = memtox(gdb_ctx->str_buf + 1, xml + addr, total_len - addr);
|
||||
g_string_assign(gdbserver_state.str_buf, "l");
|
||||
memtox(gdbserver_state.str_buf, xml + addr, total_len - addr);
|
||||
}
|
||||
|
||||
put_packet_binary(gdb_ctx->str_buf, len + 1, true);
|
||||
put_packet_binary(gdbserver_state.str_buf->str,
|
||||
gdbserver_state.str_buf->len, true);
|
||||
}
|
||||
|
||||
static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
@ -2185,19 +2178,19 @@ static void handle_query_attached(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
|
||||
static void handle_query_qemu_supported(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
{
|
||||
snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "sstepbits;sstep");
|
||||
g_string_printf(gdbserver_state.str_buf, "sstepbits;sstep");
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
pstrcat(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), ";PhyMemMode");
|
||||
g_string_append(gdbserver_state.str_buf, ";PhyMemMode");
|
||||
#endif
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
static void handle_query_qemu_phy_mem_mode(GdbCmdContext *gdb_ctx,
|
||||
void *user_ctx)
|
||||
{
|
||||
snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "%d", phy_memory_mode);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
g_string_printf(gdbserver_state.str_buf, "%d", phy_memory_mode);
|
||||
put_strbuf();
|
||||
}
|
||||
|
||||
static void handle_set_qemu_phy_mem_mode(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
@ -2362,13 +2355,10 @@ static void handle_gen_set(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
|
||||
static void handle_target_halt(GdbCmdContext *gdb_ctx, void *user_ctx)
|
||||
{
|
||||
char thread_id[16];
|
||||
|
||||
gdb_fmt_thread_id(gdbserver_state.c_cpu, thread_id,
|
||||
sizeof(thread_id));
|
||||
snprintf(gdb_ctx->str_buf, sizeof(gdb_ctx->str_buf), "T%02xthread:%s;",
|
||||
GDB_SIGNAL_TRAP, thread_id);
|
||||
put_packet(gdb_ctx->str_buf);
|
||||
g_string_printf(gdbserver_state.str_buf, "T%02xthread:", GDB_SIGNAL_TRAP);
|
||||
gdb_append_thread_id(gdbserver_state.c_cpu, gdbserver_state.str_buf);
|
||||
g_string_append_c(gdbserver_state.str_buf, ';');
|
||||
put_strbuf();
|
||||
/*
|
||||
* Remove all the breakpoints when this query is issued,
|
||||
* because gdb is doing an initial connect and the state
|
||||
@ -2631,8 +2621,8 @@ void gdb_set_stop_cpu(CPUState *cpu)
|
||||
static void gdb_vm_state_change(void *opaque, int running, RunState state)
|
||||
{
|
||||
CPUState *cpu = gdbserver_state.c_cpu;
|
||||
char buf[256];
|
||||
char thread_id[16];
|
||||
g_autoptr(GString) buf = g_string_new(NULL);
|
||||
g_autoptr(GString) tid = g_string_new(NULL);
|
||||
const char *type;
|
||||
int ret;
|
||||
|
||||
@ -2650,7 +2640,7 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
|
||||
return;
|
||||
}
|
||||
|
||||
gdb_fmt_thread_id(cpu, thread_id, sizeof(thread_id));
|
||||
gdb_append_thread_id(cpu, tid);
|
||||
|
||||
switch (state) {
|
||||
case RUN_STATE_DEBUG:
|
||||
@ -2668,10 +2658,9 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
|
||||
}
|
||||
trace_gdbstub_hit_watchpoint(type, cpu_gdb_index(cpu),
|
||||
(target_ulong)cpu->watchpoint_hit->vaddr);
|
||||
snprintf(buf, sizeof(buf),
|
||||
"T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
|
||||
GDB_SIGNAL_TRAP, thread_id, type,
|
||||
(target_ulong)cpu->watchpoint_hit->vaddr);
|
||||
g_string_printf(buf, "T%02xthread:%s;%swatch:" TARGET_FMT_lx ";",
|
||||
GDB_SIGNAL_TRAP, tid->str, type,
|
||||
(target_ulong)cpu->watchpoint_hit->vaddr);
|
||||
cpu->watchpoint_hit = NULL;
|
||||
goto send_packet;
|
||||
} else {
|
||||
@ -2712,10 +2701,10 @@ static void gdb_vm_state_change(void *opaque, int running, RunState state)
|
||||
break;
|
||||
}
|
||||
gdb_set_stop_cpu(cpu);
|
||||
snprintf(buf, sizeof(buf), "T%02xthread:%s;", ret, thread_id);
|
||||
g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
|
||||
|
||||
send_packet:
|
||||
put_packet(buf);
|
||||
put_packet(buf->str);
|
||||
|
||||
/* disable single step if it was enabled */
|
||||
cpu_single_step(cpu, 0);
|
||||
@ -3196,13 +3185,9 @@ static void gdb_chr_event(void *opaque, QEMUChrEvent event)
|
||||
|
||||
static void gdb_monitor_output(const char *msg, int len)
|
||||
{
|
||||
char buf[MAX_PACKET_LENGTH];
|
||||
|
||||
buf[0] = 'O';
|
||||
if (len > (MAX_PACKET_LENGTH/2) - 1)
|
||||
len = (MAX_PACKET_LENGTH/2) - 1;
|
||||
memtohex(buf + 1, (uint8_t *)msg, len);
|
||||
put_packet(buf);
|
||||
g_autoptr(GString) buf = g_string_new("O");
|
||||
memtohex(buf, (uint8_t *)msg, len);
|
||||
put_packet(buf->str);
|
||||
}
|
||||
|
||||
static int gdb_monitor_write(Chardev *chr, const uint8_t *buf, int len)
|
||||
|
Loading…
Reference in New Issue
Block a user