Alex Bennée | c566080 | 2023-03-02 18:57:57 -0800 | [diff] [blame] | 1 | /* |
| 2 | * GDB Syscall support |
| 3 | * |
| 4 | * Copyright (c) 2023 Linaro Ltd |
| 5 | * |
| 6 | * SPDX-License-Identifier: LGPL-2.0+ |
| 7 | */ |
| 8 | |
| 9 | #ifndef _SYSCALLS_H_ |
| 10 | #define _SYSCALLS_H_ |
| 11 | |
| 12 | /* For gdb file i/o remote protocol open flags. */ |
| 13 | #define GDB_O_RDONLY 0 |
| 14 | #define GDB_O_WRONLY 1 |
| 15 | #define GDB_O_RDWR 2 |
| 16 | #define GDB_O_APPEND 8 |
| 17 | #define GDB_O_CREAT 0x200 |
| 18 | #define GDB_O_TRUNC 0x400 |
| 19 | #define GDB_O_EXCL 0x800 |
| 20 | |
| 21 | /* For gdb file i/o remote protocol errno values */ |
| 22 | #define GDB_EPERM 1 |
| 23 | #define GDB_ENOENT 2 |
| 24 | #define GDB_EINTR 4 |
| 25 | #define GDB_EBADF 9 |
| 26 | #define GDB_EACCES 13 |
| 27 | #define GDB_EFAULT 14 |
| 28 | #define GDB_EBUSY 16 |
| 29 | #define GDB_EEXIST 17 |
| 30 | #define GDB_ENODEV 19 |
| 31 | #define GDB_ENOTDIR 20 |
| 32 | #define GDB_EISDIR 21 |
| 33 | #define GDB_EINVAL 22 |
| 34 | #define GDB_ENFILE 23 |
| 35 | #define GDB_EMFILE 24 |
| 36 | #define GDB_EFBIG 27 |
| 37 | #define GDB_ENOSPC 28 |
| 38 | #define GDB_ESPIPE 29 |
| 39 | #define GDB_EROFS 30 |
| 40 | #define GDB_ENAMETOOLONG 91 |
| 41 | #define GDB_EUNKNOWN 9999 |
| 42 | |
| 43 | /* For gdb file i/o remote protocol lseek whence. */ |
| 44 | #define GDB_SEEK_SET 0 |
| 45 | #define GDB_SEEK_CUR 1 |
| 46 | #define GDB_SEEK_END 2 |
| 47 | |
| 48 | /* For gdb file i/o stat/fstat. */ |
| 49 | typedef uint32_t gdb_mode_t; |
| 50 | typedef uint32_t gdb_time_t; |
| 51 | |
| 52 | struct gdb_stat { |
| 53 | uint32_t gdb_st_dev; /* device */ |
| 54 | uint32_t gdb_st_ino; /* inode */ |
| 55 | gdb_mode_t gdb_st_mode; /* protection */ |
| 56 | uint32_t gdb_st_nlink; /* number of hard links */ |
| 57 | uint32_t gdb_st_uid; /* user ID of owner */ |
| 58 | uint32_t gdb_st_gid; /* group ID of owner */ |
| 59 | uint32_t gdb_st_rdev; /* device type (if inode device) */ |
| 60 | uint64_t gdb_st_size; /* total size, in bytes */ |
| 61 | uint64_t gdb_st_blksize; /* blocksize for filesystem I/O */ |
| 62 | uint64_t gdb_st_blocks; /* number of blocks allocated */ |
| 63 | gdb_time_t gdb_st_atime; /* time of last access */ |
| 64 | gdb_time_t gdb_st_mtime; /* time of last modification */ |
| 65 | gdb_time_t gdb_st_ctime; /* time of last change */ |
| 66 | } QEMU_PACKED; |
| 67 | |
| 68 | struct gdb_timeval { |
| 69 | gdb_time_t tv_sec; /* second */ |
| 70 | uint64_t tv_usec; /* microsecond */ |
| 71 | } QEMU_PACKED; |
| 72 | |
| 73 | typedef void (*gdb_syscall_complete_cb)(CPUState *cpu, uint64_t ret, int err); |
| 74 | |
| 75 | /** |
| 76 | * gdb_do_syscall: |
| 77 | * @cb: function to call when the system call has completed |
| 78 | * @fmt: gdb syscall format string |
| 79 | * ...: list of arguments to interpolate into @fmt |
| 80 | * |
| 81 | * Send a GDB syscall request. This function will return immediately; |
| 82 | * the callback function will be called later when the remote system |
| 83 | * call has completed. |
| 84 | * |
| 85 | * @fmt should be in the 'call-id,parameter,parameter...' format documented |
| 86 | * for the F request packet in the GDB remote protocol. A limited set of |
| 87 | * printf-style format specifiers is supported: |
| 88 | * %x - target_ulong argument printed in hex |
| 89 | * %lx - 64-bit argument printed in hex |
| 90 | * %s - string pointer (target_ulong) and length (int) pair |
| 91 | */ |
| 92 | void gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...); |
| 93 | |
| 94 | /** |
Alex Bennée | c566080 | 2023-03-02 18:57:57 -0800 | [diff] [blame] | 95 | * use_gdb_syscalls() - report if GDB should be used for syscalls |
| 96 | * |
| 97 | * This is mostly driven by the semihosting mode the user configures |
| 98 | * but assuming GDB is allowed by that we report true if GDB is |
| 99 | * connected to the stub. |
| 100 | */ |
| 101 | int use_gdb_syscalls(void); |
| 102 | |
| 103 | /** |
| 104 | * gdb_exit: exit gdb session, reporting inferior status |
| 105 | * @code: exit code reported |
| 106 | * |
| 107 | * This closes the session and sends a final packet to GDB reporting |
| 108 | * the exit status of the program. It also cleans up any connections |
| 109 | * detritus before returning. |
| 110 | */ |
| 111 | void gdb_exit(int code); |
| 112 | |
| 113 | #endif /* _SYSCALLS_H_ */ |