user-target.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426
  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-or-later
  8. */
  9. #include "qemu/osdep.h"
  10. #include "exec/gdbstub.h"
  11. #include "gdbstub/commands.h"
  12. #include "qemu.h"
  13. #include "internals.h"
  14. #ifdef CONFIG_LINUX
  15. #include "linux-user/loader.h"
  16. #include "linux-user/qemu.h"
  17. #endif
  18. /*
  19. * Map target signal numbers to GDB protocol signal numbers and vice
  20. * versa. For user emulation's currently supported systems, we can
  21. * assume most signals are defined.
  22. */
  23. static int gdb_signal_table[] = {
  24. 0,
  25. TARGET_SIGHUP,
  26. TARGET_SIGINT,
  27. TARGET_SIGQUIT,
  28. TARGET_SIGILL,
  29. TARGET_SIGTRAP,
  30. TARGET_SIGABRT,
  31. -1, /* SIGEMT */
  32. TARGET_SIGFPE,
  33. TARGET_SIGKILL,
  34. TARGET_SIGBUS,
  35. TARGET_SIGSEGV,
  36. TARGET_SIGSYS,
  37. TARGET_SIGPIPE,
  38. TARGET_SIGALRM,
  39. TARGET_SIGTERM,
  40. TARGET_SIGURG,
  41. TARGET_SIGSTOP,
  42. TARGET_SIGTSTP,
  43. TARGET_SIGCONT,
  44. TARGET_SIGCHLD,
  45. TARGET_SIGTTIN,
  46. TARGET_SIGTTOU,
  47. TARGET_SIGIO,
  48. TARGET_SIGXCPU,
  49. TARGET_SIGXFSZ,
  50. TARGET_SIGVTALRM,
  51. TARGET_SIGPROF,
  52. TARGET_SIGWINCH,
  53. -1, /* SIGLOST */
  54. TARGET_SIGUSR1,
  55. TARGET_SIGUSR2,
  56. #ifdef TARGET_SIGPWR
  57. TARGET_SIGPWR,
  58. #else
  59. -1,
  60. #endif
  61. -1, /* SIGPOLL */
  62. -1,
  63. -1,
  64. -1,
  65. -1,
  66. -1,
  67. -1,
  68. -1,
  69. -1,
  70. -1,
  71. -1,
  72. -1,
  73. #ifdef __SIGRTMIN
  74. __SIGRTMIN + 1,
  75. __SIGRTMIN + 2,
  76. __SIGRTMIN + 3,
  77. __SIGRTMIN + 4,
  78. __SIGRTMIN + 5,
  79. __SIGRTMIN + 6,
  80. __SIGRTMIN + 7,
  81. __SIGRTMIN + 8,
  82. __SIGRTMIN + 9,
  83. __SIGRTMIN + 10,
  84. __SIGRTMIN + 11,
  85. __SIGRTMIN + 12,
  86. __SIGRTMIN + 13,
  87. __SIGRTMIN + 14,
  88. __SIGRTMIN + 15,
  89. __SIGRTMIN + 16,
  90. __SIGRTMIN + 17,
  91. __SIGRTMIN + 18,
  92. __SIGRTMIN + 19,
  93. __SIGRTMIN + 20,
  94. __SIGRTMIN + 21,
  95. __SIGRTMIN + 22,
  96. __SIGRTMIN + 23,
  97. __SIGRTMIN + 24,
  98. __SIGRTMIN + 25,
  99. __SIGRTMIN + 26,
  100. __SIGRTMIN + 27,
  101. __SIGRTMIN + 28,
  102. __SIGRTMIN + 29,
  103. __SIGRTMIN + 30,
  104. __SIGRTMIN + 31,
  105. -1, /* SIGCANCEL */
  106. __SIGRTMIN,
  107. __SIGRTMIN + 32,
  108. __SIGRTMIN + 33,
  109. __SIGRTMIN + 34,
  110. __SIGRTMIN + 35,
  111. __SIGRTMIN + 36,
  112. __SIGRTMIN + 37,
  113. __SIGRTMIN + 38,
  114. __SIGRTMIN + 39,
  115. __SIGRTMIN + 40,
  116. __SIGRTMIN + 41,
  117. __SIGRTMIN + 42,
  118. __SIGRTMIN + 43,
  119. __SIGRTMIN + 44,
  120. __SIGRTMIN + 45,
  121. __SIGRTMIN + 46,
  122. __SIGRTMIN + 47,
  123. __SIGRTMIN + 48,
  124. __SIGRTMIN + 49,
  125. __SIGRTMIN + 50,
  126. __SIGRTMIN + 51,
  127. __SIGRTMIN + 52,
  128. __SIGRTMIN + 53,
  129. __SIGRTMIN + 54,
  130. __SIGRTMIN + 55,
  131. __SIGRTMIN + 56,
  132. __SIGRTMIN + 57,
  133. __SIGRTMIN + 58,
  134. __SIGRTMIN + 59,
  135. __SIGRTMIN + 60,
  136. __SIGRTMIN + 61,
  137. __SIGRTMIN + 62,
  138. __SIGRTMIN + 63,
  139. __SIGRTMIN + 64,
  140. __SIGRTMIN + 65,
  141. __SIGRTMIN + 66,
  142. __SIGRTMIN + 67,
  143. __SIGRTMIN + 68,
  144. __SIGRTMIN + 69,
  145. __SIGRTMIN + 70,
  146. __SIGRTMIN + 71,
  147. __SIGRTMIN + 72,
  148. __SIGRTMIN + 73,
  149. __SIGRTMIN + 74,
  150. __SIGRTMIN + 75,
  151. __SIGRTMIN + 76,
  152. __SIGRTMIN + 77,
  153. __SIGRTMIN + 78,
  154. __SIGRTMIN + 79,
  155. __SIGRTMIN + 80,
  156. __SIGRTMIN + 81,
  157. __SIGRTMIN + 82,
  158. __SIGRTMIN + 83,
  159. __SIGRTMIN + 84,
  160. __SIGRTMIN + 85,
  161. __SIGRTMIN + 86,
  162. __SIGRTMIN + 87,
  163. __SIGRTMIN + 88,
  164. __SIGRTMIN + 89,
  165. __SIGRTMIN + 90,
  166. __SIGRTMIN + 91,
  167. __SIGRTMIN + 92,
  168. __SIGRTMIN + 93,
  169. __SIGRTMIN + 94,
  170. __SIGRTMIN + 95,
  171. -1, /* SIGINFO */
  172. -1, /* UNKNOWN */
  173. -1, /* DEFAULT */
  174. -1,
  175. -1,
  176. -1,
  177. -1,
  178. -1,
  179. -1
  180. #endif
  181. };
  182. int gdb_signal_to_target(int sig)
  183. {
  184. if (sig < ARRAY_SIZE(gdb_signal_table)) {
  185. return gdb_signal_table[sig];
  186. } else {
  187. return -1;
  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. int gdb_get_cpu_index(CPUState *cpu)
  201. {
  202. TaskState *ts = get_task_state(cpu);
  203. return ts ? ts->ts_tid : -1;
  204. }
  205. /*
  206. * User-mode specific command helpers
  207. */
  208. void gdb_handle_query_offsets(GArray *params, void *user_ctx)
  209. {
  210. TaskState *ts;
  211. ts = get_task_state(gdbserver_state.c_cpu);
  212. g_string_printf(gdbserver_state.str_buf,
  213. "Text=" TARGET_ABI_FMT_lx
  214. ";Data=" TARGET_ABI_FMT_lx
  215. ";Bss=" TARGET_ABI_FMT_lx,
  216. ts->info->code_offset,
  217. ts->info->data_offset,
  218. ts->info->data_offset);
  219. gdb_put_strbuf();
  220. }
  221. #if defined(CONFIG_LINUX)
  222. /* Partial user only duplicate of helper in gdbstub.c */
  223. static inline int target_memory_rw_debug(CPUState *cpu, target_ulong addr,
  224. uint8_t *buf, int len, bool is_write)
  225. {
  226. CPUClass *cc;
  227. cc = CPU_GET_CLASS(cpu);
  228. if (cc->memory_rw_debug) {
  229. return cc->memory_rw_debug(cpu, addr, buf, len, is_write);
  230. }
  231. return cpu_memory_rw_debug(cpu, addr, buf, len, is_write);
  232. }
  233. void gdb_handle_query_xfer_auxv(GArray *params, void *user_ctx)
  234. {
  235. TaskState *ts;
  236. unsigned long offset, len, saved_auxv, auxv_len;
  237. if (params->len < 2) {
  238. gdb_put_packet("E22");
  239. return;
  240. }
  241. offset = gdb_get_cmd_param(params, 0)->val_ul;
  242. len = gdb_get_cmd_param(params, 1)->val_ul;
  243. ts = get_task_state(gdbserver_state.c_cpu);
  244. saved_auxv = ts->info->saved_auxv;
  245. auxv_len = ts->info->auxv_len;
  246. if (offset >= auxv_len) {
  247. gdb_put_packet("E00");
  248. return;
  249. }
  250. if (len > (MAX_PACKET_LENGTH - 5) / 2) {
  251. len = (MAX_PACKET_LENGTH - 5) / 2;
  252. }
  253. if (len < auxv_len - offset) {
  254. g_string_assign(gdbserver_state.str_buf, "m");
  255. } else {
  256. g_string_assign(gdbserver_state.str_buf, "l");
  257. len = auxv_len - offset;
  258. }
  259. g_byte_array_set_size(gdbserver_state.mem_buf, len);
  260. if (target_memory_rw_debug(gdbserver_state.g_cpu, saved_auxv + offset,
  261. gdbserver_state.mem_buf->data, len, false)) {
  262. gdb_put_packet("E14");
  263. return;
  264. }
  265. gdb_memtox(gdbserver_state.str_buf,
  266. (const char *)gdbserver_state.mem_buf->data, len);
  267. gdb_put_packet_binary(gdbserver_state.str_buf->str,
  268. gdbserver_state.str_buf->len, true);
  269. }
  270. #endif
  271. static const char *get_filename_param(GArray *params, int i)
  272. {
  273. const char *hex_filename = gdb_get_cmd_param(params, i)->data;
  274. gdb_hextomem(gdbserver_state.mem_buf, hex_filename,
  275. strlen(hex_filename) / 2);
  276. g_byte_array_append(gdbserver_state.mem_buf, (const guint8 *)"", 1);
  277. return (const char *)gdbserver_state.mem_buf->data;
  278. }
  279. static void hostio_reply_with_data(const void *buf, size_t n)
  280. {
  281. g_string_printf(gdbserver_state.str_buf, "F%zx;", n);
  282. gdb_memtox(gdbserver_state.str_buf, buf, n);
  283. gdb_put_packet_binary(gdbserver_state.str_buf->str,
  284. gdbserver_state.str_buf->len, true);
  285. }
  286. void gdb_handle_v_file_open(GArray *params, void *user_ctx)
  287. {
  288. const char *filename = get_filename_param(params, 0);
  289. uint64_t flags = gdb_get_cmd_param(params, 1)->val_ull;
  290. uint64_t mode = gdb_get_cmd_param(params, 2)->val_ull;
  291. #ifdef CONFIG_LINUX
  292. int fd = do_guest_openat(cpu_env(gdbserver_state.g_cpu), 0, filename,
  293. flags, mode, false);
  294. #else
  295. int fd = open(filename, flags, mode);
  296. #endif
  297. if (fd < 0) {
  298. g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
  299. } else {
  300. g_string_printf(gdbserver_state.str_buf, "F%x", fd);
  301. }
  302. gdb_put_strbuf();
  303. }
  304. void gdb_handle_v_file_close(GArray *params, void *user_ctx)
  305. {
  306. int fd = gdb_get_cmd_param(params, 0)->val_ul;
  307. if (close(fd) == -1) {
  308. g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
  309. gdb_put_strbuf();
  310. return;
  311. }
  312. gdb_put_packet("F00");
  313. }
  314. void gdb_handle_v_file_pread(GArray *params, void *user_ctx)
  315. {
  316. int fd = gdb_get_cmd_param(params, 0)->val_ul;
  317. size_t count = gdb_get_cmd_param(params, 1)->val_ull;
  318. off_t offset = gdb_get_cmd_param(params, 2)->val_ull;
  319. size_t bufsiz = MIN(count, BUFSIZ);
  320. g_autofree char *buf = g_try_malloc(bufsiz);
  321. if (buf == NULL) {
  322. gdb_put_packet("E12");
  323. return;
  324. }
  325. ssize_t n = pread(fd, buf, bufsiz, offset);
  326. if (n < 0) {
  327. g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
  328. gdb_put_strbuf();
  329. return;
  330. }
  331. hostio_reply_with_data(buf, n);
  332. }
  333. void gdb_handle_v_file_readlink(GArray *params, void *user_ctx)
  334. {
  335. const char *filename = get_filename_param(params, 0);
  336. g_autofree char *buf = g_try_malloc(BUFSIZ);
  337. if (buf == NULL) {
  338. gdb_put_packet("E12");
  339. return;
  340. }
  341. #ifdef CONFIG_LINUX
  342. ssize_t n = do_guest_readlink(filename, buf, BUFSIZ);
  343. #else
  344. ssize_t n = readlink(filename, buf, BUFSIZ);
  345. #endif
  346. if (n < 0) {
  347. g_string_printf(gdbserver_state.str_buf, "F-1,%x", errno);
  348. gdb_put_strbuf();
  349. return;
  350. }
  351. hostio_reply_with_data(buf, n);
  352. }
  353. void gdb_handle_query_xfer_exec_file(GArray *params, void *user_ctx)
  354. {
  355. uint32_t pid = gdb_get_cmd_param(params, 0)->val_ul;
  356. uint32_t offset = gdb_get_cmd_param(params, 1)->val_ul;
  357. uint32_t length = gdb_get_cmd_param(params, 2)->val_ul;
  358. GDBProcess *process = gdb_get_process(pid);
  359. if (!process) {
  360. gdb_put_packet("E00");
  361. return;
  362. }
  363. CPUState *cpu = gdb_get_first_cpu_in_process(process);
  364. if (!cpu) {
  365. gdb_put_packet("E00");
  366. return;
  367. }
  368. TaskState *ts = get_task_state(cpu);
  369. if (!ts || !ts->bprm || !ts->bprm->filename) {
  370. gdb_put_packet("E00");
  371. return;
  372. }
  373. size_t total_length = strlen(ts->bprm->filename);
  374. if (offset > total_length) {
  375. gdb_put_packet("E00");
  376. return;
  377. }
  378. if (offset + length > total_length) {
  379. length = total_length - offset;
  380. }
  381. g_string_printf(gdbserver_state.str_buf, "l%.*s", length,
  382. ts->bprm->filename + offset);
  383. gdb_put_strbuf();
  384. }
  385. int gdb_target_sigtrap(void)
  386. {
  387. return TARGET_SIGTRAP;
  388. }