1 /* 2 * Target specific user-mode handling 3 * 4 * Copyright (c) 2003-2005 Fabrice Bellard 5 * Copyright (c) 2022 Linaro Ltd 6 * 7 * SPDX-License-Identifier: LGPL-2.0+ 8 */ 9 10 #include "qemu/osdep.h" 11 #include "exec/gdbstub.h" 12 #include "qemu.h" 13 #include "internals.h" 14 15 /* 16 * Map target signal numbers to GDB protocol signal numbers and vice 17 * versa. For user emulation's currently supported systems, we can 18 * assume most signals are defined. 19 */ 20 21 static int gdb_signal_table[] = { 22 0, 23 TARGET_SIGHUP, 24 TARGET_SIGINT, 25 TARGET_SIGQUIT, 26 TARGET_SIGILL, 27 TARGET_SIGTRAP, 28 TARGET_SIGABRT, 29 -1, /* SIGEMT */ 30 TARGET_SIGFPE, 31 TARGET_SIGKILL, 32 TARGET_SIGBUS, 33 TARGET_SIGSEGV, 34 TARGET_SIGSYS, 35 TARGET_SIGPIPE, 36 TARGET_SIGALRM, 37 TARGET_SIGTERM, 38 TARGET_SIGURG, 39 TARGET_SIGSTOP, 40 TARGET_SIGTSTP, 41 TARGET_SIGCONT, 42 TARGET_SIGCHLD, 43 TARGET_SIGTTIN, 44 TARGET_SIGTTOU, 45 TARGET_SIGIO, 46 TARGET_SIGXCPU, 47 TARGET_SIGXFSZ, 48 TARGET_SIGVTALRM, 49 TARGET_SIGPROF, 50 TARGET_SIGWINCH, 51 -1, /* SIGLOST */ 52 TARGET_SIGUSR1, 53 TARGET_SIGUSR2, 54 #ifdef TARGET_SIGPWR 55 TARGET_SIGPWR, 56 #else 57 -1, 58 #endif 59 -1, /* SIGPOLL */ 60 -1, 61 -1, 62 -1, 63 -1, 64 -1, 65 -1, 66 -1, 67 -1, 68 -1, 69 -1, 70 -1, 71 #ifdef __SIGRTMIN 72 __SIGRTMIN + 1, 73 __SIGRTMIN + 2, 74 __SIGRTMIN + 3, 75 __SIGRTMIN + 4, 76 __SIGRTMIN + 5, 77 __SIGRTMIN + 6, 78 __SIGRTMIN + 7, 79 __SIGRTMIN + 8, 80 __SIGRTMIN + 9, 81 __SIGRTMIN + 10, 82 __SIGRTMIN + 11, 83 __SIGRTMIN + 12, 84 __SIGRTMIN + 13, 85 __SIGRTMIN + 14, 86 __SIGRTMIN + 15, 87 __SIGRTMIN + 16, 88 __SIGRTMIN + 17, 89 __SIGRTMIN + 18, 90 __SIGRTMIN + 19, 91 __SIGRTMIN + 20, 92 __SIGRTMIN + 21, 93 __SIGRTMIN + 22, 94 __SIGRTMIN + 23, 95 __SIGRTMIN + 24, 96 __SIGRTMIN + 25, 97 __SIGRTMIN + 26, 98 __SIGRTMIN + 27, 99 __SIGRTMIN + 28, 100 __SIGRTMIN + 29, 101 __SIGRTMIN + 30, 102 __SIGRTMIN + 31, 103 -1, /* SIGCANCEL */ 104 __SIGRTMIN, 105 __SIGRTMIN + 32, 106 __SIGRTMIN + 33, 107 __SIGRTMIN + 34, 108 __SIGRTMIN + 35, 109 __SIGRTMIN + 36, 110 __SIGRTMIN + 37, 111 __SIGRTMIN + 38, 112 __SIGRTMIN + 39, 113 __SIGRTMIN + 40, 114 __SIGRTMIN + 41, 115 __SIGRTMIN + 42, 116 __SIGRTMIN + 43, 117 __SIGRTMIN + 44, 118 __SIGRTMIN + 45, 119 __SIGRTMIN + 46, 120 __SIGRTMIN + 47, 121 __SIGRTMIN + 48, 122 __SIGRTMIN + 49, 123 __SIGRTMIN + 50, 124 __SIGRTMIN + 51, 125 __SIGRTMIN + 52, 126 __SIGRTMIN + 53, 127 __SIGRTMIN + 54, 128 __SIGRTMIN + 55, 129 __SIGRTMIN + 56, 130 __SIGRTMIN + 57, 131 __SIGRTMIN + 58, 132 __SIGRTMIN + 59, 133 __SIGRTMIN + 60, 134 __SIGRTMIN + 61, 135 __SIGRTMIN + 62, 136 __SIGRTMIN + 63, 137 __SIGRTMIN + 64, 138 __SIGRTMIN + 65, 139 __SIGRTMIN + 66, 140 __SIGRTMIN + 67, 141 __SIGRTMIN + 68, 142 __SIGRTMIN + 69, 143 __SIGRTMIN + 70, 144 __SIGRTMIN + 71, 145 __SIGRTMIN + 72, 146 __SIGRTMIN + 73, 147 __SIGRTMIN + 74, 148 __SIGRTMIN + 75, 149 __SIGRTMIN + 76, 150 __SIGRTMIN + 77, 151 __SIGRTMIN + 78, 152 __SIGRTMIN + 79, 153 __SIGRTMIN + 80, 154 __SIGRTMIN + 81, 155 __SIGRTMIN + 82, 156 __SIGRTMIN + 83, 157 __SIGRTMIN + 84, 158 __SIGRTMIN + 85, 159 __SIGRTMIN + 86, 160 __SIGRTMIN + 87, 161 __SIGRTMIN + 88, 162 __SIGRTMIN + 89, 163 __SIGRTMIN + 90, 164 __SIGRTMIN + 91, 165 __SIGRTMIN + 92, 166 __SIGRTMIN + 93, 167 __SIGRTMIN + 94, 168 __SIGRTMIN + 95, 169 -1, /* SIGINFO */ 170 -1, /* UNKNOWN */ 171 -1, /* DEFAULT */ 172 -1, 173 -1, 174 -1, 175 -1, 176 -1, 177 -1 178 #endif 179 }; 180 181 int gdb_signal_to_target(int sig) 182 { 183 if (sig < ARRAY_SIZE(gdb_signal_table)) { 184 return gdb_signal_table[sig]; 185 } else { 186 return -1; 187 } 188 } 189 190 int gdb_target_signal_to_gdb(int sig) 191 { 192 int i; 193 for (i = 0; i < ARRAY_SIZE(gdb_signal_table); i++) { 194 if (gdb_signal_table[i] == sig) { 195 return i; 196 } 197 } 198 return GDB_SIGNAL_UNKNOWN; 199 } 200 201 int gdb_get_cpu_index(CPUState *cpu) 202 { 203 TaskState *ts = (TaskState *) cpu->opaque; 204 return ts ? ts->ts_tid : -1; 205 } 206 207 /* 208 * User-mode specific command helpers 209 */ 210 211 void gdb_handle_query_offsets(GArray *params, void *user_ctx) 212 { 213 TaskState *ts; 214 215 ts = gdbserver_state.c_cpu->opaque; 216 g_string_printf(gdbserver_state.str_buf, 217 "Text=" TARGET_ABI_FMT_lx 218 ";Data=" TARGET_ABI_FMT_lx 219 ";Bss=" TARGET_ABI_FMT_lx, 220 ts->info->code_offset, 221 ts->info->data_offset, 222 ts->info->data_offset); 223 gdb_put_strbuf(); 224 } 225 226 #if defined(CONFIG_LINUX) 227 /* Partial user only duplicate of helper in gdbstub.c */ 228 static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr, 229 uint8_t *buf, int len, bool is_write) 230 { 231 CPUClass *cc; 232 cc = CPU_GET_CLASS(cpu); 233 if (cc->memory_rw_debug) { 234 return cc->memory_rw_debug(cpu, addr, buf, len, is_write); 235 } 236 return cpu_memory_rw_debug(cpu, addr, buf, len, is_write); 237 } 238 239 void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx) 240 { 241 TaskState *ts; 242 unsigned long offset, len, saved_auxv, auxv_len; 243 244 if (params->len < 2) { 245 gdb_put_packet("E22"); 246 return; 247 } 248 249 offset = get_param(params, 0)->val_ul; 250 len = get_param(params, 1)->val_ul; 251 ts = gdbserver_state.c_cpu->opaque; 252 saved_auxv = ts->info->saved_auxv; 253 auxv_len = ts->info->auxv_len; 254 255 if (offset >= auxv_len) { 256 gdb_put_packet("E00"); 257 return; 258 } 259 260 if (len > (MAX_PACKET_LENGTH - 5) / 2) { 261 len = (MAX_PACKET_LENGTH - 5) / 2; 262 } 263 264 if (len < auxv_len - offset) { 265 g_string_assign(gdbserver_state.str_buf, "m"); 266 } else { 267 g_string_assign(gdbserver_state.str_buf, "l"); 268 len = auxv_len - offset; 269 } 270 271 g_byte_array_set_size(gdbserver_state.mem_buf, len); 272 if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset, 273 gdbserver_state.mem_buf->data, len, false)) { 274 gdb_put_packet("E14"); 275 return; 276 } 277 278 gdb_memtox(gdbserver_state.str_buf, 279 (const char *)gdbserver_state.mem_buf->data, len); 280 gdb_put_packet_binary(gdbserver_state.str_buf->str, 281 gdbserver_state.str_buf->len, true); 282 } 283 #endif 284