2
0

syscalls.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * GDB Syscall Handling
  3. *
  4. * GDB can execute syscalls on the guests behalf, currently used by
  5. * the various semihosting extensions.
  6. *
  7. * Copyright (c) 2003-2005 Fabrice Bellard
  8. * Copyright (c) 2023 Linaro Ltd
  9. *
  10. * SPDX-License-Identifier: LGPL-2.0-or-later
  11. */
  12. #include "qemu/osdep.h"
  13. #include "qemu/error-report.h"
  14. #include "semihosting/semihost.h"
  15. #include "system/runstate.h"
  16. #include "gdbstub/user.h"
  17. #include "gdbstub/syscalls.h"
  18. #include "gdbstub/commands.h"
  19. #include "trace.h"
  20. #include "internals.h"
  21. /* Syscall specific state */
  22. typedef struct {
  23. char syscall_buf[256];
  24. gdb_syscall_complete_cb current_syscall_cb;
  25. } GDBSyscallState;
  26. static GDBSyscallState gdbserver_syscall_state;
  27. /*
  28. * Return true if there is a GDB currently connected to the stub
  29. * and attached to a CPU
  30. */
  31. static bool gdb_attached(void)
  32. {
  33. return gdbserver_state.init && gdbserver_state.c_cpu;
  34. }
  35. static enum {
  36. GDB_SYS_UNKNOWN,
  37. GDB_SYS_ENABLED,
  38. GDB_SYS_DISABLED,
  39. } gdb_syscall_mode;
  40. /* Decide if either remote gdb syscalls or native file IO should be used. */
  41. int use_gdb_syscalls(void)
  42. {
  43. SemihostingTarget target = semihosting_get_target();
  44. if (target == SEMIHOSTING_TARGET_NATIVE) {
  45. /* -semihosting-config target=native */
  46. return false;
  47. } else if (target == SEMIHOSTING_TARGET_GDB) {
  48. /* -semihosting-config target=gdb */
  49. return true;
  50. }
  51. /* -semihosting-config target=auto */
  52. /* On the first call check if gdb is connected and remember. */
  53. if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
  54. gdb_syscall_mode = gdb_attached() ? GDB_SYS_ENABLED : GDB_SYS_DISABLED;
  55. }
  56. return gdb_syscall_mode == GDB_SYS_ENABLED;
  57. }
  58. /* called when the stub detaches */
  59. void gdb_disable_syscalls(void)
  60. {
  61. gdb_syscall_mode = GDB_SYS_DISABLED;
  62. }
  63. void gdb_syscall_reset(void)
  64. {
  65. gdbserver_syscall_state.current_syscall_cb = NULL;
  66. }
  67. bool gdb_handled_syscall(void)
  68. {
  69. if (gdbserver_syscall_state.current_syscall_cb) {
  70. gdb_put_packet(gdbserver_syscall_state.syscall_buf);
  71. return true;
  72. }
  73. return false;
  74. }
  75. /*
  76. * Send a gdb syscall request.
  77. * This accepts limited printf-style format specifiers, specifically:
  78. * %x - target_ulong argument printed in hex.
  79. * %lx - 64-bit argument printed in hex.
  80. * %s - string pointer (target_ulong) and length (int) pair.
  81. */
  82. void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
  83. {
  84. char *p, *p_end;
  85. va_list va;
  86. if (!gdb_attached()) {
  87. return;
  88. }
  89. gdbserver_syscall_state.current_syscall_cb = cb;
  90. va_start(va, fmt);
  91. p = gdbserver_syscall_state.syscall_buf;
  92. p_end = p + sizeof(gdbserver_syscall_state.syscall_buf);
  93. *(p++) = 'F';
  94. while (*fmt) {
  95. if (*fmt == '%') {
  96. uint64_t i64;
  97. uint32_t i32;
  98. fmt++;
  99. switch (*fmt++) {
  100. case 'x':
  101. i32 = va_arg(va, uint32_t);
  102. p += snprintf(p, p_end - p, "%" PRIx32, i32);
  103. break;
  104. case 'l':
  105. if (*(fmt++) != 'x') {
  106. goto bad_format;
  107. }
  108. i64 = va_arg(va, uint64_t);
  109. p += snprintf(p, p_end - p, "%" PRIx64, i64);
  110. break;
  111. case 's':
  112. i64 = va_arg(va, uint64_t);
  113. i32 = va_arg(va, uint32_t);
  114. p += snprintf(p, p_end - p, "%" PRIx64 "/%x" PRIx32, i64, i32);
  115. break;
  116. default:
  117. bad_format:
  118. error_report("gdbstub: Bad syscall format string '%s'",
  119. fmt - 1);
  120. break;
  121. }
  122. } else {
  123. *(p++) = *(fmt++);
  124. }
  125. }
  126. *p = 0;
  127. va_end(va);
  128. gdb_syscall_handling(gdbserver_syscall_state.syscall_buf);
  129. }
  130. /*
  131. * GDB Command Handlers
  132. */
  133. void gdb_handle_file_io(GArray *params, void *user_ctx)
  134. {
  135. if (params->len >= 1 && gdbserver_syscall_state.current_syscall_cb) {
  136. uint64_t ret;
  137. int err;
  138. ret = gdb_get_cmd_param(params, 0)->val_ull;
  139. if (params->len >= 2) {
  140. err = gdb_get_cmd_param(params, 1)->val_ull;
  141. } else {
  142. err = 0;
  143. }
  144. /* Convert GDB error numbers back to host error numbers. */
  145. #define E(X) case GDB_E##X: err = E##X; break
  146. switch (err) {
  147. case 0:
  148. break;
  149. E(PERM);
  150. E(NOENT);
  151. E(INTR);
  152. E(BADF);
  153. E(ACCES);
  154. E(FAULT);
  155. E(BUSY);
  156. E(EXIST);
  157. E(NODEV);
  158. E(NOTDIR);
  159. E(ISDIR);
  160. E(INVAL);
  161. E(NFILE);
  162. E(MFILE);
  163. E(FBIG);
  164. E(NOSPC);
  165. E(SPIPE);
  166. E(ROFS);
  167. E(NAMETOOLONG);
  168. default:
  169. err = EINVAL;
  170. break;
  171. }
  172. #undef E
  173. gdbserver_syscall_state.current_syscall_cb(gdbserver_state.c_cpu,
  174. ret, err);
  175. gdbserver_syscall_state.current_syscall_cb = NULL;
  176. }
  177. if (params->len >= 3 && gdb_get_cmd_param(params, 2)->opcode == (uint8_t)'C') {
  178. gdb_put_packet("T02");
  179. return;
  180. }
  181. gdb_continue();
  182. }