1 /* 2 * gdbstub internals 3 * 4 * Copyright (c) 2022 Linaro Ltd 5 * 6 * SPDX-License-Identifier: GPL-2.0-or-later 7 */ 8 9 #ifndef GDBSTUB_INTERNALS_H 10 #define GDBSTUB_INTERNALS_H 11 12 #include "exec/cpu-common.h" 13 14 #define MAX_PACKET_LENGTH 4096 15 16 /* 17 * Shared structures and definitions 18 */ 19 20 enum { 21 GDB_SIGNAL_0 = 0, 22 GDB_SIGNAL_INT = 2, 23 GDB_SIGNAL_QUIT = 3, 24 GDB_SIGNAL_TRAP = 5, 25 GDB_SIGNAL_ABRT = 6, 26 GDB_SIGNAL_ALRM = 14, 27 GDB_SIGNAL_IO = 23, 28 GDB_SIGNAL_XCPU = 24, 29 GDB_SIGNAL_UNKNOWN = 143 30 }; 31 32 typedef struct GDBProcess { 33 uint32_t pid; 34 bool attached; 35 36 char target_xml[1024]; 37 } GDBProcess; 38 39 enum RSState { 40 RS_INACTIVE, 41 RS_IDLE, 42 RS_GETLINE, 43 RS_GETLINE_ESC, 44 RS_GETLINE_RLE, 45 RS_CHKSUM1, 46 RS_CHKSUM2, 47 }; 48 49 typedef struct GDBState { 50 bool init; /* have we been initialised? */ 51 CPUState *c_cpu; /* current CPU for step/continue ops */ 52 CPUState *g_cpu; /* current CPU for other ops */ 53 CPUState *query_cpu; /* for q{f|s}ThreadInfo */ 54 enum RSState state; /* parsing state */ 55 char line_buf[MAX_PACKET_LENGTH]; 56 int line_buf_index; 57 int line_sum; /* running checksum */ 58 int line_csum; /* checksum at the end of the packet */ 59 GByteArray *last_packet; 60 int signal; 61 bool multiprocess; 62 GDBProcess *processes; 63 int process_num; 64 char syscall_buf[256]; 65 gdb_syscall_complete_cb current_syscall_cb; 66 GString *str_buf; 67 GByteArray *mem_buf; 68 int sstep_flags; 69 int supported_sstep_flags; 70 } GDBState; 71 72 /* lives in main gdbstub.c */ 73 extern GDBState gdbserver_state; 74 75 /* 76 * Inline utility function, convert from int to hex and back 77 */ 78 79 static inline int fromhex(int v) 80 { 81 if (v >= '0' && v <= '9') { 82 return v - '0'; 83 } else if (v >= 'A' && v <= 'F') { 84 return v - 'A' + 10; 85 } else if (v >= 'a' && v <= 'f') { 86 return v - 'a' + 10; 87 } else { 88 return 0; 89 } 90 } 91 92 static inline int tohex(int v) 93 { 94 if (v < 10) { 95 return v + '0'; 96 } else { 97 return v - 10 + 'a'; 98 } 99 } 100 101 /* 102 * Connection helpers for both softmmu and user backends 103 */ 104 105 void gdb_put_strbuf(void); 106 int gdb_put_packet(const char *buf); 107 int gdb_put_packet_binary(const char *buf, int len, bool dump); 108 void gdb_hextomem(GByteArray *mem, const char *buf, int len); 109 void gdb_memtohex(GString *buf, const uint8_t *mem, int len); 110 void gdb_memtox(GString *buf, const char *mem, int len); 111 void gdb_read_byte(uint8_t ch); 112 113 /* utility helpers */ 114 CPUState *gdb_first_attached_cpu(void); 115 void gdb_append_thread_id(CPUState *cpu, GString *buf); 116 int gdb_get_cpu_index(CPUState *cpu); 117 118 void gdb_create_default_process(GDBState *s); 119 120 /* signal mapping, common for softmmu, specialised for user-mode */ 121 int gdb_signal_to_target(int sig); 122 int gdb_target_signal_to_gdb(int sig); 123 124 int gdb_get_char(void); /* user only */ 125 126 /** 127 * gdb_continue() - handle continue in mode specific way. 128 */ 129 void gdb_continue(void); 130 131 /** 132 * gdb_continue_partial() - handle partial continue in mode specific way. 133 */ 134 int gdb_continue_partial(char *newstates); 135 136 /* 137 * Helpers with separate softmmu and user implementations 138 */ 139 void gdb_put_buffer(const uint8_t *buf, int len); 140 141 /* 142 * Command handlers - either softmmu or user only 143 */ 144 void gdb_init_gdbserver_state(void); 145 146 typedef enum GDBThreadIdKind { 147 GDB_ONE_THREAD = 0, 148 GDB_ALL_THREADS, /* One process, all threads */ 149 GDB_ALL_PROCESSES, 150 GDB_READ_THREAD_ERR 151 } GDBThreadIdKind; 152 153 typedef union GdbCmdVariant { 154 const char *data; 155 uint8_t opcode; 156 unsigned long val_ul; 157 unsigned long long val_ull; 158 struct { 159 GDBThreadIdKind kind; 160 uint32_t pid; 161 uint32_t tid; 162 } thread_id; 163 } GdbCmdVariant; 164 165 #define get_param(p, i) (&g_array_index(p, GdbCmdVariant, i)) 166 167 void gdb_handle_query_rcmd(GArray *params, void *user_ctx); /* softmmu */ 168 void gdb_handle_query_offsets(GArray *params, void *user_ctx); /* user */ 169 void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx); /*user */ 170 171 /* 172 * Break/Watch point support - there is an implementation for softmmu 173 * and user mode. 174 */ 175 bool gdb_supports_guest_debug(void); 176 int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len); 177 int gdb_breakpoint_remove(CPUState *cs, int type, vaddr addr, vaddr len); 178 void gdb_breakpoint_remove_all(CPUState *cs); 179 180 #endif /* GDBSTUB_INTERNALS_H */ 181