| 1 | #ifndef GDBSTUB_COMMANDS_H |
| 2 | #define GDBSTUB_COMMANDS_H |
| 3 | |
| 4 | typedef void (*GdbCmdHandler)(GArray *params, void *user_ctx); |
| 5 | |
| 6 | typedef enum GDBThreadIdKind { |
| 7 | GDB_ONE_THREAD = 0, |
| 8 | GDB_ALL_THREADS, /* One process, all threads */ |
| 9 | GDB_ALL_PROCESSES, |
| 10 | GDB_READ_THREAD_ERR |
| 11 | } GDBThreadIdKind; |
| 12 | |
| 13 | typedef union GdbCmdVariant { |
| 14 | const char *data; |
| 15 | uint8_t opcode; |
| 16 | unsigned long val_ul; |
| 17 | unsigned long long val_ull; |
| 18 | struct { |
| 19 | GDBThreadIdKind kind; |
| 20 | uint32_t pid; |
| 21 | uint32_t tid; |
| 22 | } thread_id; |
| 23 | } GdbCmdVariant; |
| 24 | |
| 25 | #define gdb_get_cmd_param(p, i) (&g_array_index(p, GdbCmdVariant, i)) |
| 26 | |
| 27 | /** |
| 28 | * typedef GdbCmdParseEntry - gdb command parser |
| 29 | * |
| 30 | * This structure keeps the information necessary to match a gdb command, |
| 31 | * parse it (extract its parameters), and select the correct handler for it. |
| 32 | * |
| 33 | * @cmd: The command to be matched |
| 34 | * @cmd_startswith: If true, @cmd is compared using startswith |
| 35 | * @schema: Each schema for the command parameter entry consists of 2 chars, |
| 36 | * the first char represents the parameter type handling the second char |
| 37 | * represents the delimiter for the next parameter. |
| 38 | * |
| 39 | * Currently supported schema types: |
| 40 | * 'l' -> unsigned long (stored in .val_ul) |
| 41 | * 'L' -> unsigned long long (stored in .val_ull) |
| 42 | * 's' -> string (stored in .data) |
| 43 | * 'o' -> single char (stored in .opcode) |
| 44 | * 't' -> thread id (stored in .thread_id) |
| 45 | * '?' -> skip according to delimiter |
| 46 | * |
| 47 | * Currently supported delimiters: |
| 48 | * '?' -> Stop at any delimiter (",;:=\0") |
| 49 | * '0' -> Stop at "\0" |
| 50 | * '.' -> Skip 1 char unless reached "\0" |
| 51 | * Any other value is treated as the delimiter value itself |
| 52 | * |
| 53 | * @allow_stop_reply: True if the gdbstub can respond to this command with a |
| 54 | * "stop reply" packet. The list of commands that accept such response is |
| 55 | * defined at the GDB Remote Serial Protocol documentation. See: |
| 56 | * https://sourceware.org/gdb/onlinedocs/gdb/Stop-Reply-Packets.html#Stop-Reply-Packets. |
| 57 | * |
| 58 | * @need_cpu_context: Pass current CPU context to command handler via user_ctx. |
| 59 | */ |
| 60 | typedef struct GdbCmdParseEntry { |
| 61 | GdbCmdHandler handler; |
| 62 | const char *cmd; |
| 63 | bool cmd_startswith; |
| 64 | const char *schema; |
| 65 | bool allow_stop_reply; |
| 66 | bool need_cpu_context; |
| 67 | } GdbCmdParseEntry; |
| 68 | |
| 69 | /** |
| 70 | * gdb_put_packet() - put string into gdb server's buffer so it is sent |
| 71 | * to the client |
| 72 | */ |
| 73 | int gdb_put_packet(const char *buf); |
| 74 | |
| 75 | /** |
| 76 | * gdb_extend_query_table() - Extend query table. |
| 77 | * @table: GPtrArray of GdbCmdParseEntry entries. |
| 78 | * |
| 79 | * The caller should free @table afterwards |
| 80 | */ |
| 81 | void gdb_extend_query_table(GPtrArray *table); |
| 82 | |
| 83 | /** |
| 84 | * gdb_extend_set_table() - Extend set table. |
| 85 | * @table: GPtrArray of GdbCmdParseEntry entries. |
| 86 | * |
| 87 | * The caller should free @table afterwards |
| 88 | */ |
| 89 | void gdb_extend_set_table(GPtrArray *table); |
| 90 | |
| 91 | /** |
| 92 | * gdb_extend_qsupported_features() - Extend the qSupported features string. |
| 93 | * @qsupported_features: The additional qSupported feature(s) string. The string |
| 94 | * should start with a semicolon and, if there are more than one feature, the |
| 95 | * features should be separate by a semicolon. |
| 96 | * |
| 97 | * The caller should free @qsupported_features afterwards if |
| 98 | * dynamically allocated. |
| 99 | */ |
| 100 | void gdb_extend_qsupported_features(char *qsupported_features); |
| 101 | |
| 102 | /** |
| 103 | * Convert a hex string to bytes. Conversion is done per byte, so 2 hex digits |
| 104 | * are converted to 1 byte. Invalid hex digits are treated as 0 digits. |
| 105 | */ |
| 106 | void gdb_hextomem(GByteArray *mem, const char *buf, int len); |
| 107 | |
| 108 | #endif /* GDBSTUB_COMMANDS_H */ |