Support more function.

This commit is contained in:
Colin 2025-09-25 06:47:09 +00:00
parent 06775f841a
commit 3514600e30
6 changed files with 199 additions and 28 deletions

View File

@ -59,6 +59,9 @@
"ctype.h": "c",
"gdbstub.h": "c",
"pthread.h": "c",
"enums.h": "c"
"enums.h": "c",
"ctime": "c",
"iomanip": "c",
"sstream": "c"
}
}

View File

@ -3,6 +3,39 @@
#include <iostream>
/**
* Helper function for error checking after strtol() and the like
*/
static int check_strtox_error(const char *nptr, char *ep, const char **endptr, bool check_zero, int libc_errno) {
assert(ep >= nptr);
/* Windows has a bug in that it fails to parse 0 from "0x" in base 16 */
if (check_zero && ep == nptr && libc_errno == 0) {
char *tmp;
errno = 0;
if (strtol(nptr, &tmp, 10) == 0 && errno == 0 && (*tmp == 'x' || *tmp == 'X')) {
ep = tmp;
}
}
if (endptr) {
*endptr = ep;
}
/* Turn "no conversion" into an error */
if (libc_errno == 0 && ep == nptr) {
return -EINVAL;
}
/* Fail when we're expected to consume the string, but didn't */
if (!endptr && *ep) {
return -EINVAL;
}
return -libc_errno;
}
int qemu_strtoul(const char *nptr, const char **endptr, int base, unsigned long *result) {
char *ep;
@ -21,7 +54,7 @@ int qemu_strtoul(const char *nptr, const char **endptr, int base, unsigned long
if (errno == ERANGE) {
*result = -1;
}
return 0;
return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
}
int qemu_strtou64(const char *nptr, const char **endptr, int base, uint64_t *result) {
@ -44,5 +77,5 @@ int qemu_strtou64(const char *nptr, const char **endptr, int base, uint64_t *res
if (errno == ERANGE) {
*result = -1;
}
return 0;
}
return check_strtox_error(nptr, ep, endptr, *result == 0, errno);
}

View File

@ -220,7 +220,10 @@ static void gdb_set_cpu_pc(vaddr pc) {
cpu_set_pc(cpu, pc);
}
void gdb_append_thread_id(CPUState *cpu, GString *buf) { g_string_append_printf(buf, "%02x", 1); }
void gdb_append_thread_id(CPUState *cpu, GString *buf) {
g_string_append_printf(buf, "p%02x.%02x", 1, 1);
// g_string_append_printf(buf, "%02x", 1);
}
static GDBThreadIdKind read_thread_id(const char *buf, const char **end_buf, uint32_t *pid, uint32_t *tid) {
unsigned long p, t;
@ -345,10 +348,10 @@ static int gdb_handle_vcont(const char *p) {
break;
case GDB_ALL_THREADS:
process = gdb_get_process();
if (!process->attached) {
return -EINVAL;
}
// process = gdb_get_process();
// if (!process->attached) {
// return -EINVAL;
// }
cpu = get_cpu();
if (cpu) {
if (newstates[cpu->cpu_index] == 1) {
@ -856,7 +859,6 @@ static void handle_v_commands(GArray *params, void *user_ctx) {
if (!params->len) {
return;
}
if (!process_string_cmd(gdb_get_cmd_param(params, 0)->data, gdb_v_commands_table, ARRAY_SIZE(gdb_v_commands_table))) {
gdb_put_packet("");
}
@ -915,6 +917,11 @@ static void handle_query_curr_tid(GArray *params, void *user_ctx) {
gdb_put_strbuf();
}
static void handle_query_gdb_server_version(GArray *params, void *user_ctx) {
g_string_printf(gdb_state.str_buf, "name:system-riscv;version:1.9;");
gdb_put_strbuf();
}
static void handle_query_threads(GArray *params, void *user_ctx) {
if (!gdb_state.query_cpu) {
gdb_put_packet("l");
@ -925,11 +932,6 @@ static void handle_query_threads(GArray *params, void *user_ctx) {
gdb_state.query_cpu = 0;
}
static void handle_query_gdb_server_version(GArray *params, void *user_ctx) {
g_string_printf(gdb_state.str_buf, "name:qemu-system-riscv;version:1.9;");
gdb_put_strbuf();
}
static void handle_query_first_threads(GArray *params, void *user_ctx) {
gdb_state.query_cpu = get_cpu();
handle_query_threads(params, user_ctx);

View File

@ -240,4 +240,6 @@ void cpu_register_gdb_commands();
int cpu_common_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int cpu_common_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
void gdb_vm_state_change();
#endif /* GDBSTUB_INTERNALS_H */

View File

@ -10,7 +10,9 @@
* SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <iomanip>
#include <iostream>
#include <string>
#include "commands.h"
#include "cpu.h"
@ -312,40 +314,71 @@ bool runstate_is_running() {
/////// local cpu operation
///////
void vm_stop() { get_cpu()->running = false; }
void vm_start() { get_cpu()->running = true; }
void vm_stop() {
std::cout << "CPU=>vm_stop" << std::endl;
get_cpu()->running = false;
}
void vm_start() {
std::cout << "CPU=>vm_start" << std::endl;
get_cpu()->running = true;
}
void cpu_synchronize_state(CPUState *cpu) {}
void gdb_exit(int i) {};
void gdb_qemu_exit(int i) {};
void gdb_breakpoint_remove_all(CPUState *cs) {}
int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len) { return 0; }
int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len) { return 0; }
void gdb_breakpoint_remove_all(CPUState *cs) { std::cout << "CPU=>gdb_breakpoint_remove_all" << std::endl; }
int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len) {
std::cout << "CPU=>gdb_breakpoint_insert" << std::endl;
return 0;
}
int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len) {
std::cout << "CPU=>gdb_breakpoint_remove" << std::endl;
return 0;
}
static inline void cpu_physical_memory_write(hwaddr addr, const void *buf, hwaddr len) {}
static inline void cpu_physical_memory_read(hwaddr addr, const void *buf, hwaddr len) {}
static inline void cpu_physical_memory_write(hwaddr addr, const void *buf, hwaddr len) {
std::cout << "CPU=>memory_write addr:0x" << std::hex << addr << " len:0x" << len << std::endl;
std::cout << "CPU=>memory_write data:";
for (int i = 0; i < len; i++) {
uint8_t d = *((uint8_t *)buf + i);
std::cout << std::hex << std::setfill('0') << std::setw(2) << static_cast<int>(d);
}
std::cout << std::endl;
}
static inline void cpu_physical_memory_read(hwaddr addr, const void *buf, hwaddr len) {
std::cout << "CPU=>memory_read addr:0x" << std::hex << addr << " len:0x" << len << std::endl;
}
bool runstate_needs_reset(void) { return false; }
bool vm_prepare_start(bool step_requested) { return true; }
bool vm_prepare_start(bool step_requested) { return false; }
void gdb_handle_file_io(GArray *params, void *user_ctx) {}
void gdb_handle_file_io(GArray *params, void *user_ctx) { std::cout << "CPU=>gdb_handle_file_io" << std::endl; }
void gdb_disable_syscalls(void) {}
void cpu_single_step(CPUState *cpu, int enabled) {}
void cpu_single_step(CPUState *cpu, int enabled) { std::cout << "CPU=>cpu_single_step" << std::endl; }
void cpu_resume(CPUState *cpu) {
cpu->stop = false;
cpu->stopped = false;
std::cout << "CPU=>cpu_resume" << std::endl;
// g_autoptr(GString) buf = g_string_new(NULL);
// g_string_printf(buf, "T%02xthread:p01.01;", 05);
// gdb_put_packet(buf->str);
}
int cpu_common_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg) {
uint64_t val = 0;
g_byte_array_append(buf, (uint8_t *)&val, 8);
std::cout << "CPU=>read_register reg:0x" << reg << std::endl;
return 8;
}
int cpu_common_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg) { return 0; }
int cpu_common_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg) {
std::cout << "CPU=>write_register reg:0x" << reg << std::endl;
return 0;
}
int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr, uint8_t *buf, int len, bool is_write) {
if (is_write) {
@ -357,7 +390,105 @@ int gdb_target_memory_rw_debug(CPUState *cpu, hwaddr addr, uint8_t *buf, int len
}
void gdb_continue(void) {
std::cout << "CPU=>gdb_continue" << std::endl;
if (!runstate_needs_reset()) {
vm_start();
}
}
}
// static void gdb_vm_state_change() {
// CPUState *cpu = gdbserver_state.c_cpu;
// g_autoptr(GString) buf = g_string_new(NULL);
// g_autoptr(GString) tid = g_string_new(NULL);
// const char *type;
// int ret;
// if (running || gdbserver_state.state == RS_INACTIVE) {
// return;
// }
// /* Is there a GDB syscall waiting to be sent? */
// if (gdb_handled_syscall()) {
// return;
// }
// if (cpu == NULL) {
// /* No process attached */
// return;
// }
// if (!gdbserver_state.allow_stop_reply) {
// return;
// }
// gdb_append_thread_id(cpu, tid);
// switch (state) {
// case RUN_STATE_DEBUG:
// if (cpu->watchpoint_hit) {
// switch (cpu->watchpoint_hit->flags & BP_MEM_ACCESS) {
// case BP_MEM_READ:
// type = "r";
// break;
// case BP_MEM_ACCESS:
// type = "a";
// break;
// default:
// type = "";
// break;
// }
// trace_gdbstub_hit_watchpoint(type, gdb_get_cpu_index(cpu), cpu->watchpoint_hit->vaddr);
// g_string_printf(buf, "T%02xthread:%s;%swatch:%" VADDR_PRIx ";", GDB_SIGNAL_TRAP, tid->str, type,
// cpu->watchpoint_hit->vaddr);
// cpu->watchpoint_hit = NULL;
// goto send_packet;
// } else {
// trace_gdbstub_hit_break();
// }
// if (tcg_enabled()) {
// tb_flush(cpu);
// }
// ret = GDB_SIGNAL_TRAP;
// break;
// case RUN_STATE_PAUSED:
// trace_gdbstub_hit_paused();
// ret = GDB_SIGNAL_INT;
// break;
// case RUN_STATE_SHUTDOWN:
// trace_gdbstub_hit_shutdown();
// ret = GDB_SIGNAL_QUIT;
// break;
// case RUN_STATE_IO_ERROR:
// trace_gdbstub_hit_io_error();
// ret = GDB_SIGNAL_STOP;
// break;
// case RUN_STATE_WATCHDOG:
// trace_gdbstub_hit_watchdog();
// ret = GDB_SIGNAL_ALRM;
// break;
// case RUN_STATE_INTERNAL_ERROR:
// trace_gdbstub_hit_internal_error();
// ret = GDB_SIGNAL_ABRT;
// break;
// case RUN_STATE_SAVE_VM:
// case RUN_STATE_RESTORE_VM:
// return;
// case RUN_STATE_FINISH_MIGRATE:
// ret = GDB_SIGNAL_XCPU;
// break;
// default:
// trace_gdbstub_hit_unknown(state);
// ret = GDB_SIGNAL_UNKNOWN;
// break;
// }
// gdb_set_stop_cpu(cpu);
// g_string_printf(buf, "T%02xthread:%s;", ret, tid->str);
// send_packet:
// gdb_put_packet(buf->str);
// gdbserver_state.allow_stop_reply = false;
// /* disable single step if it was enabled */
// cpu_single_step(cpu, 0);
// }

View File

@ -90,7 +90,7 @@ void conn_recv_packet(conn_t *conn) {
packet_t *conn_pop_packet(conn_t *conn) {
packet_t *pkt = pktbuf_pop_packet(&conn->pktbuf);
if (pkt) printf("packet = %s\n", pkt->data);
if (pkt) printf("receive = %s\n", pkt->data);
return pkt;
}