Rizin
unix-like reverse engineering framework and cli tools
io_gdb.c File Reference
#include <rz_io.h>
#include <rz_lib.h>
#include <rz_socket.h>
#include <rz_util.h>
#include <ctype.h>
#include <libgdbr.h>
#include <gdbclient/commands.h>
#include <gdbclient/responses.h>

Go to the source code of this file.

Classes

struct  RzIOGdb
 

Macros

#define IRAPI   static inline
 
#define RZ_GDB_MAGIC   rz_str_djb2_hash("gdb")
 

Functions

static int __close (RzIODesc *fd)
 
static bool __plugin_open (RzIO *io, const char *file, bool many)
 
static int debug_gdb_read_at (ut8 *buf, int sz, ut64 addr)
 
static int debug_gdb_write_at (const ut8 *buf, int sz, ut64 addr)
 
static RzIODesc__open (RzIO *io, const char *file, int rw, int mode)
 
static int __write (RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
 
static ut64 __lseek (RzIO *io, RzIODesc *fd, ut64 offset, int whence)
 
static int __read (RzIO *io, RzIODesc *fd, ut8 *buf, int count)
 
static int __getpid (RzIODesc *fd)
 
static int __gettid (RzIODesc *fd)
 
int send_msg (libgdbr_t *g, const char *command)
 
int read_packet (libgdbr_t *instance, bool vcont)
 
static char * __system (RzIO *io, RzIODesc *fd, const char *cmd)
 

Variables

static libgdbr_tdesc = NULL
 
RzIOPlugin rz_io_plugin_gdb
 
RZ_API RzLibStruct rizin_plugin
 

Macro Definition Documentation

◆ IRAPI

#define IRAPI   static inline

Definition at line 9 of file io_gdb.c.

◆ RZ_GDB_MAGIC

#define RZ_GDB_MAGIC   rz_str_djb2_hash("gdb")

Definition at line 18 of file io_gdb.c.

Function Documentation

◆ __close()

static int __close ( RzIODesc fd)
static

Definition at line 167 of file io_gdb.c.

167  {
168  if (fd) {
169  RZ_FREE(fd->name);
170  }
173  RZ_FREE(desc);
174  return -1;
175 }
int gdbr_disconnect(libgdbr_t *g)
disconnects the lib
Definition: core.c:283
static libgdbr_t * desc
Definition: io_gdb.c:21
int gdbr_cleanup(libgdbr_t *g)
frees all buffers and cleans the libgdbr instance stuff
Definition: libgdbr.c:146
#define RZ_FREE(x)
Definition: rz_types.h:369
char * name
Definition: z80_tab.h:24
static const z80_opcode fd[]
Definition: z80_tab.h:997

References desc, fd, gdbr_cleanup(), gdbr_disconnect(), z80_opcode::name, and RZ_FREE.

Referenced by __open().

◆ __getpid()

static int __getpid ( RzIODesc fd)
static

Definition at line 177 of file io_gdb.c.

177  {
178  // XXX don't use globals
179  return desc ? desc->pid : -1;
180 #if 0
181  // dupe for ? rz_io_desc_get_pid (desc);
182  if (!desc || !desc->data) {
183  return -1;
184  }
185  RzIODescData *iodd = desc->data;
186  if (iodd) {
187  if (iodd->magic != RZ_GDB_MAGIC) {
188  return -1;
189  }
190  return iodd->pid;
191  }
192  return -1;
193 #endif
194 }
#define RZ_GDB_MAGIC
Definition: io_gdb.c:18
int pid
Definition: rz_io.h:109
ut64 magic
Definition: rz_io.h:108
char * data
Definition: libgdbr.h:171
int pid
Definition: libgdbr.h:176

References libgdbr_t::data, desc, RzIODescData::magic, RzIODescData::pid, libgdbr_t::pid, and RZ_GDB_MAGIC.

◆ __gettid()

static int __gettid ( RzIODesc fd)
static

Definition at line 196 of file io_gdb.c.

196  {
197  return desc ? desc->tid : -1;
198 }
int tid
Definition: libgdbr.h:177

References desc, and libgdbr_t::tid.

◆ __lseek()

static ut64 __lseek ( RzIO io,
RzIODesc fd,
ut64  offset,
int  whence 
)
static

Definition at line 141 of file io_gdb.c.

141  {
142  switch (whence) {
143  case RZ_IO_SEEK_SET:
144  io->off = offset;
145  break;
146  case RZ_IO_SEEK_CUR:
147  io->off += offset;
148  break;
149  case RZ_IO_SEEK_END:
150  io->off = ST64_MAX;
151  }
152  return io->off;
153 }
voidpf uLong offset
Definition: ioapi.h:144
#define RZ_IO_SEEK_CUR
Definition: rz_io.h:16
#define RZ_IO_SEEK_SET
Definition: rz_io.h:15
#define RZ_IO_SEEK_END
Definition: rz_io.h:17
#define ST64_MAX
Definition: rz_types_base.h:84
ut64 off
Definition: rz_io.h:61

References rz_io_t::off, RZ_IO_SEEK_CUR, RZ_IO_SEEK_END, RZ_IO_SEEK_SET, and ST64_MAX.

◆ __open()

static RzIODesc* __open ( RzIO io,
const char *  file,
int  rw,
int  mode 
)
static

Definition at line 54 of file io_gdb.c.

54  {
55  RzIODesc *riogdb = NULL;
56  RzIOGdb *riog;
57  char host[128], *port, *pid;
58  int i_port = -1;
59  bool isdev = false;
60 
61  if (!__plugin_open(io, file, 0)) {
62  return NULL;
63  }
64  strncpy(host, file + 6, sizeof(host) - 1);
65  host[sizeof(host) - 1] = '\0';
66  if (host[0] == '/') {
67  isdev = true;
68  }
69 
70  if (isdev) {
71  port = strchr(host, '@');
72  if (port) {
73  *port = '\0';
74  port++;
75  pid = strchr(port, ':');
76  } else {
77  pid = strchr(host, ':');
78  }
79  } else {
80  port = strchr(host, ':');
81  if (!port) {
82  eprintf("Invalid debugger URI. Port missing?\nPlease use either\n"
83  " - gdb://host:port[/pid] for a network gdbserver.\n"
84  " - gdb:///dev/DEVICENAME[@speed][:pid] for a serial gdbserver.\n");
85  return NULL;
86  }
87  *port = '\0';
88  port++;
89  pid = strchr(port, '/');
90  }
91 
92  int i_pid = -1;
93  if (pid) {
94  *pid = 0;
95  pid++;
96  i_pid = atoi(pid);
97  }
98 
99  if (port) {
100  i_port = atoi(port);
101  }
102 
103  if (!(riog = RZ_NEW0(RzIOGdb))) {
104  return NULL;
105  }
106  gdbr_init(&riog->desc, false);
107 
108  if (gdbr_connect(&riog->desc, host, i_port) == 0) {
109  __close(NULL);
110  // RZ_FREE (desc);
111  desc = &riog->desc;
112  if (pid > 0) { // FIXME this is here for now because RzDebug's pid and libgdbr's aren't properly synced.
113  desc->pid = i_pid;
114  if (gdbr_attach(desc, i_pid) < 0) {
115  eprintf("gdbr: Failed to attach to PID %i\n", i_pid);
116  return NULL;
117  }
118  } else if ((i_pid = desc->pid) < 0) {
119  i_pid = -1;
120  }
121  riogdb = rz_io_desc_new(io, &rz_io_plugin_gdb, file, RZ_PERM_RWX, mode, riog);
122  }
123  // Get name
124  if (riogdb) {
125  riogdb->name = gdbr_exec_file_read(desc, i_pid);
126  } else {
127  eprintf("gdb.io.open: Cannot connect to host.\n");
128  free(riog);
129  }
130  return riogdb;
131 }
int gdbr_connect(libgdbr_t *g, const char *server, int port)
Function connects to a gdbserver instance.
Definition: core.c:155
int gdbr_attach(libgdbr_t *g, int pid)
attaches to a process
Definition: core.c:439
char * gdbr_exec_file_read(libgdbr_t *g, int pid)
Definition: core.c:1635
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RzIOPlugin rz_io_plugin_gdb
Definition: io_gdb.c:410
static bool __plugin_open(RzIO *io, const char *file, bool many)
Definition: io_gdb.c:23
static int __close(RzIODesc *fd)
Definition: io_gdb.c:167
const char int mode
Definition: ioapi.h:137
int gdbr_init(libgdbr_t *g, bool is_server)
Function initializes the libgdbr lib.
Definition: libgdbr.c:9
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc pid
Definition: sflib.h:64
#define eprintf(x, y...)
Definition: rlcc.c:7
RZ_API RzIODesc * rz_io_desc_new(RzIO *io, RzIOPlugin *plugin, const char *uri, int flags, int mode, void *data)
Definition: io_desc.c:11
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RWX
Definition: rz_types.h:98
libgdbr_t desc
Definition: debug_gdb.c:11
Definition: gzappend.c:170
char * name
Definition: rz_io.h:99

References __close(), __plugin_open(), RzIOGdb::desc, desc, eprintf, free(), gdbr_attach(), gdbr_connect(), gdbr_exec_file_read(), gdbr_init(), rz_io_desc_t::name, NULL, pid, libgdbr_t::pid, rz_io_desc_new(), rz_io_plugin_gdb, RZ_NEW0, and RZ_PERM_RWX.

◆ __plugin_open()

static bool __plugin_open ( RzIO io,
const char *  file,
bool  many 
)
static

Definition at line 23 of file io_gdb.c.

23  {
24  return (!strncmp(file, "gdb://", 6));
25 }

Referenced by __open().

◆ __read()

static int __read ( RzIO io,
RzIODesc fd,
ut8 buf,
int  count 
)
static

Definition at line 155 of file io_gdb.c.

155  {
156  if (!io || !fd || !buf || count < 1) {
157  return -1;
158  }
159  memset(buf, 0xff, count);
160  ut64 addr = io->off;
161  if (!desc || !desc->data) {
162  return -1;
163  }
164  return debug_gdb_read_at(buf, count, addr);
165 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static int debug_gdb_read_at(ut8 *buf, int sz, ut64 addr)
Definition: io_gdb.c:27
voidpf void * buf
Definition: ioapi.h:138
return memset(p, 0, total)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58

References addr, count, libgdbr_t::data, debug_gdb_read_at(), desc, fd, memset(), rz_io_t::off, and ut64().

◆ __system()

static char* __system ( RzIO io,
RzIODesc fd,
const char *  cmd 
)
static

Definition at line 203 of file io_gdb.c.

203  {
204  if (!desc) {
205  return NULL;
206  }
207  if (!*cmd) {
208  return NULL;
209  }
210  if (cmd[0] == '?' || !strcmp(cmd, "help")) {
211  eprintf("Usage: R!cmd args\n"
212  " R!pid - show targeted pid\n"
213  " R!pkt s - send packet 's'\n"
214  " R!rd - show reverse debugging availability\n"
215  " R!dsb - step backwards\n"
216  " R!dcb - continue backwards\n"
217  " R!monitor cmd - hex-encode monitor command and pass"
218  " to target interpreter\n"
219  " R!detach [pid] - detach from remote/detach specific pid\n"
220  " R!inv.reg - invalidate reg cache\n"
221  " R!pktsz - get max packet size used\n"
222  " R!pktsz bytes - set max. packet size as 'bytes' bytes\n"
223  " R!exec_file [pid] - get file which was executed for"
224  " current/specified pid\n");
225  return NULL;
226  }
227  if (rz_str_startswith(cmd, "pktsz")) {
228  const char *ptr = rz_str_trim_head_ro(cmd + 5);
229  if (!isdigit((ut8)*ptr)) {
230  io->cb_printf("packet size: %u bytes\n",
232  return NULL;
233  }
234  ut32 pktsz;
235  if (!(pktsz = (ut32)strtoul(ptr, NULL, 10))) {
236  // pktsz = 0 doesn't make sense
237  return NULL;
238  }
239  desc->stub_features.pkt_sz = RZ_MAX(pktsz, 8); // min = 64
240  return NULL;
241  }
242  if (rz_str_startswith(cmd, "detach")) {
243  int res;
244  if (!isspace((ut8)cmd[6]) || !desc->stub_features.multiprocess) {
245  res = gdbr_detach(desc) >= 0;
246  } else {
247  int pid = 0;
248  cmd = rz_str_trim_head_ro(cmd + 6);
249  if (!*cmd || !(pid = strtoul(cmd, NULL, 10))) {
250  res = gdbr_detach(desc) >= 0;
251  } else {
252  res = gdbr_detach_pid(desc, pid) >= 0;
253  }
254  }
255  eprintf("%d\n", res);
256  return NULL;
257  }
258  if (rz_str_startswith(cmd, "pkt ")) {
259  if (!gdbr_lock_enter(desc)) {
260  goto gdb_lock_leave;
261  }
262  if (send_msg(desc, cmd + 4) >= 0) {
263  (void)read_packet(desc, false);
264  desc->data[desc->data_len] = '\0';
265  io->cb_printf("reply:\n%s\n", desc->data);
266  if (!desc->no_ack) {
267  eprintf("[waiting for ack]\n");
268  }
269  }
270  goto gdb_lock_leave;
271  }
272  if (rz_str_startswith(cmd, "rd")) {
273  PJ *pj = pj_new();
274  pj_o(pj);
275  pj_kb(pj, "reverse-continue", desc->stub_features.ReverseStep);
276  pj_kb(pj, "reverse-step", desc->stub_features.ReverseContinue);
277  pj_end(pj);
278  io->cb_printf("%s\n", pj_string(pj));
279  pj_free(pj);
280  return NULL;
281  }
282  if (rz_str_startswith(cmd, "dsb")) {
284  eprintf("Stepping backwards is not supported in this gdbserver implementation\n");
285  return NULL;
286  }
287  if (!gdbr_lock_enter(desc)) {
288  goto gdb_lock_leave;
289  }
290  if (send_msg(desc, "bs") >= 0) {
291  (void)read_packet(desc, false);
292  desc->data[desc->data_len] = '\0';
293  if (!desc->no_ack) {
294  eprintf("[waiting for ack]\n");
295  } else {
297  if (desc->stop_reason.is_valid == false) {
298  eprintf("Thread (%d) stopped for an invalid reason: %d\n",
300  }
301  }
303  }
304  goto gdb_lock_leave;
305  }
306  if (rz_str_startswith(cmd, "dcb")) {
308  eprintf("Continue backwards is not supported in this gdbserver implementation\n");
309  return NULL;
310  }
311  if (!gdbr_lock_enter(desc)) {
312  goto gdb_lock_leave;
313  }
314  if (send_msg(desc, "bc") >= 0) {
315  (void)read_packet(desc, false);
316  desc->data[desc->data_len] = '\0';
317  if (!desc->no_ack) {
318  eprintf("[waiting for ack]\n");
319  } else {
321  if (desc->stop_reason.is_valid == false) {
322  eprintf("Thread (%d) stopped for an invalid reason: %d\n",
324  }
325  }
327  }
328  goto gdb_lock_leave;
329  }
330  if (rz_str_startswith(cmd, "pid")) {
331  int pid = desc ? desc->pid : -1;
332  if (!cmd[3]) {
333  io->cb_printf("%d\n", pid);
334  }
335  return rz_str_newf("%d", pid);
336  }
337  if (rz_str_startswith(cmd, "monitor")) {
338  const char *qrcmd = cmd + 8;
339  if (!isspace((ut8)cmd[7])) {
340  qrcmd = "help";
341  }
342  if (gdbr_send_qRcmd(desc, qrcmd, io->cb_printf) < 0) {
343  eprintf("remote error\n");
344  return NULL;
345  }
346  return NULL;
347  }
348  if (rz_str_startswith(cmd, "inv.reg")) {
350  return NULL;
351  }
352  if (rz_str_startswith(cmd, "exec_file")) {
353  const char *ptr = cmd + strlen("exec_file");
354  char *file;
355  if (!isspace((ut8)*ptr)) {
357  } else {
358  while (isspace((ut8)*ptr)) {
359  ptr++;
360  }
361  if (isdigit((ut8)*ptr)) {
362  int pid = atoi(ptr);
364  } else {
366  }
367  }
368  if (!file) {
369  return NULL;
370  }
371  io->cb_printf("%s\n", file);
372  return file;
373  }
374  // These are internal, not available to user directly
375  if (rz_str_startswith(cmd, "retries")) {
376  int num_retries;
377  if (isspace((ut8)cmd[7]) && isdigit((ut8)cmd[8])) {
378  if ((num_retries = atoi(cmd + 8)) >= 1) {
379  desc->num_retries = num_retries;
380  }
381  return NULL;
382  }
383  io->cb_printf("num_retries: %d byte(s)\n", desc->page_size);
384  return NULL;
385  }
386  if (rz_str_startswith(cmd, "page_size")) {
387  int page_size;
388  if (isspace((ut8)cmd[9]) && isdigit((ut8)cmd[10])) {
389  if ((page_size = atoi(cmd + 10)) >= 64) {
390  desc->page_size = page_size;
391  }
392  return NULL;
393  }
394  io->cb_printf("page size: %d byte(s)\n", desc->page_size);
395  return NULL;
396  }
397  // Sets a flag that next call to get memmap will be for getting baddr
398  if (!strcmp(cmd, "baddr")) {
399  desc->get_baddr = true;
400  return NULL;
401  }
402  eprintf("Try: 'R!?'\n");
403  return NULL;
404 
405 gdb_lock_leave:
407  return NULL;
408 }
int gdbr_detach(libgdbr_t *g)
detaches from a process
Definition: core.c:495
bool gdbr_lock_enter(libgdbr_t *g)
Acquires the gdbr lock and sets up breaking.
Definition: core.c:105
void gdbr_lock_leave(libgdbr_t *g)
Releases the gdbr lock.
Definition: core.c:117
int gdbr_detach_pid(libgdbr_t *g, int pid)
Definition: core.c:520
void gdbr_invalidate_reg_cache(void)
invalidates the reg cache
Definition: core.c:1570
int gdbr_send_qRcmd(libgdbr_t *g, const char *cmd, PrintfCallback cb_printf)
sends a qRcmd packet which basically passes a command to the remote target's interpreter.
Definition: core.c:1574
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
uint32_t ut32
int read_packet(libgdbr_t *instance, bool vcont)
Definition: packet.c:143
int send_msg(libgdbr_t *g, const char *command)
Definition: common.c:146
uint8_t ut8
Definition: lh5801.h:11
int handle_stop_reason(libgdbr_t *g)
Definition: responses.c:244
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API PJ * pj_kb(PJ *j, const char *k, bool v)
Definition: pj.c:177
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definition: str_trim.c:86
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286
#define RZ_MAX(x, y)
#define isspace(c)
Definition: safe-ctype.h:141
#define isdigit(c)
Definition: safe-ctype.h:131
struct libgdbr_stop_reason::@441 thread
bool get_baddr
Definition: libgdbr.h:189
int page_size
Definition: libgdbr.h:178
bool no_ack
Definition: libgdbr.h:186
ssize_t data_len
Definition: libgdbr.h:172
libgdbr_stop_reason_t stop_reason
Definition: libgdbr.h:190
libgdbr_stub_features_t stub_features
Definition: libgdbr.h:180
int num_retries
Definition: libgdbr.h:183
Definition: rz_pj.h:12
PrintfCallback cb_printf
Definition: rz_io.h:91
static int file
Definition: z80asm.c:58

References rz_io_t::cb_printf, cmd, libgdbr_t::data, libgdbr_t::data_len, desc, eprintf, file, gdbr_detach(), gdbr_detach_pid(), gdbr_exec_file_read(), gdbr_invalidate_reg_cache(), gdbr_lock_enter(), gdbr_lock_leave(), gdbr_send_qRcmd(), libgdbr_t::get_baddr, handle_stop_reason(), libgdbr_stop_reason::is_valid, isdigit, isspace, libgdbr_stub_features_t::multiprocess, libgdbr_t::no_ack, NULL, libgdbr_t::num_retries, libgdbr_t::page_size, pid, libgdbr_t::pid, pj_end(), pj_free(), pj_kb(), pj_new(), pj_o(), pj_string(), libgdbr_stub_features_t::pkt_sz, read_packet(), libgdbr_stop_reason::reason, libgdbr_stub_features_t::ReverseContinue, libgdbr_stub_features_t::ReverseStep, RZ_MAX, rz_str_newf(), rz_str_startswith(), rz_str_trim_head_ro(), send_msg(), libgdbr_t::stop_reason, libgdbr_t::stub_features, libgdbr_stop_reason::thread, and libgdbr_stop_reason::tid.

◆ __write()

static int __write ( RzIO io,
RzIODesc fd,
const ut8 buf,
int  count 
)
static

Definition at line 133 of file io_gdb.c.

133  {
134  ut64 addr = io->off;
135  if (!desc || !desc->data) {
136  return -1;
137  }
138  return debug_gdb_write_at(buf, count, addr);
139 }
static int debug_gdb_write_at(const ut8 *buf, int sz, ut64 addr)
Definition: io_gdb.c:34

References addr, count, libgdbr_t::data, debug_gdb_write_at(), desc, rz_io_t::off, and ut64().

◆ debug_gdb_read_at()

static int debug_gdb_read_at ( ut8 buf,
int  sz,
ut64  addr 
)
static

Definition at line 27 of file io_gdb.c.

27  {
28  if (sz < 1 || addr >= UT64_MAX || !desc) {
29  return -1;
30  }
31  return gdbr_read_memory(desc, addr, buf, sz);
32 }
int gdbr_read_memory(libgdbr_t *g, ut64 address, ut8 *buf, int len)
Definition: core.c:812
#define UT64_MAX
Definition: rz_types_base.h:86

References addr, desc, gdbr_read_memory(), and UT64_MAX.

Referenced by __read().

◆ debug_gdb_write_at()

static int debug_gdb_write_at ( const ut8 buf,
int  sz,
ut64  addr 
)
static

Definition at line 34 of file io_gdb.c.

34  {
35  ut32 x, size_max;
36  ut32 packets;
37  ut32 last;
38  if (sz < 1 || addr >= UT64_MAX || !desc) {
39  return -1;
40  }
41  size_max = desc->read_max;
42  packets = sz / size_max;
43  last = sz % size_max;
44  ut64 offset = 0;
45  for (x = 0; x < packets; x++, offset += size_max) {
46  gdbr_write_memory(desc, addr + offset, buf + offset, size_max);
47  }
48  if (last) {
50  }
51  return sz;
52 }
int gdbr_write_memory(libgdbr_t *g, ut64 address, const uint8_t *data, ut64 len)
Definition: core.c:860
int x
Definition: mipsasm.c:20
ssize_t read_max
Definition: libgdbr.h:164

References addr, desc, gdbr_write_memory(), libgdbr_t::read_max, ut64(), UT64_MAX, and x.

Referenced by __write().

◆ read_packet()

int read_packet ( libgdbr_t instance,
bool  vcont 
)

Definition at line 143 of file packet.c.

143  {
144  struct parse_ctx ctx = { 0 };
145  int ret, i;
146  if (!g) {
147  eprintf("Initialize libgdbr_t first\n");
148  return -1;
149  }
150  g->data_len = 0;
151  if (g->read_len > 0) {
152  if (unpack(g, &ctx, g->read_len) == 0) {
153  // TODO: Evaluate if partial packets are clubbed
154  g->data[g->data_len] = '\0';
155  if (g->server_debug) {
156  eprintf("getpkt (\"%s\"); %s\n", g->data,
157  g->no_ack ? "[no ack sent]" : "[sending ack]");
158  }
159  return 0;
160  }
161  }
162  g->data_len = 0;
163  for (i = 0; i < g->num_retries && !g->isbreaked; vcont ? 0 : i++) {
164  ret = rz_socket_ready(g->sock, 0, READ_TIMEOUT);
165  if (ret == 0 && !vcont) {
166  continue;
167  }
168  if (ret <= 0) {
169  return -1;
170  }
171  int sz = rz_socket_read(g->sock, (void *)g->read_buff, g->read_max - 1);
172  if (sz <= 0) {
173  eprintf("%s: read failed\n", __func__);
174  return -1;
175  }
176  ret = unpack(g, &ctx, sz);
177  if (ret < 0) {
178  eprintf("%s: unpack failed\n", __func__);
179  return -1;
180  }
181  if (!ret) {
182  g->data[g->data_len] = '\0';
183  if (g->server_debug) {
184  eprintf("getpkt (\"%s\"); %s\n", g->data,
185  g->no_ack ? "[no ack sent]" : "[sending ack]");
186  }
187  return 0;
188  }
189  }
190  return -1;
191 }
lzma_index ** i
Definition: index.h:629
struct @667 g
RZ_API int rz_socket_ready(RzSocket *s, int secs, int usecs)
Definition: socket.c:688
RZ_API void RZ_API int rz_socket_read(RzSocket *s, ut8 *read, int len)
Definition: socket.c:783
#define READ_TIMEOUT
Definition: packet.c:7
static int unpack(libgdbr_t *g, struct parse_ctx *ctx, int len)
Definition: packet.c:43

References eprintf, g, i, READ_TIMEOUT, rz_socket_read(), rz_socket_ready(), and unpack().

Referenced by __system(), gdbr_attach(), gdbr_check_extended_mode(), gdbr_check_vcont(), gdbr_close_file(), gdbr_connect(), gdbr_connect_lldb(), gdbr_detach_pid(), gdbr_exec_file_read(), gdbr_get_baddr(), gdbr_is_thread_dead(), gdbr_kill_pid(), gdbr_open_file(), gdbr_pids_list(), gdbr_read_feature(), gdbr_read_file(), gdbr_read_memory_page(), gdbr_read_osdata(), gdbr_read_registers(), gdbr_read_registers_lldb(), gdbr_select(), gdbr_send_qRcmd(), gdbr_server_serve(), gdbr_stop_reason(), gdbr_threads_list(), gdbr_write_bin_registers(), gdbr_write_memory(), gdbr_write_register(), gdbr_write_registers(), remove_bp(), send_vcont(), set_bp(), and test_command().

◆ send_msg()

int send_msg ( libgdbr_t g,
const char *  command 
)

Definition at line 146 of file common.c.

146  {
147  int ret;
148  if (!g || !msg) {
149  return -1;
150  }
151  ret = pack(g, msg);
152  if (ret < 0) {
153  return -1;
154  }
155  ret = send_packet(g);
156  g->send_len = ret;
157  return ret;
158 }
int send_packet(libgdbr_t *g)
sends a packet sends a packet to the established connection
Definition: packet.c:193
int pack(libgdbr_t *g, const char *msg)
Definition: packet.c:206
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119

References g, msg, pack(), and send_packet().

Referenced by __system(), _server_handle_c(), _server_handle_exec_file_read(), _server_handle_g(), _server_handle_Hc(), _server_handle_Hg(), _server_handle_M(), _server_handle_m(), _server_handle_p(), _server_handle_P(), _server_handle_qAttached(), _server_handle_qC(), _server_handle_qfThreadInfo(), _server_handle_qOffsets(), _server_handle_qsThreadInfo(), _server_handle_qSupported(), _server_handle_qTfV(), _server_handle_qTStatus(), _server_handle_ques(), _server_handle_s(), _server_handle_vCont(), _server_handle_vKill(), _server_handle_vMustReplyEmpty(), _server_handle_z(), gdbr_attach(), gdbr_check_extended_mode(), gdbr_check_vcont(), gdbr_close_file(), gdbr_connect(), gdbr_connect_lldb(), gdbr_detach(), gdbr_detach_pid(), gdbr_exec_file_read(), gdbr_get_baddr(), gdbr_is_thread_dead(), gdbr_kill(), gdbr_kill_pid(), gdbr_open_file(), gdbr_pids_list(), gdbr_read_feature(), gdbr_read_file(), gdbr_read_memory_page(), gdbr_read_osdata(), gdbr_read_registers(), gdbr_read_registers_lldb(), gdbr_select(), gdbr_send_qRcmd(), gdbr_server_serve(), gdbr_stop_reason(), gdbr_threads_list(), gdbr_write_bin_registers(), gdbr_write_memory(), gdbr_write_register(), gdbr_write_registers(), remove_bp(), send_vcont(), set_bp(), and test_command().

Variable Documentation

◆ desc

libgdbr_t* desc = NULL
static

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
.type = RZ_LIB_TYPE_IO,
.data = &rz_io_plugin_gdb,
}
@ RZ_LIB_TYPE_IO
Definition: rz_lib.h:69
#define RZ_VERSION
Definition: rz_version.h:8
const char * version
Definition: rz_io.h:117

Definition at line 429 of file io_gdb.c.

◆ rz_io_plugin_gdb

RzIOPlugin rz_io_plugin_gdb
Initial value:
= {
.name = "gdb",
.license = "LGPL3",
.desc = "Attach to gdbserver instance",
.uris = "gdb://",
.open = __open,
.close = __close,
.read = __read,
.write = __write,
.check = __plugin_open,
.lseek = __lseek,
.system = __system,
.getpid = __getpid,
.gettid = __gettid,
.isdbg = true
}
static int __read(RzIO *io, RzIODesc *fd, ut8 *buf, int count)
Definition: io_gdb.c:155
static int __gettid(RzIODesc *fd)
Definition: io_gdb.c:196
static RzIODesc * __open(RzIO *io, const char *file, int rw, int mode)
Definition: io_gdb.c:54
static int __write(RzIO *io, RzIODesc *fd, const ut8 *buf, int count)
Definition: io_gdb.c:133
static ut64 __lseek(RzIO *io, RzIODesc *fd, ut64 offset, int whence)
Definition: io_gdb.c:141
static char * __system(RzIO *io, RzIODesc *fd, const char *cmd)
Definition: io_gdb.c:203
static int __getpid(RzIODesc *fd)
Definition: io_gdb.c:177

Definition at line 410 of file io_gdb.c.

Referenced by __open().