Rizin
unix-like reverse engineering framework and cli tools
debug_gdb.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2009-2018 pancake <pancake@nopcode.org>
2 // SPDX-FileCopyrightText: 2009-2018 defragger <rlaemmert@gmail.com>
3 // SPDX-License-Identifier: LGPL-3.0-only
4 
5 #include <rz_core.h>
6 #include <rz_debug.h>
7 #include <libgdbr.h>
8 #include <gdbclient/commands.h>
9 
10 typedef struct {
12 } RzIOGdb;
13 
14 #define UNKNOWN (-1)
15 #define UNSUPPORTED 0
16 #define SUPPORTED 1
17 
18 typedef struct rz_debug_gdb_ctx_t {
22  int buf_size;
26 
27 static bool rz_debug_gdb_init(RzDebug *dbg, void **user) {
29  if (!ctx) {
30  return false;
31  }
32  ctx->support_sw_bp = UNKNOWN;
33  ctx->support_hw_bp = UNKNOWN;
34  *user = ctx;
35  return true;
36 }
37 
38 static void rz_debug_gdb_fini(RzDebug *dbg, void *user) {
39  RzDebugGdbCtx *ctx = user;
40  free(ctx);
41 }
42 
43 static int rz_debug_gdb_attach(RzDebug *dbg, int pid);
44 static void check_connection(RzDebug *dbg) {
46  if (!ctx->desc) {
48  }
49 }
50 
54  if (!ctx->desc) {
56  }
57  gdbr_step(ctx->desc, dbg->tid);
58  return true;
59 }
60 
63  RzList *list;
64  if ((list = gdbr_threads_list(ctx->desc, pid))) {
66  }
67  return list;
68 }
69 
72  RzList *list;
73  if ((list = gdbr_pids_list(ctx->desc, pid))) {
75  }
76  return list;
77 }
78 
79 static int rz_debug_gdb_reg_read(RzDebug *dbg, int type, ut8 *buf, int size) {
81  int copy_size;
82  int buflen = 0;
84  if (!ctx->desc) {
86  }
87  gdbr_read_registers(ctx->desc);
88  if (!ctx->desc || !ctx->desc->data) {
89  return -1;
90  }
91  // read the len of the current area
93  if (size < ctx->desc->data_len) {
94  eprintf("rz_debug_gdb_reg_read: small buffer %d vs %d\n",
95  (int)size, (int)ctx->desc->data_len);
96  // return -1;
97  }
98  copy_size = RZ_MIN(ctx->desc->data_len, size);
99  buflen = RZ_MAX(ctx->desc->data_len, buflen);
100  if (ctx->reg_buf) {
101  // if (buf_size < copy_size) { //desc->data_len) {
102  if (buflen > ctx->buf_size) { // copy_size) {
103  ut8 *new_buf = realloc(ctx->reg_buf, buflen);
104  if (!new_buf) {
105  return -1;
106  }
107  ctx->reg_buf = new_buf;
108  ctx->buf_size = buflen;
109  }
110  } else {
111  ctx->reg_buf = calloc(buflen, 1);
112  if (!ctx->reg_buf) {
113  return -1;
114  }
115  ctx->buf_size = buflen;
116  }
117  memset((void *)(volatile void *)buf, 0, size);
118  memcpy((void *)(volatile void *)buf, ctx->desc->data, RZ_MIN(copy_size, size));
119  memset((void *)(volatile void *)ctx->reg_buf, 0, buflen);
120  memcpy((void *)(volatile void *)ctx->reg_buf, ctx->desc->data, copy_size);
121 #if 0
122  int i;
123  //for(i=0;i<168;i++) {
124  for(i=0;i<copy_size;i++) {
125  if (!(i%16)) printf ("\n0x%08x ", i);
126  printf ("%02x ", buf[i]); //(ut8)desc->data[i]);
127  }
128  printf("\n");
129 #endif
130  return ctx->desc->data_len;
131 }
132 
136  if (!ctx->desc || ctx->desc->pid <= 0) {
137  return NULL;
138  }
139  RzList *retlist = NULL;
140  if (ctx->desc->get_baddr) {
141  ctx->desc->get_baddr = false;
142  ut64 baddr;
143  if ((baddr = gdbr_get_baddr(ctx->desc)) != UINT64_MAX) {
144  if (!(retlist = rz_list_new())) {
145  return NULL;
146  }
147  RzDebugMap *map;
148  if (!(map = rz_debug_map_new("", baddr, baddr, RZ_PERM_RX, 0))) {
149  rz_list_free(retlist);
150  return NULL;
151  }
152  rz_list_append(retlist, map);
153  return retlist;
154  }
155  }
156 
157  // Get file from GDB
158  char path[128];
159  ut8 *buf;
160  int ret;
161  // TODO don't hardcode buffer size, get from remote target
162  // (I think gdb doesn't do that, it just keeps reading till EOF)
163  // fstat info can get file size, but it doesn't work for /proc/pid/maps
164  ut64 buflen = 16384;
165  // If /proc/%d/maps is not valid for gdbserver, we return NULL, as of now
166  snprintf(path, sizeof(path) - 1, "/proc/%d/maps", ctx->desc->pid);
167 
168 #ifdef _MSC_VER
169 #define GDB_FILE_OPEN_MODE (_S_IREAD | _S_IWRITE)
170 #else
171 #define GDB_FILE_OPEN_MODE (S_IRUSR | S_IWUSR | S_IXUSR)
172 #endif
173 
174  if (gdbr_open_file(ctx->desc, path, O_RDONLY, GDB_FILE_OPEN_MODE) < 0) {
175  return NULL;
176  }
177  if (!(buf = malloc(buflen))) {
178  gdbr_close_file(ctx->desc);
179  return NULL;
180  }
181  if ((ret = gdbr_read_file(ctx->desc, buf, buflen - 1)) <= 0) {
182  gdbr_close_file(ctx->desc);
183  free(buf);
184  return NULL;
185  }
186  buf[ret] = '\0';
187 
188  // Get map list
189  int unk = 0, perm, i;
190  char *ptr, *pos_1;
191  size_t line_len;
192  char name[1024], region1[100], region2[100], perms[5];
193  RzDebugMap *map = NULL;
194  region1[0] = region2[0] = '0';
195  region1[1] = region2[1] = 'x';
196  if (!(ptr = strtok((char *)buf, "\n"))) {
197  gdbr_close_file(ctx->desc);
198  free(buf);
199  return NULL;
200  }
201  if (!(retlist = rz_list_new())) {
202  gdbr_close_file(ctx->desc);
203  free(buf);
204  return NULL;
205  }
206  while (ptr) {
207  ut64 map_start, map_end, offset;
208  bool map_is_shared = false;
209  line_len = strlen(ptr);
210  // maps files should not have empty lines
211  if (line_len == 0) {
212  break;
213  }
214  // We assume Linux target, for now, so -
215  // 7ffff7dda000-7ffff7dfd000 r-xp 00000000 08:05 265428 /usr/lib/ld-2.25.so
216  ret = sscanf(ptr, "%s %s %" PFMT64x " %*s %*s %[^\n]", &region1[2],
217  perms, &offset, name);
218  if (ret == 3) {
219  name[0] = '\0';
220  } else if (ret != 4) {
221  eprintf("%s: Unable to parse \"%s\"\nContent:\n%s\n",
222  __func__, path, buf);
223  gdbr_close_file(ctx->desc);
224  free(buf);
225  rz_list_free(retlist);
226  return NULL;
227  }
228  if (!(pos_1 = strchr(&region1[2], '-'))) {
229  ptr = strtok(NULL, "\n");
230  continue;
231  }
232  strncpy(&region2[2], pos_1 + 1, sizeof(region2) - 2 - 1);
233  if (!*name) {
234  snprintf(name, sizeof(name), "unk%d", unk++);
235  }
236  perm = 0;
237  for (i = 0; i < 5 && perms[i]; i++) {
238  switch (perms[i]) {
239  case 'r': perm |= RZ_PERM_R; break;
240  case 'w': perm |= RZ_PERM_W; break;
241  case 'x': perm |= RZ_PERM_X; break;
242  case 'p': map_is_shared = false; break;
243  case 's': map_is_shared = true; break;
244  }
245  }
246  map_start = rz_num_get(NULL, region1);
247  map_end = rz_num_get(NULL, region2);
248  if (map_start == map_end || map_end == 0) {
249  eprintf("%s: ignoring invalid map size: %s - %s\n",
250  __func__, region1, region2);
251  ptr = strtok(NULL, "\n");
252  continue;
253  }
254  if (!(map = rz_debug_map_new(name, map_start, map_end, perm, 0))) {
255  break;
256  }
257  map->offset = offset;
258  map->shared = map_is_shared;
259  map->file = strdup(name);
260  rz_list_append(retlist, map);
261  ptr = strtok(NULL, "\n");
262  }
263  gdbr_close_file(ctx->desc);
264  free(buf);
265  return retlist;
266 }
267 
269  char *lastname = NULL;
270  RzDebugMap *map;
271  RzListIter *iter, *iter2;
272  RzList *list, *last;
273  bool must_delete;
274  if (!(list = rz_debug_gdb_map_get(dbg))) {
275  return NULL;
276  }
277  if (!(last = rz_list_newf((RzListFree)rz_debug_map_free))) {
279  return NULL;
280  }
281  rz_list_foreach_safe (list, iter, iter2, map) {
282  const char *file = map->file;
283  if (!map->file) {
284  file = map->file = strdup(map->name);
285  }
286  must_delete = true;
287  if (file && *file == '/') {
288  if (!lastname || strcmp(lastname, file)) {
289  must_delete = false;
290  }
291  }
292  if (must_delete) {
294  } else {
295  rz_list_append(last, map);
296  free(lastname);
297  lastname = strdup(file);
298  }
299  }
300  list->free = NULL;
301  free(lastname);
303  return last;
304 }
305 
306 static int rz_debug_gdb_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size) {
309  if (!ctx->desc) {
311  }
312  if (!ctx->reg_buf) {
313  // we cannot write registers before we once read them
314  return -1;
315  }
316  int buflen = 0;
317  int bits = dbg->analysis->bits;
318  const char *pcname = rz_reg_get_name(dbg->analysis->reg, RZ_REG_NAME_PC);
319  RzRegItem *reg = rz_reg_get(dbg->analysis->reg, pcname, 0);
320  if (reg) {
321  if (dbg->analysis->bits != reg->size) {
322  bits = reg->size;
323  }
324  }
326  // some implementations of the gdb protocol are acting weird.
327  // so winedbg is not able to write registers through the <G> packet
328  // and also it does not return the whole gdb register profile after
329  // calling <g>
330  // so this workaround resizes the small register profile buffer
331  // to the whole set and fills the rest with 0
332  if (ctx->buf_size < buflen) {
333  ut8 *new_buf = realloc(ctx->reg_buf, buflen * sizeof(ut8));
334  if (!new_buf) {
335  return -1;
336  }
337  ctx->reg_buf = new_buf;
338  memset(new_buf + ctx->buf_size, 0, buflen - ctx->buf_size);
339  }
340 
341  RzRegItem *current = NULL;
342  // We default to little endian if there's no way to get the configuration,
343  // since this was the behaviour prior to the change.
344  RzRegArena *arena = dbg->reg->regset[type].arena;
345  for (;;) {
346  current = rz_reg_next_diff(dbg->reg, type, ctx->reg_buf, buflen, current, bits);
347  if (!current) {
348  break;
349  }
350  gdbr_write_reg(ctx->desc, current->name, (char *)arena->bytes + (current->offset / 8), current->size / 8);
351  }
352  return true;
353 }
354 
355 static int rz_debug_gdb_continue(RzDebug *dbg, int pid, int tid, int sig) {
358  if (!ctx->desc) {
360  }
361  gdbr_continue(ctx->desc, pid, -1, sig); // Continue all threads
362  if (ctx->desc->stop_reason.is_valid && ctx->desc->stop_reason.thread.present) {
363  // if (desc->tid != desc->stop_reason.thread.tid) {
364  // eprintf ("thread id (%d) in reason differs from current thread id (%d)\n", dbg->pid, dbg->tid);
365  // }
366  ctx->desc->tid = ctx->desc->stop_reason.thread.tid;
367  }
368  return ctx->desc->tid;
369 }
370 
374  if (!ctx->desc) {
376  }
377  if (!ctx->desc->stop_reason.is_valid) {
378  if (gdbr_stop_reason(ctx->desc) < 0) {
381  }
382  }
383  if (ctx->desc->stop_reason.thread.present) {
384  dbg->reason.tid = ctx->desc->stop_reason.thread.tid;
385  dbg->pid = ctx->desc->stop_reason.thread.pid;
386  dbg->tid = ctx->desc->stop_reason.thread.tid;
387  if (dbg->pid != ctx->desc->pid || dbg->tid != ctx->desc->tid) {
388  // eprintf ("= attach %d %d\n", dbg->pid, dbg->tid);
389  gdbr_select(ctx->desc, dbg->pid, dbg->tid);
390  }
391  }
392  dbg->reason.signum = ctx->desc->stop_reason.signum;
393  dbg->reason.type = ctx->desc->stop_reason.reason;
394  return ctx->desc->stop_reason.reason;
395 }
396 
397 static int rz_debug_gdb_attach(RzDebug *dbg, int pid) {
399  RzIODesc *d = dbg->iob.io->desc;
400  // TODO: the core must update the dbg.swstep config var when this var is changed
401  dbg->swstep = false;
402  // eprintf ("XWJSTEP TOFALSE\n");
403  if (d && d->plugin && d->plugin->name && d->data) {
404  if (!strcmp("gdb", d->plugin->name)) {
405  RzIOGdb *g = d->data;
406  ctx->origrziogdb = (RzIOGdb **)&d->data; // TODO bit of a hack, please improve
407  ctx->support_sw_bp = UNKNOWN;
408  ctx->support_hw_bp = UNKNOWN;
409  ctx->desc = &g->desc;
410  int arch = rz_sys_arch_id(dbg->arch);
411  int bits = dbg->analysis->bits;
413  } else {
414  eprintf("ERROR: Underlying IO descriptor is not a GDB one..\n");
415  }
416  }
417  return true;
418 }
419 
420 static int rz_debug_gdb_detach(RzDebug *dbg, int pid) {
422  int ret = 0;
423 
424  if (pid <= 0 || !ctx->desc->stub_features.multiprocess) {
425  gdbr_detach(ctx->desc);
426  }
427  ret = gdbr_detach_pid(ctx->desc, pid);
428 
429  if (dbg->pid == pid) {
430  ctx->desc = NULL;
431  }
432  return ret;
433 }
434 
435 static const char *rz_debug_gdb_reg_profile(RzDebug *dbg) {
438  int arch = rz_sys_arch_id(dbg->arch);
439  int bits = dbg->analysis->bits;
440  // XXX This happens when rizin set dbg.backend before opening io_gdb
441  if (!ctx->desc) {
442  return gdbr_get_reg_profile(arch, bits);
443  }
444  if (!ctx->desc->target.valid) {
446  }
447  if (ctx->desc->target.regprofile) {
448  return strdup(ctx->desc->target.regprofile);
449  }
450  return NULL;
451 }
452 
453 static int rz_debug_gdb_set_reg_profile(RzDebug *dbg, const char *str) {
455  if (ctx->desc && str) {
456  return gdbr_set_reg_profile(ctx->desc, str);
457  }
458  return false;
459 }
460 
462  RzDebug *dbg = bp->user;
464  int ret = 0, bpsize;
465  if (!b) {
466  return false;
467  }
468  bpsize = b->size;
469  // TODO handle conditions
470  switch (b->perm) {
471  case RZ_PERM_X: {
472  if (set) {
473  ret = b->hw ? gdbr_set_hwbp(ctx->desc, b->addr, "", bpsize) : gdbr_set_bp(ctx->desc, b->addr, "", bpsize);
474  } else {
475  ret = b->hw ? gdbr_remove_hwbp(ctx->desc, b->addr, bpsize) : gdbr_remove_bp(ctx->desc, b->addr, bpsize);
476  }
477  break;
478  }
479  // TODO handle size (area of watch in upper layer and then bpsize. For the moment watches are set on exact on byte
480  case RZ_PERM_W: {
481  if (set) {
482  gdbr_set_hww(ctx->desc, b->addr, "", 1);
483  } else {
484  gdbr_remove_hww(ctx->desc, b->addr, 1);
485  }
486  break;
487  }
488  case RZ_PERM_R: {
489  if (set) {
490  gdbr_set_hwr(ctx->desc, b->addr, "", 1);
491  } else {
492  gdbr_remove_hwr(ctx->desc, b->addr, 1);
493  }
494  break;
495  }
496  case RZ_PERM_ACCESS: {
497  if (set) {
498  gdbr_set_hwa(ctx->desc, b->addr, "", 1);
499  } else {
500  gdbr_remove_hwa(ctx->desc, b->addr, 1);
501  }
502  break;
503  }
504  }
505  return !ret;
506 }
507 
508 static bool rz_debug_gdb_kill(RzDebug *dbg, int pid, int tid, int sig) {
510  // TODO kill based on pid and signal
511  if (sig != 0) {
512  if (gdbr_kill(ctx->desc) < 0) {
513  return false;
514  }
515  }
516  return true;
517 }
518 
519 static int rz_debug_gdb_select(RzDebug *dbg, int pid, int tid) {
521  if (!ctx->desc || !*ctx->origrziogdb) {
522  ctx->desc = NULL; // TODO hacky fix, please improve. I would suggest using a **desc instead of a *desc, so it is automatically updated
523  return false;
524  }
525 
526  return gdbr_select(ctx->desc, pid, tid) >= 0;
527 }
528 
529 static RzDebugInfo *rz_debug_gdb_info(RzDebug *dbg, const char *arg) {
531  RzDebugInfo *rdi;
532  if (!(rdi = RZ_NEW0(RzDebugInfo))) {
533  return NULL;
534  }
535  RzList *th_list;
536  bool list_alloc = false;
537  if (dbg->threads) {
538  th_list = dbg->threads;
539  } else {
540  th_list = rz_debug_gdb_threads(dbg, dbg->pid);
541  list_alloc = true;
542  }
543  RzDebugPid *th;
544  RzListIter *it;
545  bool found = false;
546  rz_list_foreach (th_list, it, th) {
547  if (th->pid == dbg->pid) {
548  found = true;
549  break;
550  }
551  }
552  rdi->pid = dbg->pid;
553  rdi->tid = dbg->tid;
554  rdi->exe = gdbr_exec_file_read(ctx->desc, dbg->pid);
555  rdi->status = found ? th->status : RZ_DBG_PROC_STOP;
556  rdi->uid = found ? th->uid : -1;
557  rdi->gid = found ? th->gid : -1;
558  if (gdbr_stop_reason(ctx->desc) >= 0) {
559  eprintf("signal: %d\n", ctx->desc->stop_reason.signum);
560  rdi->signum = ctx->desc->stop_reason.signum;
561  }
562  if (list_alloc) {
563  rz_list_free(th_list);
564  }
565  return rdi;
566 }
567 
568 #include "native/bt.c"
569 
571  return rz_debug_native_frames(dbg, at);
572 }
573 
575  .name = "gdb",
576  /* TODO: Add support for more architectures here */
577  .license = "LGPL3",
578  .arch = "x86,arm,sh,mips,avr,lm32,v850,ba2",
580  .init = rz_debug_gdb_init,
581  .fini = rz_debug_gdb_fini,
582  .step = rz_debug_gdb_step,
583  .cont = rz_debug_gdb_continue,
584  .attach = &rz_debug_gdb_attach,
585  .detach = &rz_debug_gdb_detach,
586  .threads = &rz_debug_gdb_threads,
587  .pids = &rz_debug_gdb_pids,
588  .canstep = 1,
589  .wait = &rz_debug_gdb_wait,
590  .map_get = rz_debug_gdb_map_get,
591  .modules_get = rz_debug_gdb_modules_get,
592  .breakpoint = &rz_debug_gdb_breakpoint,
593  .reg_read = &rz_debug_gdb_reg_read,
594  .reg_write = &rz_debug_gdb_reg_write,
595  .reg_profile = (void *)rz_debug_gdb_reg_profile,
596  .set_reg_profile = &rz_debug_gdb_set_reg_profile,
600  .frames = &rz_debug_gdb_frames,
601  //.bp_write = &rz_debug_gdb_bp_write,
602  //.bp_read = &rz_debug_gdb_bp_read,
603 };
604 
605 #ifndef RZ_PLUGIN_INCORE
608  .data = &rz_debug_plugin_gdb,
610 };
611 #endif
lzma_index ** i
Definition: index.h:629
RZ_API ut8 * rz_reg_get_bytes(RzReg *reg, int type, int *size)
Definition: arena.c:8
static ut64 baddr(RzBinFile *bf)
Definition: bin_any.c:58
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
const char * desc
Definition: bin_vsf.c:19
int bits(struct state *s, int need)
Definition: blast.c:72
static RzList * rz_debug_native_frames(RzDebug *dbg, ut64 at)
Definition: bt.c:46
int gdbr_remove_hwa(libgdbr_t *g, ut64 address, int sizebp)
Definition: core.c:1392
int gdbr_remove_bp(libgdbr_t *g, ut64 address, int sizebp)
Definition: core.c:1377
int gdbr_open_file(libgdbr_t *g, const char *filename, int flags, int mode)
Definition: core.c:1445
int gdbr_remove_hwbp(libgdbr_t *g, ut64 address, int sizebp)
Definition: core.c:1380
int gdbr_read_registers(libgdbr_t *g)
Definition: core.c:685
int gdbr_remove_hwr(libgdbr_t *g, ut64 address, int sizebp)
Definition: core.c:1388
int gdbr_detach(libgdbr_t *g)
detaches from a process
Definition: core.c:495
RzList * gdbr_threads_list(libgdbr_t *g, int pid)
get list of threads for given pid
Definition: core.c:1833
int gdbr_set_bp(libgdbr_t *g, ut64 address, const char *conditions, int sizebp)
Function sets normal breakpoint (0xcc, int3)
Definition: core.c:1357
char * gdbr_exec_file_read(libgdbr_t *g, int pid)
Definition: core.c:1635
int gdbr_remove_hww(libgdbr_t *g, ut64 address, int sizebp)
Definition: core.c:1384
RzList * gdbr_pids_list(libgdbr_t *g, int pid)
get a list of the child processes of the given pid
Definition: core.c:1731
int gdbr_detach_pid(libgdbr_t *g, int pid)
Definition: core.c:520
int gdbr_set_hwa(libgdbr_t *g, ut64 address, const char *conditions, int sizebp)
Definition: core.c:1373
int gdbr_set_hwbp(libgdbr_t *g, ut64 address, const char *conditions, int sizebp)
Definition: core.c:1361
int gdbr_step(libgdbr_t *g, int thread_id)
Definition: core.c:929
int gdbr_continue(libgdbr_t *g, int pid, int tid, int sig)
Definition: core.c:950
int gdbr_set_hwr(libgdbr_t *g, ut64 address, const char *conditions, int sizebp)
Definition: core.c:1369
int gdbr_write_reg(libgdbr_t *g, const char *name, char *value, int len)
Definition: core.c:1058
int gdbr_read_file(libgdbr_t *g, ut8 *buf, ut64 max_len)
Definition: core.c:1485
ut64 gdbr_get_baddr(libgdbr_t *g)
Definition: core.c:1931
int gdbr_select(libgdbr_t *g, int pid, int tid)
Definition: core.c:304
int gdbr_kill(libgdbr_t *g)
kills the process the remote gdbserver is debugging (TODO: handle pid)
Definition: core.c:572
int gdbr_set_hww(libgdbr_t *g, ut64 address, const char *conditions, int sizebp)
Definition: core.c:1365
int gdbr_stop_reason(libgdbr_t *g)
gets reason why remote target stopped
Definition: core.c:391
int gdbr_close_file(libgdbr_t *g)
Definition: core.c:1539
#define RZ_API
#define NULL
Definition: cris-opc.c:27
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
cs_arch arch
Definition: cstool.c:13
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
static int rz_debug_gdb_set_reg_profile(RzDebug *dbg, const char *str)
Definition: debug_gdb.c:453
static int rz_debug_gdb_reg_read(RzDebug *dbg, int type, ut8 *buf, int size)
Definition: debug_gdb.c:79
static bool rz_debug_gdb_init(RzDebug *dbg, void **user)
Definition: debug_gdb.c:27
static void check_connection(RzDebug *dbg)
Definition: debug_gdb.c:44
struct rz_debug_gdb_ctx_t RzDebugGdbCtx
static int rz_debug_gdb_select(RzDebug *dbg, int pid, int tid)
Definition: debug_gdb.c:519
RzDebugPlugin rz_debug_plugin_gdb
Definition: debug_gdb.c:574
#define GDB_FILE_OPEN_MODE
static int rz_debug_gdb_continue(RzDebug *dbg, int pid, int tid, int sig)
Definition: debug_gdb.c:355
static RzList * rz_debug_gdb_map_get(RzDebug *dbg)
Definition: debug_gdb.c:133
static const char * rz_debug_gdb_reg_profile(RzDebug *dbg)
Definition: debug_gdb.c:435
static RzList * rz_debug_gdb_frames(RzDebug *dbg, ut64 at)
Definition: debug_gdb.c:570
RZ_API RzLibStruct rizin_plugin
Definition: debug_gdb.c:606
static int rz_debug_gdb_step(RzDebug *dbg)
Definition: debug_gdb.c:51
static RzList * rz_debug_gdb_modules_get(RzDebug *dbg)
Definition: debug_gdb.c:268
static RzList * rz_debug_gdb_threads(RzDebug *dbg, int pid)
Definition: debug_gdb.c:61
static bool rz_debug_gdb_kill(RzDebug *dbg, int pid, int tid, int sig)
Definition: debug_gdb.c:508
static RzList * rz_debug_gdb_pids(RzDebug *dbg, int pid)
Definition: debug_gdb.c:70
static int rz_debug_gdb_attach(RzDebug *dbg, int pid)
Definition: debug_gdb.c:397
static int rz_debug_gdb_breakpoint(RzBreakpoint *bp, RzBreakpointItem *b, bool set)
Definition: debug_gdb.c:461
static int rz_debug_gdb_detach(RzDebug *dbg, int pid)
Definition: debug_gdb.c:420
#define UNKNOWN
Definition: debug_gdb.c:14
static int rz_debug_gdb_reg_write(RzDebug *dbg, int type, const ut8 *buf, int size)
Definition: debug_gdb.c:306
static RzDebugReasonType rz_debug_gdb_wait(RzDebug *dbg, int pid)
Definition: debug_gdb.c:371
static void rz_debug_gdb_fini(RzDebug *dbg, void *user)
Definition: debug_gdb.c:38
static RzDebugInfo * rz_debug_gdb_info(RzDebug *dbg, const char *arg)
Definition: debug_gdb.c:529
RzDebug * dbg
Definition: desil.c:30
RZ_API void rz_debug_map_free(RzDebugMap *map)
Definition: dmap.c:77
RZ_API RzDebugMap * rz_debug_map_new(char *name, ut64 addr, ut64 addr_end, int perm, int user)
Definition: dmap.c:7
struct @667 g
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
voidpf void * buf
Definition: ioapi.h:138
snprintf
Definition: kernel.h:364
#define reg(n)
uint8_t ut8
Definition: lh5801.h:11
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
int gdbr_set_reg_profile(libgdbr_t *g, const char *str)
Function set the gdbr internal registers profile.
Definition: libgdbr.c:125
bool gdbr_set_architecture(libgdbr_t *g, int arch, int bits)
Function initializes the architecture of the gdbsession.
Definition: libgdbr.c:52
char * gdbr_get_reg_profile(int arch, int bits)
Function get gdb registers profile based on arch and bits.
Definition: libgdbr.c:76
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API void rz_list_delete(RZ_NONNULL RzList *list, RZ_NONNULL RzListIter *iter)
Removes an entry in the list by using the RzListIter pointer.
Definition: list.c:162
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
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 kill
Definition: sflib.h:64
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
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 static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz select
Definition: sflib.h:108
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int type
Definition: mipsasm.c:17
RZ_API RzDebugPid * rz_debug_pid_free(RzDebugPid *pid)
Definition: pid.c:20
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
RZ_API const char * rz_reg_get_name(RzReg *reg, int role)
Definition: reg.c:147
RZ_API RzRegItem * rz_reg_next_diff(RzReg *reg, int type, const ut8 *buf, int buflen, RzRegItem *prev_ri, int regsize)
Definition: reg.c:430
#define eprintf(x, y...)
Definition: rlcc.c:7
RzDebugReasonType
Definition: rz_debug.h:89
@ RZ_DEBUG_REASON_UNKNOWN
Definition: rz_debug.h:103
@ RZ_DBG_PROC_STOP
Definition: rz_debug.h:60
@ RZ_LIB_TYPE_DBG
Definition: rz_lib.h:70
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
@ RZ_REG_NAME_PC
Definition: rz_reg.h:43
@ RZ_SYS_BITS_32
Definition: rz_sys.h:20
@ RZ_SYS_BITS_64
Definition: rz_sys.h:21
@ RZ_SYS_BITS_16
Definition: rz_sys.h:19
RZ_API int rz_sys_arch_id(const char *arch)
Definition: sys.c:788
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_ACCESS
Definition: rz_types.h:102
#define RZ_PERM_W
Definition: rz_types.h:94
#define RZ_PERM_X
Definition: rz_types.h:95
#define RZ_PERM_RX
Definition: rz_types.h:97
#define PFMT64x
Definition: rz_types.h:393
#define RZ_MIN(x, y)
#define RZ_MAX(x, y)
#define RZ_VERSION
Definition: rz_version.h:8
#define O_RDONLY
Definition: sftypes.h:486
#define d(i)
Definition: sha256.c:44
#define b(i)
Definition: sha256.c:42
#define UINT64_MAX
libgdbr_t desc
Definition: debug_gdb.c:11
Definition: gzappend.c:170
Definition: z80asm.h:102
Definition: rz_bp.h:78
void * user
Definition: rz_bp.h:79
libgdbr_t * desc
Definition: debug_gdb.c:20
RzIOGdb ** origrziogdb
Definition: debug_gdb.c:19
const char * version
Definition: rz_debug.h:362
const char * name
Definition: rz_debug.h:359
RzList * threads
Definition: rz_debug.h:251
int swstep
Definition: rz_debug.h:261
RzDebugReason reason
Definition: rz_debug.h:276
RzAnalysis * analysis
Definition: rz_debug.h:305
char * arch
Definition: rz_debug.h:242
RzReg * reg
Definition: rz_debug.h:286
void * plugin_data
Definition: rz_debug.h:296
RzIOBind iob
Definition: rz_debug.h:293
RzIO * io
Definition: rz_io.h:232
struct rz_io_desc_t * desc
Definition: rz_io.h:60
ut8 * bytes
Definition: rz_reg.h:131
int size
in bits> 8,16,32,64 ... 128/256
Definition: rz_reg.h:120
int offset
Offset into register profile in bits.
Definition: rz_reg.h:121
char * name
Definition: rz_reg.h:118
RzRegArena * arena
Definition: rz_reg.h:136
RzRegSet regset[RZ_REG_TYPE_LAST]
Definition: rz_reg.h:150
ut64 buflen
Definition: core.c:76
ut64(WINAPI *w32_GetEnabledXStateFeatures)()