1 /* 2 * GDB Syscall Handling 3 * 4 * GDB can execute syscalls on the guests behalf, currently used by 5 * the various semihosting extensions. As this interfaces with a guest 6 * ABI we need to build it per-guest (although in reality its a 32 or 7 * 64 bit target_ulong that is the only difference). 8 * 9 * Copyright (c) 2003-2005 Fabrice Bellard 10 * Copyright (c) 2023 Linaro Ltd 11 * 12 * SPDX-License-Identifier: LGPL-2.0+ 13 */ 14 15 #include "qemu/osdep.h" 16 #include "qemu/error-report.h" 17 #include "cpu.h" 18 #include "semihosting/semihost.h" 19 #include "sysemu/runstate.h" 20 #include "gdbstub/user.h" 21 #include "gdbstub/syscalls.h" 22 #include "trace.h" 23 #include "internals.h" 24 25 /* Syscall specific state */ 26 typedef struct { 27 char syscall_buf[256]; 28 gdb_syscall_complete_cb current_syscall_cb; 29 } GDBSyscallState; 30 31 static GDBSyscallState gdbserver_syscall_state; 32 33 /* 34 * Return true if there is a GDB currently connected to the stub 35 * and attached to a CPU 36 */ 37 static bool gdb_attached(void) 38 { 39 return gdbserver_state.init && gdbserver_state.c_cpu; 40 } 41 42 static enum { 43 GDB_SYS_UNKNOWN, 44 GDB_SYS_ENABLED, 45 GDB_SYS_DISABLED, 46 } gdb_syscall_mode; 47 48 /* Decide if either remote gdb syscalls or native file IO should be used. */ 49 int use_gdb_syscalls(void) 50 { 51 SemihostingTarget target = semihosting_get_target(); 52 if (target == SEMIHOSTING_TARGET_NATIVE) { 53 /* -semihosting-config target=native */ 54 return false; 55 } else if (target == SEMIHOSTING_TARGET_GDB) { 56 /* -semihosting-config target=gdb */ 57 return true; 58 } 59 60 /* -semihosting-config target=auto */ 61 /* On the first call check if gdb is connected and remember. */ 62 if (gdb_syscall_mode == GDB_SYS_UNKNOWN) { 63 gdb_syscall_mode = gdb_attached() ? GDB_SYS_ENABLED : GDB_SYS_DISABLED; 64 } 65 return gdb_syscall_mode == GDB_SYS_ENABLED; 66 } 67 68 /* called when the stub detaches */ 69 void gdb_disable_syscalls(void) 70 { 71 gdb_syscall_mode = GDB_SYS_DISABLED; 72 } 73 74 void gdb_syscall_reset(void) 75 { 76 gdbserver_syscall_state.current_syscall_cb = NULL; 77 } 78 79 bool gdb_handled_syscall(void) 80 { 81 if (gdbserver_syscall_state.current_syscall_cb) { 82 gdb_put_packet(gdbserver_syscall_state.syscall_buf); 83 return true; 84 } 85 86 return false; 87 } 88 89 /* 90 * Send a gdb syscall request. 91 * This accepts limited printf-style format specifiers, specifically: 92 * %x - target_ulong argument printed in hex. 93 * %lx - 64-bit argument printed in hex. 94 * %s - string pointer (target_ulong) and length (int) pair. 95 */ 96 void gdb_do_syscallv(gdb_syscall_complete_cb cb, const char *fmt, va_list va) 97 { 98 char *p; 99 char *p_end; 100 target_ulong addr; 101 uint64_t i64; 102 103 if (!gdb_attached()) { 104 return; 105 } 106 107 gdbserver_syscall_state.current_syscall_cb = cb; 108 #ifndef CONFIG_USER_ONLY 109 vm_stop(RUN_STATE_DEBUG); 110 #endif 111 p = &gdbserver_syscall_state.syscall_buf[0]; 112 p_end = &gdbserver_syscall_state.syscall_buf[sizeof(gdbserver_syscall_state.syscall_buf)]; 113 *(p++) = 'F'; 114 while (*fmt) { 115 if (*fmt == '%') { 116 fmt++; 117 switch (*fmt++) { 118 case 'x': 119 addr = va_arg(va, target_ulong); 120 p += snprintf(p, p_end - p, TARGET_FMT_lx, addr); 121 break; 122 case 'l': 123 if (*(fmt++) != 'x') { 124 goto bad_format; 125 } 126 i64 = va_arg(va, uint64_t); 127 p += snprintf(p, p_end - p, "%" PRIx64, i64); 128 break; 129 case 's': 130 addr = va_arg(va, target_ulong); 131 p += snprintf(p, p_end - p, TARGET_FMT_lx "/%x", 132 addr, va_arg(va, int)); 133 break; 134 default: 135 bad_format: 136 error_report("gdbstub: Bad syscall format string '%s'", 137 fmt - 1); 138 break; 139 } 140 } else { 141 *(p++) = *(fmt++); 142 } 143 } 144 *p = 0; 145 #ifdef CONFIG_USER_ONLY 146 gdb_put_packet(gdbserver_syscall_state.syscall_buf); 147 /* 148 * Return control to gdb for it to process the syscall request. 149 * Since the protocol requires that gdb hands control back to us 150 * using a "here are the results" F packet, we don't need to check 151 * gdb_handlesig's return value (which is the signal to deliver if 152 * execution was resumed via a continue packet). 153 */ 154 gdb_handlesig(gdbserver_state.c_cpu, 0); 155 #else 156 /* 157 * In this case wait to send the syscall packet until notification that 158 * the CPU has stopped. This must be done because if the packet is sent 159 * now the reply from the syscall request could be received while the CPU 160 * is still in the running state, which can cause packets to be dropped 161 * and state transition 'T' packets to be sent while the syscall is still 162 * being processed. 163 */ 164 qemu_cpu_kick(gdbserver_state.c_cpu); 165 #endif 166 } 167 168 void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...) 169 { 170 va_list va; 171 172 va_start(va, fmt); 173 gdb_do_syscallv(cb, fmt, va); 174 va_end(va); 175 } 176 177 /* 178 * GDB Command Handlers 179 */ 180 181 void gdb_handle_file_io(GArray *params, void *user_ctx) 182 { 183 if (params->len >= 1 && gdbserver_syscall_state.current_syscall_cb) { 184 uint64_t ret; 185 int err; 186 187 ret = get_param(params, 0)->val_ull; 188 if (params->len >= 2) { 189 err = get_param(params, 1)->val_ull; 190 } else { 191 err = 0; 192 } 193 194 /* Convert GDB error numbers back to host error numbers. */ 195 #define E(X) case GDB_E##X: err = E##X; break 196 switch (err) { 197 case 0: 198 break; 199 E(PERM); 200 E(NOENT); 201 E(INTR); 202 E(BADF); 203 E(ACCES); 204 E(FAULT); 205 E(BUSY); 206 E(EXIST); 207 E(NODEV); 208 E(NOTDIR); 209 E(ISDIR); 210 E(INVAL); 211 E(NFILE); 212 E(MFILE); 213 E(FBIG); 214 E(NOSPC); 215 E(SPIPE); 216 E(ROFS); 217 E(NAMETOOLONG); 218 default: 219 err = EINVAL; 220 break; 221 } 222 #undef E 223 224 gdbserver_syscall_state.current_syscall_cb(gdbserver_state.c_cpu, 225 ret, err); 226 gdbserver_syscall_state.current_syscall_cb = NULL; 227 } 228 229 if (params->len >= 3 && get_param(params, 2)->opcode == (uint8_t)'C') { 230 gdb_put_packet("T02"); 231 return; 232 } 233 234 gdb_continue(); 235 } 236