This repository was archived by the owner on Dec 23, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 51
Expand file tree
/
Copy pathgdb-server.h
More file actions
100 lines (79 loc) · 3.23 KB
/
gdb-server.h
File metadata and controls
100 lines (79 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <stdbool.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdlib.h>
/* opaque handle */
struct gdb_server;
/* front-end interface: create, destroy, run, and notify about memory access */
struct gdb_backend;
struct gdb_server *gdb_server_create(struct gdb_backend *backend, char *bindstr, bool stopped);
void gdb_server_free(struct gdb_server *gdb);
void gdb_server_step(struct gdb_server *gdb, volatile int *done);
void gdb_server_notify(struct gdb_server *gdb, unsigned long addr, unsigned int len, bool write);
/* use GNU C attributes when possible to mark format strings
this provides nice compile time feedback about using the right formats */
#ifdef __GNUC__
#define GDB_ATTR_FORMAT(archetype, fmt, arg) __attribute__ ((format (archetype, fmt, arg)))
#else
#define GDB_ATTR_FORMAT(archetype, fmt, arg)
#endif
/* writef and friends write big-endian numbers. for little-endian, use swaps */
#define gdb_swap_u16(v) (((v & 0xff) << 8) | ((v & 0xff00) >> 8))
#define gdb_swap_u32(v) ((gdb_swap_u16(v & 0xffff) << 16) | gdb_swap_u16((v & 0xffff0000) >> 16))
/* helpers for writing packets */
void gdb_writef(struct gdb_server *gdb, const char *fmt, ...) GDB_ATTR_FORMAT(printf, 2, 3);
void gdb_writefv(struct gdb_server *gdb, const char *fmt, va_list args);
/* helpers for parsing packets*/
struct gdb_packet {
/* note: buf[len] must be safe to access. last valid byte is buf[len-1] */
char *buf;
size_t len;
/* the character at buf[0], as buf[0] may be 0 temporarily */
char c;
};
#define gdb_packet_end(p) ((p)->len == 0)
#define gdb_packet_scanf(p, end, fmt, ...) _gdb_packet_scanf(p, end, fmt "%n", ##__VA_ARGS__, end)
bool _gdb_packet_scanf(struct gdb_packet *p, int *end, const char *fmt, ...) GDB_ATTR_FORMAT(scanf, 3, 4);
bool _gdb_packet_scanfv(struct gdb_packet *p, int *end, const char *fmt, va_list args);
/* backend interface */
struct gdb_monitor_cmd {
/* command name */
const char *cmd;
/* help text, first line should be summary */
const char *help;
/* handle command with arguments in p */
void (*handle)(void *ctx, struct gdb_server *gdb, struct gdb_packet *p);
};
struct gdb_backend {
void *ctx;
void (*free)(void *ctx);
/* target description xml */
const char *target_description;
/* manipulate the program counter
specifically: what instruction will run next */
unsigned long (*get_pc)(void *ctx);
void (*set_pc)(void *ctx, unsigned long addr);
/* get and set registers */
unsigned int register_max;
void (*get_reg)(void *ctx, struct gdb_server *gdb, unsigned int reg);
bool (*set_reg)(void *ctx, struct gdb_packet *p, unsigned int reg);
/* access memory */
uint8_t (*read_mem)(void *ctx, unsigned long addr);
void (*write_mem)(void *ctx, unsigned long addr, uint8_t val);
/* monitor commands, 0-terminated */
const struct gdb_monitor_cmd *commands;
};
/* backend factories */
#ifdef GDB_BACKEND_RV32
struct MiniRV32IMAState;
struct gdb_context_rv32 {
struct MiniRV32IMAState *cpu;
uint32_t (*read8)(uint32_t addr, uint32_t *trap, uint32_t *rval);
uint32_t (*write8)(uint32_t addr, uint32_t val, uint32_t *trap, uint32_t *rval);
};
struct gdb_backend *gdb_backend_rv32(struct gdb_context_rv32 *ctx);
#endif
#ifdef GDB_BACKEND_Z80
#include "libz80/z80.h"
struct gdb_backend *gdb_backend_z80(Z80Context *ctx);
#endif