Rizin
unix-like reverse engineering framework and cli tools
debug.c File Reference
#include <rz_debug.h>
#include <rz_drx.h>
#include <rz_core.h>
#include <rz_windows.h>
#include <signal.h>

Go to the source code of this file.

Macros

#define DBG_BUF_SIZE   512
 

Functions

 RZ_LIB_VERSION (rz_debug)
 
RZ_API RzDebugInforz_debug_info (RzDebug *dbg, const char *arg)
 
RZ_API void rz_debug_info_free (RzDebugInfo *rdi)
 
RZ_API void rz_debug_bp_update (RzDebug *dbg)
 
static int rz_debug_drx_at (RzDebug *dbg, ut64 addr)
 
static int rz_debug_bp_hit (RzDebug *dbg, RzRegItem *pc_ri, ut64 pc, RzBreakpointItem **pb)
 
static int rz_debug_bps_enable (RzDebug *dbg)
 
static int rz_debug_recoil (RzDebug *dbg, RzDebugRecoilMode rc_mode)
 
RZ_API RZ_BORROW RzBreakpointItemrz_debug_bp_add (RZ_NONNULL RzDebug *dbg, ut64 addr, int hw, bool watch, int rw, RZ_NULLABLE const char *module, st64 m_delta)
 
static const char * rz_debug_str_callback (RzNum *userptr, ut64 off, int *ok)
 
void free_tracenodes_kv (HtUPKv *kv)
 
RZ_API RZ_OWN RzDebugrz_debug_new (RZ_BORROW RZ_NONNULL RzBreakpointContext *bp_ctx)
 
RZ_API void rz_debug_tracenodes_reset (RzDebug *dbg)
 
RZ_API RzDebugrz_debug_free (RzDebug *dbg)
 
RZ_API int rz_debug_attach (RzDebug *dbg, int pid)
 
RZ_API int rz_debug_stop (RzDebug *dbg)
 
RZ_API bool rz_debug_set_arch (RzDebug *dbg, const char *arch, int bits)
 
RZ_API ut64 rz_debug_execute (RzDebug *dbg, const ut8 *buf, int len, int restore)
 
RZ_API int rz_debug_startv (struct rz_debug_t *dbg, int argc, char **argv)
 
RZ_API int rz_debug_start (RzDebug *dbg, const char *cmd)
 
RZ_API int rz_debug_detach (RzDebug *dbg, int pid)
 
RZ_API bool rz_debug_select (RzDebug *dbg, int pid, int tid)
 
RZ_API const char * rz_debug_reason_to_string (int type)
 
RZ_API RzDebugReasonType rz_debug_stop_reason (RzDebug *dbg)
 
RZ_API RzDebugReasonType rz_debug_wait (RzDebug *dbg, RzBreakpointItem **bp)
 
RZ_API int rz_debug_step_soft (RzDebug *dbg)
 
RZ_API int rz_debug_step_hard (RzDebug *dbg, RzBreakpointItem **pb)
 
RZ_API int rz_debug_step (RzDebug *dbg, int steps)
 
static bool isStepOverable (ut64 opType)
 
RZ_API int rz_debug_step_over (RzDebug *dbg, int steps)
 
RZ_API bool rz_debug_goto_cnum (RzDebug *dbg, ut32 cnum)
 
RZ_API int rz_debug_step_back (RzDebug *dbg, int steps)
 
RZ_API int rz_debug_step_cnum (RzDebug *dbg, int steps)
 
RZ_API int rz_debug_continue_kill (RzDebug *dbg, int sig)
 
RZ_API int rz_debug_continue (RzDebug *dbg)
 
RZ_API int rz_debug_continue_pass_exception (RzDebug *dbg)
 
RZ_API int rz_debug_continue_until_nontraced (RzDebug *dbg)
 
RZ_API int rz_debug_continue_until_optype (RzDebug *dbg, int type, int over)
 
static int rz_debug_continue_until_internal (RzDebug *dbg, ut64 addr, bool block)
 
RZ_API int rz_debug_continue_until (RzDebug *dbg, ut64 addr)
 
RZ_API int rz_debug_continue_until_nonblock (RzDebug *dbg, ut64 addr)
 
RZ_API bool rz_debug_continue_back (RzDebug *dbg)
 
static int show_syscall (RzDebug *dbg, const char *sysreg)
 
RZ_API int rz_debug_continue_syscalls (RzDebug *dbg, int *sc, int n_sc)
 
RZ_API int rz_debug_continue_syscall (RzDebug *dbg, int sc)
 
RZ_API int rz_debug_syscall (RzDebug *dbg, int num)
 
RZ_API bool rz_debug_can_kill (RzDebug *dbg)
 check whether rz_debug_kill() will not definitely fail (for example because kill is unimplemented by the plugin) More...
 
RZ_API int rz_debug_kill (RzDebug *dbg, int pid, int tid, int sig)
 
RZ_API RzListrz_debug_frames (RzDebug *dbg, ut64 at)
 
RZ_API int rz_debug_child_fork (RzDebug *dbg)
 
RZ_API int rz_debug_child_clone (RzDebug *dbg)
 
RZ_API bool rz_debug_is_dead (RzDebug *dbg)
 
RZ_API int rz_debug_map_protect (RzDebug *dbg, ut64 addr, int size, int perms)
 
RZ_API void rz_debug_drx_list (RzDebug *dbg)
 
RZ_API int rz_debug_drx_set (RzDebug *dbg, int idx, ut64 addr, int len, int rwx, int g)
 
RZ_API int rz_debug_drx_unset (RzDebug *dbg, int idx)
 
RZ_API ut64 rz_debug_get_baddr (RzDebug *dbg, const char *file)
 
RZ_API void rz_debug_bp_rebase (RzDebug *dbg, ut64 old_base, ut64 new_base)
 

Macro Definition Documentation

◆ DBG_BUF_SIZE

#define DBG_BUF_SIZE   512

Definition at line 16 of file debug.c.

Function Documentation

◆ free_tracenodes_kv()

void free_tracenodes_kv ( HtUPKv *  kv)

Definition at line 355 of file debug.c.

355  {
356  free(kv->value);
357 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130

References free().

Referenced by rz_debug_new(), and rz_debug_tracenodes_reset().

◆ isStepOverable()

static bool isStepOverable ( ut64  opType)
static

Definition at line 1022 of file debug.c.

1022  {
1023  switch (opType & RZ_ANALYSIS_OP_TYPE_MASK) {
1028  return true;
1029  }
1030  return false;
1031 }
#define RZ_ANALYSIS_OP_TYPE_MASK
Definition: rz_analysis.h:358
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_RCALL
Definition: rz_analysis.h:380

References RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_MASK, RZ_ANALYSIS_OP_TYPE_RCALL, RZ_ANALYSIS_OP_TYPE_SWI, and RZ_ANALYSIS_OP_TYPE_UCALL.

Referenced by rz_debug_step_over().

◆ rz_debug_attach()

RZ_API int rz_debug_attach ( RzDebug dbg,
int  pid 
)

Definition at line 445 of file debug.c.

445  {
446  int ret = false;
447  if (dbg && dbg->cur && dbg->cur->attach) {
448  ret = dbg->cur->attach(dbg, pid);
449  if (ret != -1) {
450  dbg->reason.type = RZ_DEBUG_REASON_NONE; // after a successful attach, the process is not dead
451  rz_debug_select(dbg, pid, ret); // dbg->pid, dbg->tid);
452  }
453  }
454  return ret;
455 }
RzDebug * dbg
Definition: desil.c:30
RZ_API bool rz_debug_select(RzDebug *dbg, int pid, int tid)
Definition: debug.c:595
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
@ RZ_DEBUG_REASON_NONE
Definition: rz_debug.h:91
int(* attach)(RzDebug *dbg, int pid)
Definition: rz_debug.h:372
RzDebugReason reason
Definition: rz_debug.h:276
struct rz_debug_plugin_t * cur
Definition: rz_debug.h:295

References rz_debug_plugin_t::attach, rz_debug_t::cur, dbg, pid, rz_debug_t::reason, RZ_DEBUG_REASON_NONE, rz_debug_select(), and rz_debug_reason_t::type.

Referenced by cb_dbg_aftersc(), cb_dbg_clone(), cb_dbg_execs(), cb_dbg_forks(), rz_core_debug_attach(), and rz_debug_get_baddr().

◆ rz_debug_bp_add()

RZ_API RZ_BORROW RzBreakpointItem* rz_debug_bp_add ( RZ_NONNULL RzDebug dbg,
ut64  addr,
int  hw,
bool  watch,
int  rw,
RZ_NULLABLE const char *  module,
st64  m_delta 
)

Definition at line 270 of file debug.c.

270  {
272  int bpsz = rz_bp_size_at(dbg->bp, addr);
273  RzBreakpointItem *bpi;
274  const char *module_name = module;
275  RzListIter *iter;
276  RzDebugMap *map;
277  if (!addr && module) {
278  bool detect_module, valid = false;
279  int perm;
280 
281  if (m_delta) {
282  detect_module = false;
284  rz_list_foreach (list, iter, map) {
285  if (strstr(map->file, module)) {
286  addr = map->addr + m_delta;
287  module_name = map->file;
288  break;
289  }
290  }
292  } else {
293  // module holds the address
295  if (!addr) {
296  return NULL;
297  }
298  detect_module = true;
299  }
301  rz_list_foreach (dbg->maps, iter, map) {
302  if (addr >= map->addr && addr < map->addr_end) {
303  valid = true;
304  if (detect_module) {
305  module_name = map->file;
306  m_delta = addr - map->addr;
307  }
308  perm = ((map->perm & 1) << 2) | (map->perm & 2) | ((map->perm & 4) >> 2);
309  if (!(perm & RZ_PERM_X)) {
310  eprintf("WARNING: setting bp within mapped memory without exec perm\n");
311  }
312  break;
313  }
314  }
315  if (!valid) {
316  eprintf("WARNING: module's base addr + delta is not a valid address\n");
317  return NULL;
318  }
319  }
320  if (!module) {
321  // express db breakpoints as dbm due to ASLR when saving into project
323  rz_list_foreach (dbg->maps, iter, map) {
324  if (addr >= map->addr && addr < map->addr_end) {
325  module_name = map->file;
326  m_delta = addr - map->addr;
327  break;
328  }
329  }
330  }
331  if (watch) {
332  hw = 1; // XXX
333  bpi = rz_bp_watch_add(dbg->bp, addr, bpsz, hw, rw);
334  } else {
335  bpi = hw
336  ? rz_bp_add_hw(dbg->bp, addr, bpsz, RZ_PERM_X)
337  : rz_bp_add_sw(dbg->bp, addr, bpsz, RZ_PERM_X);
338  }
339  if (bpi) {
340  if (module_name) {
341  bpi->module_name = strdup(module_name);
342  bpi->name = rz_str_newf("%s+0x%" PFMT64x, module_name, m_delta);
343  }
344  bpi->module_delta = m_delta;
345  }
346  return bpi;
347 }
RZ_API RzBreakpointItem * rz_bp_add_hw(RzBreakpoint *bp, ut64 addr, int size, int perm)
Definition: bp.c:299
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_add_sw(RZ_NONNULL RzBreakpoint *bp, ut64 addr, int size, int perm)
Add a software breakpoint size preferred size of the breakpoint, or 0 to determine automatically.
Definition: bp.c:280
RZ_API int rz_bp_size_at(RZ_NONNULL RzBreakpoint *bp, ut64 addr)
Predict the software breakpoint size to use when placing a breakpoint at addr.
Definition: bp.c:399
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_watch_add(RZ_NONNULL RzBreakpoint *bp, ut64 addr, int size, int hw, int perm)
Definition: bp_watch.c:15
#define NULL
Definition: cris-opc.c:27
RZ_API bool rz_debug_map_sync(RzDebug *dbg)
Definition: dmap.c:33
RZ_API RzList * rz_debug_modules_list(RzDebug *dbg)
Definition: dmap.c:29
size_t map(int syms, int left, int len)
Definition: enough.c:237
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
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")
#define eprintf(x, y...)
Definition: rlcc.c:7
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define RZ_PERM_X
Definition: rz_types.h:95
#define PFMT64x
Definition: rz_types.h:393
Definition: sftypes.h:77
st64 module_delta
Definition: rz_bp.h:44
char * module_name
Definition: rz_bp.h:43
char * name
Definition: rz_bp.h:42
RzList * maps
Definition: rz_debug.h:306
RzNum * num
Definition: rz_debug.h:317
RzBreakpoint * bp
Definition: rz_debug.h:288
bool valid
Definition: core.c:77
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58

References addr, rz_debug_t::bp, dbg, eprintf, list(), map(), rz_debug_t::maps, rz_bp_item_t::module_delta, rz_bp_item_t::module_name, rz_bp_item_t::name, NULL, rz_debug_t::num, PFMT64x, rz_bp_add_hw(), rz_bp_add_sw(), rz_bp_size_at(), rz_bp_watch_add(), rz_debug_map_sync(), rz_debug_modules_list(), rz_list_free(), rz_num_math(), RZ_PERM_X, rz_return_val_if_fail, rz_str_newf(), strdup(), ut64(), and valid.

Referenced by debug_trace_calls(), rz_cmd_debug_add_bp_module_handler(), rz_core_debug_bp_add(), rz_core_debug_bp_add_noreturn_func(), rz_core_debug_breakpoint_toggle(), rz_core_debug_step_over(), rz_core_debug_step_skip(), and rz_w32_add_winmsg_breakpoint().

◆ rz_debug_bp_hit()

static int rz_debug_bp_hit ( RzDebug dbg,
RzRegItem pc_ri,
ut64  pc,
RzBreakpointItem **  pb 
)
static

Definition at line 66 of file debug.c.

66  {
68 
69  if (!pb) {
70  eprintf("BreakpointItem is NULL!\n");
71  return false;
72  }
73  /* initialize the output parameter */
74  *pb = NULL;
75 
76  /* if we are tracing, update the tracing data */
77  if (dbg->trace->enabled) {
79  }
80 
81  /* remove all sw breakpoints for now. we'll set them back in stage 2
82  *
83  * this is necessary because while stopped we don't want any breakpoints in
84  * the code messing up our analysis.
85  */
87  if (!rz_bp_restore(dbg->bp, false)) { // unset sw breakpoints
88  return false;
89  }
90 
91  /* if we are recoiling, tell rz_debug_step that we ignored a breakpoint
92  * event */
94  dbg->reason.bp_addr = 0;
95  return true;
96  }
97 
98  /* The MIPS ptrace has a different behaviour */
99 #if __mips__
100  /* see if we really have a breakpoint here... */
101  b = rz_bp_get_at(dbg->bp, pc);
102  if (!b) { /* we don't. nothing left to do */
103  return true;
104  }
105 #else
106  /* see if we really have a breakpoint here... */
107  if (!dbg->pc_at_bp_set) {
109  if (!b) { /* we don't. nothing left to do */
110  /* Some targets set pc to breakpoint */
111  b = rz_bp_get_at(dbg->bp, pc);
112  if (!b) {
113  /* handle the case of hw breakpoints - notify the user */
114  int drx_reg_idx = rz_debug_drx_at(dbg, pc);
115  if (drx_reg_idx != -1) {
116  eprintf("hit hardware breakpoint %d at: %" PFMT64x "\n",
117  drx_reg_idx, pc);
118  }
119  /* Couldn't find the break point. Nothing more to do... */
120  return true;
121  } else {
122  dbg->pc_at_bp_set = true;
123  dbg->pc_at_bp = true;
124  }
125  } else {
126  dbg->pc_at_bp_set = true;
127  dbg->pc_at_bp = false;
128  }
129  }
130 
131  if (!dbg->pc_at_bp_set) {
132  eprintf("failed to determine position of pc after breakpoint");
133  }
134 
135  int pc_off = 0;
136  if (dbg->pc_at_bp) {
137  b = rz_bp_get_at(dbg->bp, pc);
138  } else {
140  if (b) {
141  pc_off = b->size;
142  }
143  }
144 
145  if (!b) {
146  return true;
147  }
148 
150  if (!b) { /* we don't. nothing left to do */
151  /* Some targets set pc to breakpoint */
152  b = rz_bp_get_at(dbg->bp, pc);
153  if (!b) {
154  return true;
155  }
156  pc_off = 0;
157  }
158 
159  /* set the pc value back */
160  if (pc_off) {
161  pc -= pc_off;
162  if (!rz_reg_set_value(dbg->reg, pc_ri, pc)) {
163  eprintf("failed to set PC!\n");
164  return false;
165  }
166  if (!rz_debug_reg_sync(dbg, RZ_REG_TYPE_GPR, true)) {
167  eprintf("cannot set registers!\n");
168  return false;
169  }
170  }
171 #endif
172 
173  *pb = b;
174 
175  /* if we are on a software stepping breakpoint, we hide what is going on... */
176  if (b->swstep) {
177  dbg->reason.bp_addr = 0;
178  return true;
179  }
180 
181  /* setup our stage 2 */
182  dbg->reason.bp_addr = b->addr;
183 
184  /* inform the user of what happened */
185  if (dbg->hitinfo) {
186  eprintf("hit %spoint at: 0x%" PFMT64x "\n",
187  b->trace ? "trace" : "break", pc);
188  }
189 
190  /* now that we've cleaned up after the breakpoint, call the other
191  * potential breakpoint handlers
192  */
193  if (dbg->corebind.core && dbg->corebind.bphit) {
195  }
196  return true;
197 }
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_get_ending_at(RZ_NONNULL RzBreakpoint *bp, ut64 addr)
Get the breakpoint b that fulfills b->addr + b-> size == addr After hitting a (usually software) brea...
Definition: bp.c:119
RZ_API RZ_BORROW RzBreakpointItem * rz_bp_get_at(RZ_NONNULL RzBreakpoint *bp, ut64 addr)
Get the breakpoint at exactly addr.
Definition: bp.c:102
RZ_API int rz_bp_restore(RzBreakpoint *bp, bool set)
Definition: bp_io.c:28
RZ_API int rz_debug_reg_sync(RzDebug *dbg, int type, int write)
Definition: dreg.c:9
RZ_API void rz_debug_bp_update(RzDebug *dbg)
Definition: debug.c:39
static int rz_debug_drx_at(RzDebug *dbg, ut64 addr)
Definition: debug.c:50
RZ_API bool rz_reg_set_value(RzReg *reg, RzRegItem *item, ut64 value)
Definition: rvalue.c:186
@ RZ_DBG_RECOIL_NONE
Definition: rz_debug.h:81
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
#define b(i)
Definition: sha256.c:42
void * core
Definition: rz_bind.h:31
RzCoreDebugBpHit bphit
Definition: rz_bind.h:37
RzCoreBind corebind
Definition: rz_debug.h:314
RzDebugRecoilMode recoil_mode
Definition: rz_debug.h:277
bool pc_at_bp_set
Definition: rz_debug.h:300
int swstep
Definition: rz_debug.h:261
bool pc_at_bp
Definition: rz_debug.h:299
RzDebugTrace * trace
Definition: rz_debug.h:281
RzReg * reg
Definition: rz_debug.h:286
int hitinfo
XXX: MUST SET ///.
Definition: rz_debug.h:244
RZ_API int rz_debug_trace_pc(RzDebug *dbg, ut64 pc)
Definition: trace.c:160

References b, rz_debug_t::bp, rz_debug_reason_t::bp_addr, rz_core_bind_t::bphit, rz_core_bind_t::core, rz_debug_t::corebind, dbg, rz_debug_trace_t::enabled, eprintf, rz_debug_t::hitinfo, NULL, pc, rz_debug_t::pc_at_bp, rz_debug_t::pc_at_bp_set, PFMT64x, rz_debug_t::reason, rz_debug_t::recoil_mode, rz_debug_t::reg, rz_bp_get_at(), rz_bp_get_ending_at(), rz_bp_restore(), RZ_DBG_RECOIL_NONE, rz_debug_bp_update(), rz_debug_drx_at(), rz_debug_reg_sync(), rz_debug_trace_pc(), rz_reg_set_value(), RZ_REG_TYPE_GPR, rz_debug_t::swstep, and rz_debug_t::trace.

Referenced by rz_debug_wait().

◆ rz_debug_bp_rebase()

RZ_API void rz_debug_bp_rebase ( RzDebug dbg,
ut64  old_base,
ut64  new_base 
)

Definition at line 1737 of file debug.c.

1737  {
1738  RzBreakpointItem *bp;
1739  RzListIter *iter;
1740  ut64 diff = new_base - old_base;
1741  // update bp->baddr
1742  dbg->bp->baddr = new_base;
1743 
1744  // update bp's address
1745  rz_list_foreach (dbg->bp->bps, iter, bp) {
1746  bp->addr += diff;
1747  bp->delta = bp->addr - dbg->bp->baddr;
1748  }
1749 }
ut64 addr
Definition: rz_bp.h:45
ut64 delta
Definition: rz_bp.h:46
RzList * bps
Definition: rz_bp.h:93
ut64 baddr
Definition: rz_bp.h:96

References rz_bp_item_t::addr, rz_bp_t::baddr, rz_debug_t::bp, rz_bp_t::bps, dbg, rz_bp_item_t::delta, and ut64().

Referenced by __rebase_everything(), and rebase_helper().

◆ rz_debug_bp_update()

RZ_API void rz_debug_bp_update ( RzDebug dbg)

Definition at line 39 of file debug.c.

39  {
40  /* update all bp->addr if they are named bps */
41  RzBreakpointItem *bp;
43  rz_list_foreach (dbg->bp->bps, iter, bp) {
44  if (bp->expr) {
45  bp->addr = dbg->corebind.numGet(dbg->corebind.core, bp->expr);
46  }
47  }
48 }
char * expr
Definition: rz_bp.h:61
RzCoreNumGet numGet
Definition: rz_bind.h:47

References rz_bp_item_t::addr, rz_debug_t::bp, rz_bp_t::bps, rz_core_bind_t::core, rz_debug_t::corebind, dbg, rz_bp_item_t::expr, and rz_core_bind_t::numGet.

Referenced by linux_remove_fork_bps(), rz_debug_bp_hit(), and rz_debug_continue_kill().

◆ rz_debug_bps_enable()

static int rz_debug_bps_enable ( RzDebug dbg)
static

Definition at line 200 of file debug.c.

200  {
201  /* restore all sw breakpoints. we are about to step/continue so these need
202  * to be in place. */
203  if (!rz_bp_restore(dbg->bp, true)) {
204  return false;
205  }
206  /* done recoiling... */
208  return true;
209 }

References rz_debug_t::bp, dbg, rz_debug_t::recoil_mode, rz_bp_restore(), and RZ_DBG_RECOIL_NONE.

Referenced by rz_debug_recoil().

◆ rz_debug_can_kill()

RZ_API bool rz_debug_can_kill ( RzDebug dbg)

check whether rz_debug_kill() will not definitely fail (for example because kill is unimplemented by the plugin)

Definition at line 1594 of file debug.c.

1594  {
1595  return !rz_debug_is_dead(dbg) && dbg->cur && dbg->cur->kill;
1596 }
RZ_API bool rz_debug_is_dead(RzDebug *dbg)
Definition: debug.c:1632
bool(* kill)(RzDebug *dbg, int pid, int tid, int sig)
Definition: rz_debug.h:386

References rz_debug_t::cur, dbg, rz_debug_plugin_t::kill, and rz_debug_is_dead().

Referenced by rz_main_rizin().

◆ rz_debug_child_clone()

RZ_API int rz_debug_child_clone ( RzDebug dbg)

Definition at line 1626 of file debug.c.

1626  {
1627  // if (dbg && dbg->cur && dbg->cur->frames)
1628  // return dbg->cur->frames (dbg);
1629  return 0;
1630 }

Referenced by cmd_debug_pid().

◆ rz_debug_child_fork()

RZ_API int rz_debug_child_fork ( RzDebug dbg)

Definition at line 1620 of file debug.c.

1620  {
1621  // if (dbg && dbg->cur && dbg->cur->frames)
1622  // return dbg->cur->frames (dbg);
1623  return 0;
1624 }

Referenced by cmd_debug_pid().

◆ rz_debug_continue()

RZ_API int rz_debug_continue ( RzDebug dbg)

Definition at line 1332 of file debug.c.

1332  {
1333  return rz_debug_continue_kill(dbg, 0); // dbg->reason.signum);
1334 }
RZ_API int rz_debug_continue_kill(RzDebug *dbg, int sig)
Definition: debug.c:1141

References dbg, and rz_debug_continue_kill().

Referenced by cmd_debug_backtrace(), rz_core_debug_continue(), rz_core_debug_continue_until(), rz_core_file_reopen(), rz_debug_continue_until_internal(), rz_debug_execute(), rz_debug_step_soft(), and w32_attach().

◆ rz_debug_continue_back()

RZ_API bool rz_debug_continue_back ( RzDebug dbg)

Definition at line 1442 of file debug.c.

1442  {
1443  int cnum;
1444  bool has_bp = false;
1445 
1447  RzVector *vreg = ht_up_find(dbg->session->registers, ripc->offset | (ripc->arena << 16), NULL);
1448  if (!vreg) {
1449  eprintf("Error: cannot find PC change vector");
1450  return false;
1451  }
1453  rz_vector_foreach_prev(vreg, reg) {
1454  if (reg->cnum >= dbg->session->cnum) {
1455  continue;
1456  }
1457  has_bp = rz_bp_get_in(dbg->bp, reg->data, RZ_PERM_X) != NULL;
1458  if (has_bp) {
1459  cnum = reg->cnum;
1460  eprintf("hit breakpoint at: 0x%" PFMT64x " cnum: %d\n", reg->data, reg->cnum);
1461  break;
1462  }
1463  }
1464 
1465  if (has_bp) {
1466  rz_debug_goto_cnum(dbg, cnum);
1467  } else {
1468  if (dbg->session->maxcnum > 0) {
1469  rz_debug_goto_cnum(dbg, 0);
1470  }
1471  }
1472 
1473  return true;
1474 }
RZ_API RzBreakpointItem * rz_bp_get_in(RzBreakpoint *bp, ut64 addr, int perm)
Definition: bp.c:139
#define reg(n)
RZ_API bool rz_debug_goto_cnum(RzDebug *dbg, ut32 cnum)
Definition: debug.c:1110
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344
@ RZ_REG_NAME_PC
Definition: rz_reg.h:43
#define rz_vector_foreach_prev(vec, it)
Definition: rz_vector.h:173
RzDebugSession * session
Definition: rz_debug.h:311
int arena
In which arena is this reg living. Usually equals type.
Definition: rz_reg.h:127
int offset
Offset into register profile in bits.
Definition: rz_reg.h:121
char * name[RZ_REG_NAME_LAST]
Definition: rz_reg.h:149

References rz_reg_item_t::arena, rz_debug_t::bp, rz_debug_session_t::cnum, dbg, eprintf, rz_debug_session_t::maxcnum, rz_reg_t::name, NULL, rz_reg_item_t::offset, PFMT64x, reg, rz_debug_t::reg, rz_debug_session_t::registers, rz_bp_get_in(), rz_debug_goto_cnum(), RZ_PERM_X, rz_reg_get(), RZ_REG_NAME_PC, RZ_REG_TYPE_GPR, rz_vector_foreach_prev, and rz_debug_t::session.

Referenced by rz_cmd_debug_continue_back_handler().

◆ rz_debug_continue_kill()

RZ_API int rz_debug_continue_kill ( RzDebug dbg,
int  sig 
)

Definition at line 1141 of file debug.c.

1141  {
1143  int ret = 0;
1144  RzBreakpointItem *bp = NULL;
1145 
1146  if (!dbg) {
1147  return 0;
1148  }
1149 
1150  // If the debugger is not at the end of the changes
1151  // Go to the end or the next breakpoint in the changes
1152  if (dbg->session && dbg->session->cnum != dbg->session->maxcnum) {
1153  bool has_bp = false;
1155  RzVector *vreg = ht_up_find(dbg->session->registers, ripc->offset | (ripc->arena << 16), NULL);
1157  rz_vector_foreach_prev(vreg, reg) {
1158  if (reg->cnum <= dbg->session->cnum) {
1159  continue;
1160  }
1161  has_bp = rz_bp_get_in(dbg->bp, reg->data, RZ_PERM_X) != NULL;
1162  if (has_bp) {
1163  eprintf("hit breakpoint at: 0x%" PFMT64x " cnum: %d\n", reg->data, reg->cnum);
1164  rz_debug_goto_cnum(dbg, reg->cnum);
1165  return dbg->tid;
1166  }
1167  }
1168 
1170  return dbg->tid;
1171  }
1172 
1173 repeat:
1174  if (rz_debug_is_dead(dbg)) {
1175  return 0;
1176  }
1177  if (dbg->session && dbg->trace_continue) {
1178  while (!rz_cons_is_breaked()) {
1179  if (rz_debug_step(dbg, 1) != 1) {
1180  break;
1181  }
1183  break;
1184  }
1185  }
1186  reason = dbg->session->reasontype;
1187  bp = dbg->session->bp;
1188  } else if (dbg->cur && dbg->cur->cont) {
1189  /* handle the stage-2 of breakpoints */
1191  return 0;
1192  }
1193  /* tell the inferior to go! */
1194  ret = dbg->cur->cont(dbg, dbg->pid, dbg->tid, sig);
1195  // XXX(jjd): why? //dbg->reason.signum = 0;
1196  reason = rz_debug_wait(dbg, &bp);
1197  } else {
1198  return 0;
1199  }
1200 
1201  if (dbg->corebind.core) {
1202  RzCore *core = (RzCore *)dbg->corebind.core;
1203  RzNum *num = core->num;
1204  if (reason == RZ_DEBUG_REASON_COND) {
1205  if (bp && bp->cond && dbg->corebind.cmd) {
1206  dbg->corebind.cmd(dbg->corebind.core, bp->cond);
1207  }
1208  if (num->value) {
1209  goto repeat;
1210  }
1211  }
1212  }
1213  if (reason == RZ_DEBUG_REASON_BREAKPOINT &&
1214  ((bp && !bp->enabled) || (!bp && !rz_cons_is_breaked() && dbg->corebind.core && dbg->corebind.cfggeti(dbg->corebind.core, "dbg.bpsysign")))) {
1215  goto repeat;
1216  }
1217 
1218 #if __linux__
1219  if (reason == RZ_DEBUG_REASON_NEW_PID && dbg->follow_child) {
1220 #if DEBUGGER
1223  static bool (*linux_attach_new_process)(RzDebug * dbg, int pid) = NULL;
1224  if (!linux_attach_new_process) {
1225  linux_attach_new_process = rz_lib_dl_sym(NULL, "linux_attach_new_process");
1226  }
1229  }
1230 #endif
1231  goto repeat;
1232  }
1233 
1234  if (reason == RZ_DEBUG_REASON_NEW_TID) {
1235  ret = dbg->tid;
1236  if (!dbg->trace_clone) {
1237  goto repeat;
1238  }
1239  }
1240 
1241  if (reason == RZ_DEBUG_REASON_EXIT_TID) {
1242  goto repeat;
1243  }
1244 #endif
1245  if (reason != RZ_DEBUG_REASON_DEAD) {
1246  ret = dbg->tid;
1247  }
1248 #if __WINDOWS__
1249  if (reason == RZ_DEBUG_REASON_NEW_LIB ||
1250  reason == RZ_DEBUG_REASON_EXIT_LIB ||
1251  reason == RZ_DEBUG_REASON_NEW_TID ||
1252  reason == RZ_DEBUG_REASON_NONE ||
1253  reason == RZ_DEBUG_REASON_EXIT_TID) {
1254  goto repeat;
1255  }
1256 #endif
1257  if (reason == RZ_DEBUG_REASON_EXIT_PID) {
1258 #if __WINDOWS__
1259  dbg->pid = -1;
1260 #elif __linux__
1262  rz_bp_restore(dbg->bp, false); // (vdf) there has got to be a better way
1263 #endif
1264  }
1265 
1266  /* if continuing killed the inferior, we won't be able to get
1267  * the registers.. */
1268  if (reason == RZ_DEBUG_REASON_DEAD || rz_debug_is_dead(dbg)) {
1269  return 0;
1270  }
1271 
1272  /* if we hit a tracing breakpoint, we need to continue in
1273  * whatever mode the user desired. */
1274  if (reason == RZ_DEBUG_REASON_TRACEPOINT) {
1275  rz_debug_step(dbg, 1);
1276  goto repeat;
1277  }
1278 
1279  /* choose the thread that was returned from the continue function */
1280  // XXX(jjd): there must be a cleaner way to do this...
1281  if (ret != dbg->tid) {
1282  rz_debug_select(dbg, dbg->pid, ret);
1283  }
1284  sig = 0; // clear continuation after signal if needed
1285 
1286  /* handle general signals here based on the return from the wait
1287  * function */
1288  if (dbg->reason.signum != -1) {
1289  int what = rz_debug_signal_what(dbg, dbg->reason.signum);
1290  if (what & RZ_DBG_SIGNAL_CONT) {
1291  sig = dbg->reason.signum;
1292  eprintf("Continue into the signal %d handler\n", sig);
1293  goto repeat;
1294  } else if (what & RZ_DBG_SIGNAL_SKIP) {
1295  // skip signal. requires skipping one instruction
1296  ut8 buf[64];
1297  RzAnalysisOp op = { 0 };
1298  ut64 pc = rz_debug_reg_get(dbg, "PC");
1299  dbg->iob.read_at(dbg->iob.io, pc, buf, sizeof(buf));
1301  if (op.size > 0) {
1302  const char *signame = rz_signal_to_string(dbg->reason.signum);
1303  rz_debug_reg_set(dbg, "PC", pc + op.size);
1304  eprintf("Skip signal %d handler %s\n",
1305  dbg->reason.signum, signame);
1306  goto repeat;
1307  } else {
1308  ut64 pc = rz_debug_reg_get(dbg, "PC");
1309  eprintf("Stalled with an exception at 0x%08" PFMT64x "\n", pc);
1310  }
1311  }
1312  }
1313 #if __WINDOWS__
1315 #endif
1316 
1317  // Unset breakpoints before leaving
1318  if (reason != RZ_DEBUG_REASON_BREAKPOINT) {
1319  rz_bp_restore(dbg->bp, false);
1320  }
1321 
1322  // Add a checkpoint at stops
1323  if (dbg->session && !dbg->trace_continue) {
1324  dbg->session->cnum++;
1325  dbg->session->maxcnum++;
1327  }
1328 
1329  return ret;
1330 }
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
RZ_API ut64 rz_debug_reg_get(RzDebug *dbg, const char *name)
Definition: dreg.c:99
RZ_API int rz_debug_reg_set(struct rz_debug_t *dbg, const char *name, ut64 num)
Definition: dreg.c:89
RZ_API bool rz_debug_add_checkpoint(RzDebug *dbg)
Definition: dsession.c:58
RZ_API int rz_debug_signal_what(RzDebug *dbg, int num)
Definition: dsignal.c:151
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
static int rz_debug_recoil(RzDebug *dbg, RzDebugRecoilMode rc_mode)
Definition: debug.c:223
RZ_API int rz_debug_step(RzDebug *dbg, int steps)
Definition: debug.c:962
RZ_API RzDebugReasonType rz_debug_wait(RzDebug *dbg, RzBreakpointItem **bp)
Definition: debug.c:685
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 fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
bool linux_attach_new_process(RzDebug *dbg, int pid)
Definition: linux_debug.c:451
RZ_API int rz_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: op.c:96
static void repeat(struct parse *, sopno, int, int)
Definition: regcomp.c:1155
@ RZ_ANALYSIS_OP_MASK_BASIC
Definition: rz_analysis.h:440
RzDebugReasonType
Definition: rz_debug.h:89
@ RZ_DEBUG_REASON_NEW_TID
Definition: rz_debug.h:106
@ RZ_DEBUG_REASON_DEAD
Definition: rz_debug.h:90
@ RZ_DEBUG_REASON_STEP
Definition: rz_debug.h:98
@ RZ_DEBUG_REASON_TRACEPOINT
Definition: rz_debug.h:95
@ RZ_DEBUG_REASON_BREAKPOINT
Definition: rz_debug.h:94
@ RZ_DEBUG_REASON_NEW_LIB
Definition: rz_debug.h:107
@ RZ_DEBUG_REASON_EXIT_LIB
Definition: rz_debug.h:110
@ RZ_DEBUG_REASON_NEW_PID
Definition: rz_debug.h:105
@ RZ_DEBUG_REASON_EXIT_PID
Definition: rz_debug.h:108
@ RZ_DEBUG_REASON_EXIT_TID
Definition: rz_debug.h:109
@ RZ_DEBUG_REASON_COND
Definition: rz_debug.h:96
@ RZ_DBG_RECOIL_CONTINUE
Definition: rz_debug.h:83
@ RZ_DBG_SIGNAL_CONT
Definition: rz_debug.h:71
@ RZ_DBG_SIGNAL_SKIP
Definition: rz_debug.h:72
RZ_API void * rz_lib_dl_sym(void *handler, const char *name)
Definition: lib.c:90
RZ_API const char * rz_signal_to_string(int code)
Definition: signal.c:63
int enabled
Definition: rz_bp.h:53
char * cond
Definition: rz_bp.h:60
RzCoreCmd cmd
Definition: rz_bind.h:32
RzCoreConfigGetI cfggeti
Definition: rz_bind.h:43
RzNum * num
Definition: rz_core.h:316
int(* cont)(RzDebug *dbg, int pid, int tid, int sig)
Definition: rz_debug.h:383
RzBreakpointItem * bp
Definition: rz_debug.h:197
int forked_pid
Definition: rz_debug.h:249
int trace_clone
Definition: rz_debug.h:266
int follow_child
Definition: rz_debug.h:267
RzAnalysis * analysis
Definition: rz_debug.h:305
bool trace_continue
Definition: rz_debug.h:309
RzIOBind iob
Definition: rz_debug.h:293
RzIOReadAt read_at
Definition: rz_io.h:240
RzIO * io
Definition: rz_io.h:232
#define bool
Definition: sysdefs.h:146
Definition: dis.c:32
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References rz_debug_t::analysis, rz_reg_item_t::arena, bool, rz_debug_session_t::bp, rz_debug_t::bp, rz_core_bind_t::cfggeti, rz_core_bind_t::cmd, rz_debug_session_t::cnum, rz_bp_item_t::cond, rz_debug_plugin_t::cont, rz_core_bind_t::core, rz_debug_t::corebind, rz_debug_t::cur, dbg, rz_bp_item_t::enabled, eprintf, rz_debug_t::follow_child, rz_debug_t::forked_pid, if(), rz_io_bind_t::io, rz_debug_t::iob, linux_attach_new_process(), rz_debug_session_t::maxcnum, rz_reg_t::name, NULL, rz_core_t::num, num, rz_reg_item_t::offset, pc, PFMT64x, rz_debug_t::pid, pid, rz_io_bind_t::read_at, rz_debug_t::reason, rz_debug_session_t::reasontype, reg, rz_debug_t::reg, rz_debug_session_t::registers, repeat(), rz_analysis_op(), RZ_ANALYSIS_OP_MASK_BASIC, rz_bp_get_in(), rz_bp_restore(), rz_cons_break_pop(), rz_cons_is_breaked(), RZ_DBG_RECOIL_CONTINUE, RZ_DBG_SIGNAL_CONT, RZ_DBG_SIGNAL_SKIP, rz_debug_add_checkpoint(), rz_debug_bp_update(), rz_debug_goto_cnum(), rz_debug_is_dead(), RZ_DEBUG_REASON_BREAKPOINT, RZ_DEBUG_REASON_COND, RZ_DEBUG_REASON_DEAD, RZ_DEBUG_REASON_EXIT_LIB, RZ_DEBUG_REASON_EXIT_PID, RZ_DEBUG_REASON_EXIT_TID, RZ_DEBUG_REASON_NEW_LIB, RZ_DEBUG_REASON_NEW_PID, RZ_DEBUG_REASON_NEW_TID, RZ_DEBUG_REASON_NONE, RZ_DEBUG_REASON_STEP, RZ_DEBUG_REASON_TRACEPOINT, rz_debug_recoil(), rz_debug_reg_get(), rz_debug_reg_set(), rz_debug_select(), rz_debug_signal_what(), rz_debug_step(), rz_debug_wait(), rz_lib_dl_sym(), RZ_PERM_X, rz_reg_get(), RZ_REG_NAME_PC, RZ_REG_TYPE_GPR, rz_signal_to_string(), rz_vector_foreach_prev, rz_debug_t::session, rz_debug_reason_t::signum, rz_debug_t::tid, rz_debug_t::trace_clone, rz_debug_t::trace_continue, and ut64().

Referenced by rz_cmd_debug_continue_send_signal_handler(), rz_debug_continue(), and rz_debug_continue_pass_exception().

◆ rz_debug_continue_pass_exception()

RZ_API int rz_debug_continue_pass_exception ( RzDebug dbg)

Definition at line 1336 of file debug.c.

1336  {
1338 }

References dbg, rz_debug_t::reason, rz_debug_continue_kill(), and rz_debug_reason_t::signum.

Referenced by rz_cmd_debug_continue_exception_handler().

◆ rz_debug_continue_syscall()

RZ_API int rz_debug_continue_syscall ( RzDebug dbg,
int  sc 
)

Definition at line 1578 of file debug.c.

1578  {
1579  return rz_debug_continue_syscalls(dbg, &sc, 1);
1580 }
static char sc[]
Definition: egg_cb.c:6
RZ_API int rz_debug_continue_syscalls(RzDebug *dbg, int *sc, int n_sc)
Definition: debug.c:1507

References dbg, rz_debug_continue_syscalls(), and sc.

◆ rz_debug_continue_syscalls()

RZ_API int rz_debug_continue_syscalls ( RzDebug dbg,
int sc,
int  n_sc 
)

Definition at line 1507 of file debug.c.

1507  {
1508  int i, reg, ret = false;
1509  if (!dbg || !dbg->cur || rz_debug_is_dead(dbg)) {
1510  return false;
1511  }
1512  if (!dbg->cur->contsc) {
1513  /* user-level syscall tracing */
1515  return show_syscall(dbg, "A0");
1516  }
1517 
1518  if (!rz_debug_reg_sync(dbg, RZ_REG_TYPE_GPR, false)) {
1519  eprintf("--> cannot read registers\n");
1520  return -1;
1521  }
1522 
1524  eprintf("Cannot find 'sn' register for current arch-os.\n");
1525  return -1;
1526  }
1527  for (;;) {
1528  RzDebugReasonType reason;
1529 
1530  if (rz_cons_singleton()->context->breaked) {
1531  break;
1532  }
1533 #if __linux__
1534  // step is needed to avoid dupped contsc results
1535  /* XXX(jjd): actually one stop is before the syscall, the other is
1536  * after. this allows you to inspect the arguments before and the
1537  * return value after... */
1538  rz_debug_step(dbg, 1);
1539 #endif
1540  dbg->cur->contsc(dbg, dbg->pid, 0); // TODO handle return value
1541  // wait until continuation
1542  reason = rz_debug_wait(dbg, NULL);
1543  if (reason == RZ_DEBUG_REASON_DEAD || rz_debug_is_dead(dbg)) {
1544  break;
1545  }
1546 #if 0
1547  if (reason != RZ_DEBUG_REASON_STEP) {
1548  eprintf ("astep\n");
1549  break;
1550  }
1551 #endif
1552  if (!rz_debug_reg_sync(dbg, RZ_REG_TYPE_GPR, false)) {
1553  eprintf("--> cannot sync regs, process is probably dead\n");
1554  return -1;
1555  }
1556  reg = show_syscall(dbg, "SN");
1557 
1558  if (dbg->corebind.core && dbg->corebind.syshit) {
1560  }
1561 
1562  if (n_sc == -1) {
1563  continue;
1564  }
1565  if (n_sc == 0) {
1566  break;
1567  }
1568  for (i = 0; i < n_sc; i++) {
1569  if (sc[i] == reg) {
1570  return reg;
1571  }
1572  }
1573  // TODO: must use rz_core_cmd(as)..import code from rcore
1574  }
1575  return ret;
1576 }
lzma_index ** i
Definition: index.h:629
RZ_API RzCons * rz_cons_singleton(void)
Definition: cons.c:300
static int show_syscall(RzDebug *dbg, const char *sysreg)
Definition: debug.c:1476
RZ_API int rz_debug_continue_until_optype(RzDebug *dbg, int type, int over)
Definition: debug.c:1345
RZ_API RzRegItem * rz_reg_get_by_role(RzReg *reg, RzRegisterId role)
Definition: reg.c:154
@ RZ_REG_NAME_SN
Definition: rz_reg.h:70
RzCoreDebugSyscallHit syshit
Definition: rz_bind.h:38
int(* contsc)(RzDebug *dbg, int pid, int sc)
Definition: rz_debug.h:388

References rz_debug_plugin_t::contsc, rz_core_bind_t::core, rz_debug_t::corebind, rz_debug_t::cur, dbg, eprintf, i, NULL, rz_debug_t::pid, reg, rz_debug_t::reg, RZ_ANALYSIS_OP_TYPE_SWI, rz_cons_singleton(), rz_debug_continue_until_optype(), rz_debug_is_dead(), RZ_DEBUG_REASON_DEAD, RZ_DEBUG_REASON_STEP, rz_debug_reg_sync(), rz_debug_step(), rz_debug_wait(), rz_reg_get_by_role(), RZ_REG_NAME_SN, RZ_REG_TYPE_GPR, sc, show_syscall(), and rz_core_bind_t::syshit.

Referenced by cmd_debug_cont_syscall(), and rz_debug_continue_syscall().

◆ rz_debug_continue_until()

RZ_API int rz_debug_continue_until ( RzDebug dbg,
ut64  addr 
)

Definition at line 1434 of file debug.c.

1434  {
1435  return rz_debug_continue_until_internal(dbg, addr, true);
1436 }
static int rz_debug_continue_until_internal(RzDebug *dbg, ut64 addr, bool block)
Definition: debug.c:1402

References addr, dbg, and rz_debug_continue_until_internal().

Referenced by do_debug_trace_calls(), and rz_debug_step_over().

◆ rz_debug_continue_until_internal()

static int rz_debug_continue_until_internal ( RzDebug dbg,
ut64  addr,
bool  block 
)
static

Definition at line 1402 of file debug.c.

1402  {
1403  if (rz_debug_is_dead(dbg)) {
1404  return false;
1405  }
1406  // Check if there was another breakpoint set at addr
1407  bool has_bp = rz_bp_get_in(dbg->bp, addr, RZ_PERM_X) != NULL;
1408  if (!has_bp) {
1409  rz_bp_add_sw(dbg->bp, addr, 0, RZ_PERM_X);
1410  }
1411 
1412  // Continue until the bp is reached
1413  dbg->reason.type = 0;
1414  for (;;) {
1415  if (rz_debug_is_dead(dbg) || dbg->reason.type) {
1416  break;
1417  }
1419  if (pc == addr) {
1420  break;
1421  }
1422  if (block && rz_bp_get_at(dbg->bp, pc)) {
1423  break;
1424  }
1426  }
1427  // Clean up if needed
1428  if (!has_bp) {
1429  rz_bp_del(dbg->bp, addr);
1430  }
1431  return true;
1432 }
RZ_API bool rz_bp_del(RzBreakpoint *bp, ut64 addr)
Definition: bp.c:315
RZ_API int rz_debug_continue(RzDebug *dbg)
Definition: debug.c:1332

References addr, rz_debug_t::bp, dbg, rz_reg_t::name, NULL, pc, rz_debug_t::reason, rz_debug_t::reg, rz_bp_add_sw(), rz_bp_del(), rz_bp_get_at(), rz_bp_get_in(), rz_debug_continue(), rz_debug_is_dead(), rz_debug_reg_get(), RZ_PERM_X, RZ_REG_NAME_PC, rz_debug_reason_t::type, and ut64().

Referenced by rz_debug_continue_until(), and rz_debug_continue_until_nonblock().

◆ rz_debug_continue_until_nonblock()

RZ_API int rz_debug_continue_until_nonblock ( RzDebug dbg,
ut64  addr 
)

Definition at line 1438 of file debug.c.

1438  {
1439  return rz_debug_continue_until_internal(dbg, addr, false);
1440 }

References addr, dbg, and rz_debug_continue_until_internal().

◆ rz_debug_continue_until_nontraced()

RZ_API int rz_debug_continue_until_nontraced ( RzDebug dbg)

Definition at line 1340 of file debug.c.

1340  {
1341  eprintf("TODO\n");
1342  return false;
1343 }

References eprintf.

◆ rz_debug_continue_until_optype()

RZ_API int rz_debug_continue_until_optype ( RzDebug dbg,
int  type,
int  over 
)

Definition at line 1345 of file debug.c.

1345  {
1346  int ret, n = 0;
1347  ut64 pc, buf_pc = 0;
1348  RzAnalysisOp op;
1349  ut8 buf[DBG_BUF_SIZE];
1350 
1351  if (rz_debug_is_dead(dbg)) {
1352  return false;
1353  }
1354 
1355  if (!dbg->analysis || !dbg->reg) {
1356  eprintf("Undefined pointer at dbg->analysis\n");
1357  return false;
1358  }
1359 
1360  rz_debug_step(dbg, 1);
1362 
1363  // Initial refill
1365  dbg->iob.read_at(dbg->iob.io, buf_pc, buf, sizeof(buf));
1366 
1367  // step first, we don't want to check current optype
1368  for (;;) {
1369  if (!rz_debug_reg_sync(dbg, RZ_REG_TYPE_GPR, false)) {
1370  break;
1371  }
1372 
1374  // Try to keep the buffer full
1375  if (pc - buf_pc > sizeof(buf)) {
1376  buf_pc = pc;
1377  dbg->iob.read_at(dbg->iob.io, buf_pc, buf, sizeof(buf));
1378  }
1379  // Analyze the opcode
1380  if (rz_analysis_op(dbg->analysis, &op, pc, buf + (pc - buf_pc), sizeof(buf) - (pc - buf_pc), RZ_ANALYSIS_OP_MASK_BASIC) < 1) {
1381  eprintf("Decode error at %" PFMT64x "\n", pc);
1382  return false;
1383  }
1384  if (op.type == type) {
1385  break;
1386  }
1387  // Step over and repeat
1388  ret = over
1389  ? rz_debug_step_over(dbg, 1)
1390  : rz_debug_step(dbg, 1);
1391 
1392  if (!ret) {
1393  eprintf("rz_debug_step: failed\n");
1394  break;
1395  }
1396  n++;
1397  }
1398 
1399  return n;
1400 }
ut8 op
Definition: 6502dis.c:13
RZ_API int rz_debug_step_over(RzDebug *dbg, int steps)
Definition: debug.c:1033
#define DBG_BUF_SIZE
Definition: debug.c:16
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17

References rz_debug_t::analysis, dbg, DBG_BUF_SIZE, eprintf, rz_io_bind_t::io, rz_debug_t::iob, n, rz_reg_t::name, op, pc, PFMT64x, rz_io_bind_t::read_at, rz_debug_t::reg, rz_analysis_op(), RZ_ANALYSIS_OP_MASK_BASIC, rz_debug_is_dead(), rz_debug_reg_get(), rz_debug_reg_sync(), rz_debug_step(), rz_debug_step_over(), RZ_REG_NAME_PC, RZ_REG_TYPE_GPR, type, and ut64().

Referenced by rz_cmd_debug_continue_call_handler(), rz_cmd_debug_continue_ret_handler(), rz_cmd_debug_continue_unknown_call_handler(), rz_core_debug_single_step_over(), and rz_debug_continue_syscalls().

◆ rz_debug_detach()

RZ_API int rz_debug_detach ( RzDebug dbg,
int  pid 
)

Definition at line 583 of file debug.c.

583  {
584  int ret = 0;
585  if (dbg->cur && dbg->cur->detach) {
586  ret = dbg->cur->detach(dbg, pid);
587  if (dbg->pid == pid) {
588  dbg->pid = -1;
589  dbg->tid = -1;
590  }
591  }
592  return ret;
593 }
int(* detach)(RzDebug *dbg, int pid)
Definition: rz_debug.h:373

References rz_debug_t::cur, dbg, rz_debug_plugin_t::detach, rz_debug_t::pid, pid, and rz_debug_t::tid.

Referenced by cmd_debug_pid(), rz_core_debug_process_close(), rz_core_file_reopen(), and rz_main_rizin().

◆ rz_debug_drx_at()

static int rz_debug_drx_at ( RzDebug dbg,
ut64  addr 
)
static

Definition at line 50 of file debug.c.

50  {
51  if (dbg && dbg->cur && dbg->cur->drx) {
52  return dbg->cur->drx(dbg, 0, addr, 0, 0, 0, DRX_API_GET_BP);
53  }
54  return -1;
55 }
@ DRX_API_GET_BP
Definition: rz_drx.h:6
int(* drx)(RzDebug *dbg, int n, ut64 addr, int size, int rwx, int g, int api_type)
Definition: rz_debug.h:402

References addr, rz_debug_t::cur, dbg, rz_debug_plugin_t::drx, and DRX_API_GET_BP.

Referenced by rz_debug_bp_hit().

◆ rz_debug_drx_list()

RZ_API void rz_debug_drx_list ( RzDebug dbg)

Definition at line 1662 of file debug.c.

1662  {
1663  if (dbg && dbg->cur && dbg->cur->drx) {
1664  dbg->cur->drx(dbg, 0, 0, 0, 0, 0, DRX_API_LIST);
1665  }
1666 }
@ DRX_API_LIST
Definition: rz_drx.h:5

References rz_debug_t::cur, dbg, rz_debug_plugin_t::drx, and DRX_API_LIST.

Referenced by rz_debug_drx_handler().

◆ rz_debug_drx_set()

RZ_API int rz_debug_drx_set ( RzDebug dbg,
int  idx,
ut64  addr,
int  len,
int  rwx,
int  g 
)

Definition at line 1668 of file debug.c.

1668  {
1669  if (dbg && dbg->cur && dbg->cur->drx) {
1670  return dbg->cur->drx(dbg, idx, addr, len, rwx, g, DRX_API_SET_BP);
1671  }
1672  return false;
1673 }
size_t len
Definition: 6502dis.c:15
struct @667 g
int idx
Definition: setup.py:197
@ DRX_API_SET_BP
Definition: rz_drx.h:7

References addr, rz_debug_t::cur, dbg, rz_debug_plugin_t::drx, DRX_API_SET_BP, g, setup::idx, and len.

Referenced by drx_add(), and rz_debug_drx_handler().

◆ rz_debug_drx_unset()

RZ_API int rz_debug_drx_unset ( RzDebug dbg,
int  idx 
)

Definition at line 1675 of file debug.c.

1675  {
1676  if (dbg && dbg->cur && dbg->cur->drx) {
1677  return dbg->cur->drx(dbg, idx, 0, -1, 0, 0, DRX_API_REMOVE_BP);
1678  }
1679  return false;
1680 }
@ DRX_API_REMOVE_BP
Definition: rz_drx.h:8

References rz_debug_t::cur, dbg, rz_debug_plugin_t::drx, DRX_API_REMOVE_BP, and setup::idx.

Referenced by drx_del(), linux_remove_fork_bps(), and rz_debug_drx_unset_handler().

◆ rz_debug_execute()

RZ_API ut64 rz_debug_execute ( RzDebug dbg,
const ut8 buf,
int  len,
int  restore 
)

Definition at line 510 of file debug.c.

510  {
511  int orig_sz;
512  ut8 stackbackup[4096];
513  ut8 *backup, *orig = NULL;
514  RzRegItem *ri, *risp, *ripc;
515  ut64 rsp, rpc, ra0 = 0LL;
516  if (rz_debug_is_dead(dbg)) {
517  return false;
518  }
521  if (ripc) {
523  orig = rz_reg_get_bytes(dbg->reg, RZ_REG_TYPE_ANY, &orig_sz);
524  if (!orig) {
525  eprintf("Cannot get register arena bytes\n");
526  return 0LL;
527  }
528  rpc = rz_reg_get_value(dbg->reg, ripc);
529  rsp = rz_reg_get_value(dbg->reg, risp);
530 
531  backup = malloc(len);
532  if (!backup) {
533  free(orig);
534  return 0LL;
535  }
536  dbg->iob.read_at(dbg->iob.io, rpc, backup, len);
537  dbg->iob.read_at(dbg->iob.io, rsp, stackbackup, len);
538 
539  rz_bp_add_sw(dbg->bp, rpc + len, 0, RZ_PERM_X);
540 
541  /* execute code here */
542  dbg->iob.write_at(dbg->iob.io, rpc, buf, len);
543  // rz_bp_add_sw (dbg->bp, rpc+len, 4, RZ_PERM_X);
545  // rz_bp_del (dbg->bp, rpc+len);
546  /* TODO: check if stopped in breakpoint or not */
547 
548  rz_bp_del(dbg->bp, rpc + len);
549  dbg->iob.write_at(dbg->iob.io, rpc, backup, len);
550  if (restore) {
551  dbg->iob.write_at(dbg->iob.io, rsp, stackbackup, len);
552  }
553 
556  ra0 = rz_reg_get_value(dbg->reg, ri);
557  if (restore) {
558  rz_reg_read_regs(dbg->reg, orig, orig_sz);
559  } else {
560  rz_reg_set_value(dbg->reg, ripc, rpc);
561  }
563  free(backup);
564  free(orig);
565  eprintf("ra0=0x%08" PFMT64x "\n", ra0);
566  } else {
567  eprintf("rz_debug_execute: Cannot get program counter\n");
568  }
569  return (ra0);
570 }
RZ_API bool rz_reg_read_regs(RzReg *reg, ut8 *buf, const int len)
Definition: arena.c:58
RZ_API ut8 * rz_reg_get_bytes(RzReg *reg, int type, int *size)
Definition: arena.c:8
void * malloc(size_t size)
Definition: malloc.c:123
RZ_API ut64 rz_reg_get_value(RzReg *reg, RzRegItem *item)
Definition: rvalue.c:114
@ RZ_REG_TYPE_ANY
Definition: rz_reg.h:35
@ RZ_REG_NAME_SP
Definition: rz_reg.h:44
@ RZ_REG_NAME_A0
Definition: rz_reg.h:49
RzIOWriteAt write_at
Definition: rz_io.h:241

References rz_debug_t::bp, dbg, eprintf, free(), rz_io_bind_t::io, rz_debug_t::iob, len, malloc(), rz_reg_t::name, NULL, PFMT64x, rz_io_bind_t::read_at, rz_debug_t::reg, rz_bp_add_sw(), rz_bp_del(), rz_debug_continue(), rz_debug_is_dead(), rz_debug_reg_sync(), RZ_PERM_X, rz_reg_get(), rz_reg_get_bytes(), rz_reg_get_value(), RZ_REG_NAME_A0, RZ_REG_NAME_PC, RZ_REG_NAME_SP, rz_reg_read_regs(), rz_reg_set_value(), RZ_REG_TYPE_ANY, RZ_REG_TYPE_GPR, ut64(), and rz_io_bind_t::write_at.

Referenced by rz_cmd_debug().

◆ rz_debug_frames()

RZ_API RzList* rz_debug_frames ( RzDebug dbg,
ut64  at 
)

Definition at line 1612 of file debug.c.

1612  {
1613  if (dbg && dbg->cur && dbg->cur->frames) {
1614  return dbg->cur->frames(dbg, at);
1615  }
1616  return NULL;
1617 }
RzList *(* frames)(RzDebug *dbg, ut64 at)
Definition: rz_debug.h:389

References rz_debug_t::cur, dbg, rz_debug_plugin_t::frames, and NULL.

Referenced by iter_dbt_commands(), rz_cmd_debug_display_bt_ascii_handler(), rz_cmd_debug_display_bt_local_vars_handler(), rz_cmd_debug_display_bt_oneline_handler(), rz_core_cmd_foreach(), and rz_core_debug_backtraces().

◆ rz_debug_free()

RZ_API RzDebug* rz_debug_free ( RzDebug dbg)

Definition at line 416 of file debug.c.

416  {
417  if (dbg) {
419  rz_bp_free(dbg->bp);
420  free(dbg->snap_path);
424  rz_num_free(dbg->num);
425  sdb_free(dbg->sgnls);
427  ht_up_free(dbg->tracenodes);
430  free(dbg->btalgo);
434  dbg->trace = NULL;
435  rz_egg_free(dbg->egg);
436  rz_reg_free(dbg->reg);
437  free(dbg->arch);
438  free(dbg->glob_libs);
439  free(dbg->glob_unlibs);
440  free(dbg);
441  }
442  return NULL;
443 }
RZ_API RzBreakpoint * rz_bp_free(RzBreakpoint *bp)
Definition: bp.c:48
RZ_API void rz_debug_session_free(RzDebugSession *session)
Definition: dsession.c:11
RZ_API void rz_egg_free(RzEgg *egg)
Definition: egg.c:111
RZ_API void rz_hash_free(RzHash *rh)
Definition: hash.c:597
RZ_API void rz_analysis_op_free(void *op)
Definition: op.c:61
RZ_API void rz_reg_free(RzReg *reg)
Definition: reg.c:279
RZ_API void rz_num_free(RzNum *num)
Definition: unum.c:87
RZ_API void rz_tree_free(RTree *t)
Definition: tree.c:76
RZ_API bool sdb_free(Sdb *s)
Definition: sdb.c:206
RzList * maps_user
Definition: rz_debug.h:307
RzList * threads
Definition: rz_debug.h:251
RzHash * hash
Definition: rz_debug.h:303
char * snap_path
Definition: rz_debug.h:289
char * glob_unlibs
Definition: rz_debug.h:270
RzEgg * egg
Definition: rz_debug.h:318
RTree * tree
Definition: rz_debug.h:283
RzAnalysisOp * cur_op
Definition: rz_debug.h:310
char * glob_libs
Definition: rz_debug.h:269
char * arch
Definition: rz_debug.h:242
Sdb * sgnls
Definition: rz_debug.h:313
HtUP * tracenodes
Definition: rz_debug.h:282
RzList * call_frames
Definition: rz_debug.h:284
RzList * plugins
Definition: rz_debug.h:297
char * btalgo
Definition: rz_debug.h:258
RZ_API void rz_debug_trace_free(RzDebugTrace *trace)
Definition: trace.c:29

References rz_debug_t::arch, rz_debug_t::bp, rz_debug_t::btalgo, rz_debug_t::call_frames, rz_debug_t::cur_op, dbg, rz_debug_t::egg, free(), rz_debug_t::glob_libs, rz_debug_t::glob_unlibs, rz_debug_t::hash, rz_debug_t::maps, rz_debug_t::maps_user, NULL, rz_debug_t::num, rz_debug_t::plugins, rz_debug_t::reg, rz_analysis_op_free(), rz_bp_free(), rz_debug_session_free(), rz_debug_trace_free(), rz_egg_free(), rz_hash_free(), rz_list_free(), rz_num_free(), rz_reg_free(), rz_tree_free(), sdb_free(), rz_debug_t::session, rz_debug_t::sgnls, rz_debug_t::snap_path, rz_debug_t::threads, rz_debug_t::trace, rz_debug_t::tracenodes, and rz_debug_t::tree.

Referenced by rz_core_fini().

◆ rz_debug_get_baddr()

RZ_API ut64 rz_debug_get_baddr ( RzDebug dbg,
const char *  file 
)

Definition at line 1682 of file debug.c.

1682  {
1683  if (!dbg || !dbg->iob.io || !dbg->iob.io->desc) {
1684  return 0LL;
1685  }
1686  if (!strcmp(dbg->iob.io->desc->plugin->name, "gdb")) { // this is very bad
1687  // Tell gdb that we want baddr, not full mem map
1688  dbg->iob.system(dbg->iob.io, "baddr");
1689  }
1690  int pid = rz_io_desc_get_pid(dbg->iob.io->desc);
1691  int tid = rz_io_desc_get_tid(dbg->iob.io->desc);
1692  if (pid < 0 || tid < 0) {
1693  return 0LL;
1694  }
1695  if (rz_debug_attach(dbg, pid) == -1) {
1696  return 0LL;
1697  }
1698 #if __WINDOWS__
1699  ut64 base;
1700  bool ret = rz_io_desc_get_base(dbg->iob.io->desc, &base);
1701  if (ret) {
1702  return base;
1703  }
1704 #endif
1705  RzListIter *iter;
1706  RzDebugMap *map;
1707  rz_debug_select(dbg, pid, tid);
1709  char *abspath = rz_sys_pid_to_path(pid);
1710 #if !__WINDOWS__
1711  if (!abspath) {
1712  abspath = rz_file_abspath(file);
1713  }
1714 #endif
1715  if (!abspath) {
1716  abspath = strdup(file);
1717  }
1718  if (abspath) {
1719  rz_list_foreach (dbg->maps, iter, map) {
1720  if (!strcmp(abspath, map->name)) {
1721  free(abspath);
1722  return map->addr;
1723  }
1724  }
1725  free(abspath);
1726  }
1727  // fallback resolution (osx/w32?)
1728  // we assume maps to be loaded in order, so lower addresses come first
1729  rz_list_foreach (dbg->maps, iter, map) {
1730  if (map->perm == 5) { // r-x
1731  return map->addr;
1732  }
1733  }
1734  return 0LL;
1735 }
RZ_API int rz_debug_attach(RzDebug *dbg, int pid)
Definition: debug.c:445
RZ_API char * rz_file_abspath(const char *file)
Definition: file.c:267
RZ_API int rz_io_desc_get_tid(RzIODesc *desc)
Definition: io_desc.c:327
RZ_API int rz_io_desc_get_pid(RzIODesc *desc)
Definition: io_desc.c:310
RZ_API bool rz_io_desc_get_base(RzIODesc *desc, ut64 *base)
Definition: io_desc.c:344
RZ_API char * rz_sys_pid_to_path(int pid)
Definition: sys.c:920
Definition: gzappend.c:170
RzIOSystem system
Definition: rz_io.h:242
struct rz_io_plugin_t * plugin
Definition: rz_io.h:103
const char * name
Definition: rz_io.h:115
struct rz_io_desc_t * desc
Definition: rz_io.h:60

References dbg, rz_io_t::desc, free(), rz_io_bind_t::io, rz_debug_t::iob, map(), rz_debug_t::maps, rz_io_plugin_t::name, pid, rz_io_desc_t::plugin, rz_debug_attach(), rz_debug_map_sync(), rz_debug_select(), rz_file_abspath(), rz_io_desc_get_base(), rz_io_desc_get_pid(), rz_io_desc_get_tid(), rz_sys_pid_to_path(), strdup(), rz_io_bind_t::system, and ut64().

Referenced by num_callback(), rz_cmd_debug(), rz_core_file_reopen(), rz_core_file_reopen_remote_debug(), rz_core_rtr_gdb_cb(), and rz_main_rizin().

◆ rz_debug_goto_cnum()

RZ_API bool rz_debug_goto_cnum ( RzDebug dbg,
ut32  cnum 
)

Definition at line 1110 of file debug.c.

1110  {
1111  if (cnum > dbg->session->maxcnum) {
1112  eprintf("Error: out of cnum range\n");
1113  return false;
1114  }
1115  dbg->session->cnum = cnum;
1117 
1118  return true;
1119 }
RZ_API void rz_debug_session_restore_reg_mem(RzDebug *dbg, ut32 cnum)
Definition: dsession.c:173

References rz_debug_session_t::cnum, dbg, eprintf, rz_debug_session_t::maxcnum, rz_debug_session_restore_reg_mem(), and rz_debug_t::session.

Referenced by rz_debug_continue_back(), rz_debug_continue_kill(), rz_debug_step_back(), and rz_debug_step_cnum().

◆ rz_debug_info()

RZ_API RzDebugInfo* rz_debug_info ( RzDebug dbg,
const char *  arg 
)

Definition at line 18 of file debug.c.

18  {
19  if (!dbg || !dbg->cur || !dbg->cur->info) {
20  return NULL;
21  }
22  if (dbg->pid < 0) {
23  return NULL;
24  }
25  return dbg->cur->info(dbg, arg);
26 }
RzDebugInfo *(* info)(RzDebug *dbg, const char *arg)
Definition: rz_debug.h:370

References rz_debug_t::cur, dbg, rz_debug_plugin_t::info, NULL, and rz_debug_t::pid.

Referenced by rz_cmd_debug().

◆ rz_debug_info_free()

RZ_API void rz_debug_info_free ( RzDebugInfo rdi)

Definition at line 28 of file debug.c.

28  {
29  if (rdi) {
30  free(rdi->cwd);
31  free(rdi->exe);
32  free(rdi->cmdline);
33  free(rdi->libname);
34  free(rdi->usr);
35  free(rdi);
36  }
37 }

References free(), and rdi.

Referenced by rz_cmd_debug().

◆ rz_debug_is_dead()

RZ_API bool rz_debug_is_dead ( RzDebug dbg)

Definition at line 1632 of file debug.c.

1632  {
1633  if (!dbg->cur) {
1634  return false;
1635  }
1636  // workaround for debug.io.. should be generic
1637  if (!strcmp(dbg->cur->name, "io")) {
1638  return false;
1639  }
1640  bool is_dead = (dbg->pid == -1 && strncmp(dbg->cur->name, "gdb", 3)) || (dbg->reason.type == RZ_DEBUG_REASON_DEAD);
1641  if (dbg->pid > 0 && dbg->cur && dbg->cur->kill) {
1642  is_dead = !dbg->cur->kill(dbg, dbg->pid, false, 0);
1643  }
1644 #if 0
1645  if (!is_dead && dbg->cur && dbg->cur->kill) {
1646  is_dead = !dbg->cur->kill (dbg, dbg->pid, false, 0);
1647  }
1648 #endif
1649  if (is_dead) {
1651  }
1652  return is_dead;
1653 }
const char * name
Definition: rz_debug.h:359

References rz_debug_t::cur, dbg, rz_debug_plugin_t::kill, rz_debug_plugin_t::name, rz_debug_t::pid, rz_debug_t::reason, RZ_DEBUG_REASON_DEAD, and rz_debug_reason_t::type.

Referenced by debug_trace_calls(), do_debug_trace_calls(), rz_cmd_debug_start_trace_session_handler(), rz_cmd_debug_step_cond_handler(), rz_core_debug_continue_until(), rz_core_debug_map_update_flags(), rz_core_debug_step_until_frame(), rz_core_file_reopen(), rz_debug_can_kill(), rz_debug_continue_kill(), rz_debug_continue_syscalls(), rz_debug_continue_until_internal(), rz_debug_continue_until_optype(), rz_debug_execute(), rz_debug_kill(), rz_debug_reg_sync(), rz_debug_step(), rz_debug_step_hard(), rz_debug_step_over(), rz_debug_step_soft(), rz_debug_wait(), step_until(), step_until_esil(), step_until_flag(), step_until_inst(), and step_until_optype().

◆ rz_debug_kill()

RZ_API int rz_debug_kill ( RzDebug dbg,
int  pid,
int  tid,
int  sig 
)

Definition at line 1598 of file debug.c.

1598  {
1599  if (rz_debug_is_dead(dbg)) {
1600  return false;
1601  }
1602  if (dbg->cur && dbg->cur->kill) {
1603  if (pid > 0) {
1604  return dbg->cur->kill(dbg, pid, tid, sig);
1605  }
1606  return -1;
1607  }
1608  eprintf("Backend does not implement kill()\n");
1609  return false;
1610 }

References rz_debug_t::cur, dbg, eprintf, rz_debug_plugin_t::kill, pid, and rz_debug_is_dead().

Referenced by cmd_debug_pid(), rz_cmd_debug(), rz_core_debug_kill(), rz_core_debug_process_close(), rz_core_file_reopen(), and rz_main_rizin().

◆ rz_debug_map_protect()

RZ_API int rz_debug_map_protect ( RzDebug dbg,
ut64  addr,
int  size,
int  perms 
)

Definition at line 1655 of file debug.c.

1655  {
1656  if (dbg && dbg->cur && dbg->cur->map_protect) {
1657  return dbg->cur->map_protect(dbg, addr, size, perms);
1658  }
1659  return false;
1660 }
voidpf void uLong size
Definition: ioapi.h:138
int(* map_protect)(RzDebug *dbg, ut64 addr, int size, int perms)
Definition: rz_debug.h:401

References addr, rz_debug_t::cur, dbg, and rz_debug_plugin_t::map_protect.

Referenced by rz_debug_memory_permission_handler().

◆ rz_debug_new()

Definition at line 359 of file debug.c.

359  {
360  rz_return_val_if_fail(bp_ctx, NULL);
362  if (!dbg) {
363  return NULL;
364  }
365  // RZ_SYS_ARCH
367  dbg->bits = RZ_SYS_BITS;
368  dbg->trace_forks = 1;
369  dbg->forked_pid = -1;
370  dbg->main_pid = -1;
371  dbg->n_threads = 0;
372  dbg->trace_clone = 0;
373  dbg->egg = rz_egg_new();
375  dbg->trace_aftersyscall = true;
376  dbg->follow_child = false;
377  RZ_FREE(dbg->btalgo);
378  dbg->trace_execs = 0;
379  dbg->analysis = NULL;
380  dbg->pid = -1;
381  dbg->tid = -1;
382  dbg->tree = rz_tree_new();
383  dbg->tracenodes = ht_up_new(NULL, free_tracenodes_kv, NULL);
384  dbg->swstep = 0;
385  dbg->stop_all_threads = false;
387  dbg->cb_printf = (void *)printf;
388  dbg->reg = rz_reg_new();
390  dbg->cur = NULL;
391  dbg->plugin_data = NULL;
392  dbg->threads = NULL;
393  dbg->hitinfo = 1;
394  /* TODO: needs a redesign? */
397  dbg->q_regs = NULL;
398  dbg->call_frames = NULL;
399  dbg->main_arena_resolved = false;
400  dbg->glibc_version = 231; /* default version ubuntu 20 */
402  dbg->bp = rz_bp_new(bp_ctx);
404  dbg->bp->iob.init = false;
405  dbg->bp->baddr = 0;
407  dbg->hash = rz_hash_new();
408  return dbg;
409 }
RZ_API RzBreakpoint * rz_bp_new(RZ_BORROW RZ_NONNULL RzBreakpointContext *ctx)
Definition: bp.c:26
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
RZ_API RzList * rz_debug_map_list_new(void)
Definition: dmap.c:83
RZ_API ut64 rz_debug_num_callback(RzNum *userptr, const char *str, int *ok)
Definition: dreg.c:104
RZ_API void rz_debug_signal_init(RzDebug *dbg)
Definition: dsignal.c:54
RZ_API RzEgg * rz_egg_new(void)
Definition: egg.c:44
RZ_API bool rz_egg_setup(RzEgg *egg, const char *arch, int bits, int endian, const char *os)
Definition: egg.c:139
RZ_API RzHash * rz_hash_new(void)
Definition: hash.c:585
void free_tracenodes_kv(HtUPKv *kv)
Definition: debug.c:355
static const char * rz_debug_str_callback(RzNum *userptr, ut64 off, int *ok)
Definition: debug.c:349
RZ_API void rz_debug_plugin_init(RzDebug *dbg)
Definition: plugin.c:9
RZ_API RzReg * rz_reg_new(void)
Definition: reg.c:286
RZ_API RzNum * rz_num_new(RzNumCallback cb, RzNumCallback2 cb2, void *ptr)
Definition: unum.c:75
RZ_API RTree * rz_tree_new(void)
Definition: tree.c:72
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_SYS_BITS
Definition: rz_types.h:520
#define RZ_SYS_ENDIAN
Definition: rz_types.h:521
#define RZ_SYS_ARCH
Definition: rz_types.h:519
#define RZ_SYS_OS
Definition: rz_types.h:587
#define RZ_FREE(x)
Definition: rz_types.h:369
RzIOBind iob
Definition: rz_bp.h:84
PrintfCallback cb_printf
Definition: rz_debug.h:292
int stop_all_threads
Definition: rz_debug.h:262
bool main_arena_resolved
Definition: rz_debug.h:320
int trace_execs
Definition: rz_debug.h:264
RzList * q_regs
Definition: rz_debug.h:287
int n_threads
Definition: rz_debug.h:250
int bits
Definition: rz_debug.h:243
bool nt_x86_xstate_supported
Track whether X86_FEATURE_XSAVE feature is supported on current kernel.
Definition: rz_debug.h:323
int trace_aftersyscall
Definition: rz_debug.h:265
void * plugin_data
Definition: rz_debug.h:296
int glibc_version
Definition: rz_debug.h:321
int trace_forks
Definition: rz_debug.h:263
int main_pid
Definition: rz_debug.h:246
int init
Definition: rz_io.h:231
RZ_API RzDebugTrace * rz_debug_trace_new(void)
Definition: trace.c:7

References rz_debug_t::analysis, rz_debug_t::arch, rz_bp_t::baddr, rz_debug_t::bits, rz_debug_t::bp, rz_debug_t::btalgo, rz_debug_t::call_frames, rz_debug_t::cb_printf, rz_debug_t::cur, dbg, rz_debug_t::egg, rz_debug_t::follow_child, rz_debug_t::forked_pid, free_tracenodes_kv(), rz_debug_t::glibc_version, rz_debug_t::hash, rz_debug_t::hitinfo, rz_io_bind_t::init, rz_bp_t::iob, rz_debug_t::main_arena_resolved, rz_debug_t::main_pid, rz_debug_t::maps, rz_debug_t::maps_user, rz_debug_t::n_threads, rz_debug_t::nt_x86_xstate_supported, NULL, rz_debug_t::num, rz_debug_t::pid, rz_debug_t::plugin_data, printf(), rz_debug_t::q_regs, rz_debug_t::reg, rz_bp_new(), rz_debug_map_list_new(), rz_debug_num_callback(), rz_debug_plugin_init(), rz_debug_signal_init(), rz_debug_str_callback(), rz_debug_trace_new(), rz_egg_new(), rz_egg_setup(), RZ_FREE, rz_hash_new(), RZ_NEW0, rz_num_new(), rz_reg_new(), rz_return_val_if_fail, RZ_SYS_ARCH, RZ_SYS_BITS, RZ_SYS_ENDIAN, RZ_SYS_OS, rz_tree_new(), rz_debug_t::stop_all_threads, strdup(), rz_debug_t::swstep, rz_debug_t::threads, rz_debug_t::tid, rz_debug_t::trace, rz_debug_t::trace_aftersyscall, rz_debug_t::trace_clone, rz_debug_t::trace_execs, rz_debug_t::trace_forks, rz_debug_t::tracenodes, and rz_debug_t::tree.

Referenced by rz_core_init().

◆ rz_debug_reason_to_string()

RZ_API const char* rz_debug_reason_to_string ( int  type)

Definition at line 639 of file debug.c.

639  {
640  switch (type) {
641  case RZ_DEBUG_REASON_DEAD: return "dead";
642  case RZ_DEBUG_REASON_ABORT: return "abort";
643  case RZ_DEBUG_REASON_SEGFAULT: return "segfault";
644  case RZ_DEBUG_REASON_NONE: return "none";
645  case RZ_DEBUG_REASON_SIGNAL: return "signal";
646  case RZ_DEBUG_REASON_BREAKPOINT: return "breakpoint";
647  case RZ_DEBUG_REASON_TRACEPOINT: return "tracepoint";
648  case RZ_DEBUG_REASON_READERR: return "read-error";
649  case RZ_DEBUG_REASON_WRITERR: return "write-error";
650  case RZ_DEBUG_REASON_DIVBYZERO: return "div-by-zero";
651  case RZ_DEBUG_REASON_ILLEGAL: return "illegal";
652  case RZ_DEBUG_REASON_UNKNOWN: return "unknown";
653  case RZ_DEBUG_REASON_ERROR: return "error";
654  case RZ_DEBUG_REASON_NEW_PID: return "new-pid";
655  case RZ_DEBUG_REASON_NEW_TID: return "new-tid";
656  case RZ_DEBUG_REASON_NEW_LIB: return "new-lib";
657  case RZ_DEBUG_REASON_EXIT_PID: return "exit-pid";
658  case RZ_DEBUG_REASON_EXIT_TID: return "exit-tid";
659  case RZ_DEBUG_REASON_EXIT_LIB: return "exit-lib";
660  case RZ_DEBUG_REASON_TRAP: return "trap";
661  case RZ_DEBUG_REASON_SWI: return "software-interrupt";
662  case RZ_DEBUG_REASON_INT: return "interrupt";
663  case RZ_DEBUG_REASON_FPU: return "fpu";
664  case RZ_DEBUG_REASON_STEP: return "step";
665  case RZ_DEBUG_REASON_USERSUSP: return "suspended-by-user";
666  }
667  return "unhandled";
668 }
@ RZ_DEBUG_REASON_WRITERR
Definition: rz_debug.h:100
@ RZ_DEBUG_REASON_READERR
Definition: rz_debug.h:97
@ RZ_DEBUG_REASON_ILLEGAL
Definition: rz_debug.h:102
@ RZ_DEBUG_REASON_UNKNOWN
Definition: rz_debug.h:103
@ RZ_DEBUG_REASON_USERSUSP
Definition: rz_debug.h:115
@ RZ_DEBUG_REASON_TRAP
Definition: rz_debug.h:111
@ RZ_DEBUG_REASON_ABORT
Definition: rz_debug.h:99
@ RZ_DEBUG_REASON_ERROR
Definition: rz_debug.h:104
@ RZ_DEBUG_REASON_FPU
Definition: rz_debug.h:114
@ RZ_DEBUG_REASON_SEGFAULT
Definition: rz_debug.h:93
@ RZ_DEBUG_REASON_SWI
Definition: rz_debug.h:112
@ RZ_DEBUG_REASON_DIVBYZERO
Definition: rz_debug.h:101
@ RZ_DEBUG_REASON_INT
Definition: rz_debug.h:113
@ RZ_DEBUG_REASON_SIGNAL
Definition: rz_debug.h:92

References RZ_DEBUG_REASON_ABORT, RZ_DEBUG_REASON_BREAKPOINT, RZ_DEBUG_REASON_DEAD, RZ_DEBUG_REASON_DIVBYZERO, RZ_DEBUG_REASON_ERROR, RZ_DEBUG_REASON_EXIT_LIB, RZ_DEBUG_REASON_EXIT_PID, RZ_DEBUG_REASON_EXIT_TID, RZ_DEBUG_REASON_FPU, RZ_DEBUG_REASON_ILLEGAL, RZ_DEBUG_REASON_INT, RZ_DEBUG_REASON_NEW_LIB, RZ_DEBUG_REASON_NEW_PID, RZ_DEBUG_REASON_NEW_TID, RZ_DEBUG_REASON_NONE, RZ_DEBUG_REASON_READERR, RZ_DEBUG_REASON_SEGFAULT, RZ_DEBUG_REASON_SIGNAL, RZ_DEBUG_REASON_STEP, RZ_DEBUG_REASON_SWI, RZ_DEBUG_REASON_TRACEPOINT, RZ_DEBUG_REASON_TRAP, RZ_DEBUG_REASON_UNKNOWN, RZ_DEBUG_REASON_USERSUSP, RZ_DEBUG_REASON_WRITERR, and type.

Referenced by rz_cmd_debug().

◆ rz_debug_recoil()

static int rz_debug_recoil ( RzDebug dbg,
RzDebugRecoilMode  rc_mode 
)
static

Definition at line 223 of file debug.c.

223  {
224  /* if bp_addr is not set, we must not have actually hit a breakpoint */
225  if (!dbg->reason.bp_addr) {
226  return rz_debug_bps_enable(dbg);
227  }
228 
229  /* don't do anything if we already are recoiling */
231  /* the first time recoil is called with swstep, we just need to
232  * look up the bp and step past it.
233  * the second time it's called, the new sw breakpoint should exist
234  * so we just restore all except what we originally hit and reset.
235  */
236  if (dbg->swstep) {
237  if (!rz_bp_restore_except(dbg->bp, true, dbg->reason.bp_addr)) {
238  return false;
239  }
240  return true;
241  }
242 
243  /* otherwise, avoid recursion */
244  return true;
245  }
246 
247  /* we have entered recoil! */
248  dbg->recoil_mode = rc_mode;
249 
250  /* step over the place with the breakpoint and let the caller resume */
251  if (rz_debug_step(dbg, 1) != 1) {
252  return false;
253  }
254 
255  /* when stepping away from a breakpoint during recoil in stepping mode,
256  * the rz_debug_bp_hit function tells us that it was called
257  * innapropriately by setting bp_addr back to zero. however, recoil_mode
258  * is still set. we use this condition to know not to proceed but
259  * pretend as if we had.
260  */
262  return true;
263  }
264  dbg->reason.bp_addr = 0;
265 
266  return rz_debug_bps_enable(dbg);
267 }
RZ_API bool rz_bp_restore_except(RzBreakpoint *bp, bool set, ut64 addr)
Definition: bp_io.c:37
static int rz_debug_bps_enable(RzDebug *dbg)
Definition: debug.c:200
@ RZ_DBG_RECOIL_STEP
Definition: rz_debug.h:82

References rz_debug_t::bp, rz_debug_reason_t::bp_addr, dbg, rz_debug_t::reason, rz_debug_t::recoil_mode, rz_bp_restore_except(), RZ_DBG_RECOIL_NONE, RZ_DBG_RECOIL_STEP, rz_debug_bps_enable(), rz_debug_step(), and rz_debug_t::swstep.

Referenced by rz_debug_continue_kill(), and rz_debug_step_hard().

◆ rz_debug_select()

RZ_API bool rz_debug_select ( RzDebug dbg,
int  pid,
int  tid 
)

Definition at line 595 of file debug.c.

595  {
596  ut64 pc = 0;
597  int prev_pid = dbg->pid;
598  int prev_tid = dbg->tid;
599 
600  if (pid < 0) {
601  return false;
602  }
603  if (tid < 0) {
604  tid = pid;
605  }
606 
607  if ((pid != dbg->pid || tid != dbg->tid) && dbg->verbose) {
608  eprintf("= attach %d %d\n", pid, tid);
609  }
610 
611  if (dbg->cur && dbg->cur->select && !dbg->cur->select(dbg, pid, tid)) {
612  return false;
613  }
614 
615  // Don't change the pid/tid if the plugin already modified it due to internal constraints
616  if (dbg->pid == prev_pid) {
617  dbg->pid = pid;
618  }
619  if (dbg->tid == prev_tid) {
620  dbg->tid = tid;
621  }
622 
623  rz_io_system(dbg->iob.io, sdb_fmt("pid %d", dbg->tid));
624 
625  // Synchronize with the current thread's data
626  if (dbg->corebind.core) {
627  RzCore *core = (RzCore *)dbg->corebind.core;
628 
629  rz_reg_arena_swap(core->dbg->reg, true);
631 
632  pc = rz_debug_reg_get(dbg, "PC");
633  core->offset = pc;
634  }
635 
636  return true;
637 }
RZ_API void rz_reg_arena_swap(RzReg *reg, int copy)
Definition: arena.c:196
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
RZ_API char * rz_io_system(RzIO *io, const char *cmd)
Definition: io.c:411
ut64 offset
Definition: rz_core.h:301
RzDebug * dbg
Definition: rz_core.h:329
int(* select)(RzDebug *dbg, int pid, int tid)
Definition: rz_debug.h:374
bool verbose
Definition: rz_debug.h:319

References rz_core_bind_t::core, rz_debug_t::corebind, rz_debug_t::cur, dbg, rz_core_t::dbg, eprintf, rz_io_bind_t::io, rz_debug_t::iob, rz_core_t::offset, pc, rz_debug_t::pid, pid, rz_debug_t::reg, rz_debug_reg_get(), rz_debug_reg_sync(), rz_io_system(), rz_reg_arena_swap(), RZ_REG_TYPE_ANY, sdb_fmt(), rz_debug_plugin_t::select, rz_debug_t::tid, ut64(), and rz_debug_t::verbose.

Referenced by cb_cfgdebug(), cmd_debug_pid(), core_file_do_load_for_debug(), DEFINE_HANDLE_TS_FCN_AND_SYMBOL(), linux_attach_new_process(), linux_handle_signals(), linux_remove_fork_bps(), rz_cmd_debug_continue_execution_handler(), rz_cmd_debug_continue_send_signal_handler(), rz_core_cmd_foreach(), rz_core_debug_attach(), rz_core_file_reopen(), rz_core_setup_debugger(), rz_debug_attach(), rz_debug_continue_kill(), rz_debug_get_baddr(), and w32_attach_new_process().

◆ rz_debug_set_arch()

RZ_API bool rz_debug_set_arch ( RzDebug dbg,
const char *  arch,
int  bits 
)

Definition at line 465 of file debug.c.

465  {
466  if (arch && dbg && dbg->cur) {
467  switch (bits) {
468  case 16:
469  if (dbg->cur->bits & RZ_SYS_BITS_16) {
471  }
472  break;
473  case 27:
474  if (dbg->cur->bits == 27) {
475  dbg->bits = 27;
476  }
477  break;
478  case 32:
479  if (dbg->cur->bits & RZ_SYS_BITS_32) {
481  }
482  break;
483  case 64:
485  break;
486  }
487  if (!dbg->cur->bits) {
488  dbg->bits = dbg->cur->bits;
489  } else if (!(dbg->cur->bits & dbg->bits)) {
491  if (!dbg->bits) {
493  }
494  if (!dbg->bits) {
496  }
497  }
498  free(dbg->arch);
499  dbg->arch = strdup(arch);
500  return true;
501  }
502  return false;
503 }
int bits(struct state *s, int need)
Definition: blast.c:72
cs_arch arch
Definition: cstool.c:13
@ 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

References rz_debug_t::arch, arch, rz_debug_t::bits, rz_debug_plugin_t::bits, bits(), rz_debug_t::cur, dbg, free(), RZ_SYS_BITS_16, RZ_SYS_BITS_32, RZ_SYS_BITS_64, and strdup().

Referenced by cb_asmarch(), cb_asmbits(), and rz_debug_use().

◆ rz_debug_start()

RZ_API int rz_debug_start ( RzDebug dbg,
const char *  cmd 
)

Definition at line 577 of file debug.c.

577  {
578  /* TODO: this argc/argv parser is done in rz_io */
579  // TODO: parse cmd and generate argc and argv
580  return false;
581 }

◆ rz_debug_startv()

RZ_API int rz_debug_startv ( struct rz_debug_t dbg,
int  argc,
char **  argv 
)

Definition at line 572 of file debug.c.

572  {
573  /* TODO : rz_debug_startv unimplemented */
574  return false;
575 }

◆ rz_debug_step()

RZ_API int rz_debug_step ( RzDebug dbg,
int  steps 
)

Definition at line 962 of file debug.c.

962  {
963  RzBreakpointItem *bp = NULL;
964  int ret, steps_taken = 0;
965 
966  /* who calls this without giving a positive number? */
967  if (steps < 1) {
968  steps = 1;
969  }
970 
971  if (!dbg || !dbg->cur) {
972  return steps_taken;
973  }
974 
975  if (rz_debug_is_dead(dbg)) {
976  return steps_taken;
977  }
978 
980 
981  if (dbg->session) {
982  if (dbg->session->cnum != dbg->session->maxcnum) {
983  steps_taken = rz_debug_step_cnum(dbg, steps);
984  }
985  }
986 
987  for (; steps_taken < steps; steps_taken++) {
989  dbg->session->cnum++;
990  dbg->session->maxcnum++;
991  dbg->session->bp = 0;
993  eprintf("trace_ins_before: failed\n");
994  }
995  }
996 
997  if (dbg->swstep) {
998  ret = rz_debug_step_soft(dbg);
999  } else {
1000  ret = rz_debug_step_hard(dbg, &bp);
1001  }
1002  if (!ret) {
1003  eprintf("Stepping failed!\n");
1004  return steps_taken;
1005  }
1006 
1008  if (!rz_debug_trace_ins_after(dbg)) {
1009  eprintf("trace_ins_after: failed\n");
1010  }
1012  dbg->session->bp = bp;
1013  }
1014 
1015  dbg->steps++;
1017  }
1018 
1019  return steps_taken;
1020 }
RZ_API int rz_debug_step_hard(RzDebug *dbg, RzBreakpointItem **pb)
Definition: debug.c:909
RZ_API int rz_debug_step_cnum(RzDebug *dbg, int steps)
Definition: debug.c:1131
RZ_API int rz_debug_step_soft(RzDebug *dbg)
Definition: debug.c:787
int steps
Definition: rz_debug.h:275
RZ_API bool rz_debug_trace_ins_after(RzDebug *dbg)
Definition: trace.c:110
RZ_API bool rz_debug_trace_ins_before(RzDebug *dbg)
Definition: trace.c:46

References rz_debug_session_t::bp, rz_debug_session_t::cnum, rz_debug_t::cur, dbg, eprintf, rz_debug_session_t::maxcnum, NULL, rz_debug_t::reason, rz_debug_session_t::reasontype, rz_debug_t::recoil_mode, RZ_DBG_RECOIL_NONE, rz_debug_is_dead(), RZ_DEBUG_REASON_STEP, rz_debug_step_cnum(), rz_debug_step_hard(), rz_debug_step_soft(), rz_debug_trace_ins_after(), rz_debug_trace_ins_before(), rz_debug_t::session, rz_debug_t::steps, rz_debug_t::swstep, and rz_debug_reason_t::type.

Referenced by cmd_dcu(), do_debug_trace_calls(), rz_cmd_debug_continue_mapped_io_handler(), rz_cmd_debug_step_cond_handler(), rz_cmd_debug_step_prog_handler(), rz_core_debug_continue_until(), rz_core_debug_step_one(), rz_debug_continue_kill(), rz_debug_continue_syscalls(), rz_debug_continue_until_optype(), rz_debug_esil_stepi(), rz_debug_recoil(), rz_debug_step_over(), step_line(), step_until(), step_until_esil(), step_until_flag(), step_until_inst(), and step_until_optype().

◆ rz_debug_step_back()

RZ_API int rz_debug_step_back ( RzDebug dbg,
int  steps 
)

Definition at line 1121 of file debug.c.

1121  {
1122  if (steps > dbg->session->cnum) {
1123  steps = dbg->session->cnum;
1124  }
1125  if (!rz_debug_goto_cnum(dbg, dbg->session->cnum - steps)) {
1126  return -1;
1127  }
1128  return steps;
1129 }

References rz_debug_session_t::cnum, dbg, rz_debug_goto_cnum(), and rz_debug_t::session.

Referenced by rz_core_debug_step_back().

◆ rz_debug_step_cnum()

RZ_API int rz_debug_step_cnum ( RzDebug dbg,
int  steps 
)

Definition at line 1131 of file debug.c.

1131  {
1132  if (steps > dbg->session->maxcnum - dbg->session->cnum) {
1133  steps = dbg->session->maxcnum - dbg->session->cnum;
1134  }
1135 
1136  rz_debug_goto_cnum(dbg, dbg->session->cnum + steps);
1137 
1138  return steps;
1139 }

References rz_debug_session_t::cnum, dbg, rz_debug_session_t::maxcnum, rz_debug_goto_cnum(), and rz_debug_t::session.

Referenced by rz_debug_step().

◆ rz_debug_step_hard()

RZ_API int rz_debug_step_hard ( RzDebug dbg,
RzBreakpointItem **  pb 
)

Definition at line 909 of file debug.c.

909  {
910  RzDebugReasonType reason;
911 
913  if (rz_debug_is_dead(dbg)) {
914  return false;
915  }
916 
917  /* only handle recoils when not already in recoil mode. */
919  /* handle the stage-2 of breakpoints */
921  return false;
922  }
923 
924  /* recoil already stepped once, so we don't step again. */
927  return true;
928  }
929  }
930 
931  if (!dbg->cur->step(dbg)) {
932  return false;
933  }
934 
935 #if __linux__
936  // Turn off continue_all_threads to make sure linux_dbg_wait
937  // only waits for one target for a single-step or breakpoint trap
938  bool prev_continue = dbg->continue_all_threads;
939  dbg->continue_all_threads = false;
940 #endif
941  reason = rz_debug_wait(dbg, pb);
942 #if __linux__
943  dbg->continue_all_threads = prev_continue;
944 #endif
945 
946  if (reason == RZ_DEBUG_REASON_DEAD || rz_debug_is_dead(dbg)) {
947  return false;
948  }
949  // Unset breakpoints before leaving
950  if (reason != RZ_DEBUG_REASON_BREAKPOINT &&
951  reason != RZ_DEBUG_REASON_COND &&
952  reason != RZ_DEBUG_REASON_TRACEPOINT) {
953  rz_bp_restore(dbg->bp, false);
954  }
955  /* TODO: handle better */
956  if (reason == RZ_DEBUG_REASON_ERROR) {
957  return false;
958  }
959  return true;
960 }
int(* step)(RzDebug *dbg)
Definition: rz_debug.h:381
bool continue_all_threads
Definition: rz_debug.h:272

References rz_debug_t::bp, rz_debug_t::continue_all_threads, rz_debug_t::cur, dbg, rz_debug_t::reason, rz_debug_t::recoil_mode, rz_bp_restore(), RZ_DBG_RECOIL_NONE, RZ_DBG_RECOIL_STEP, rz_debug_is_dead(), RZ_DEBUG_REASON_BREAKPOINT, RZ_DEBUG_REASON_COND, RZ_DEBUG_REASON_DEAD, RZ_DEBUG_REASON_ERROR, RZ_DEBUG_REASON_STEP, RZ_DEBUG_REASON_TRACEPOINT, rz_debug_recoil(), rz_debug_wait(), rz_debug_plugin_t::step, and rz_debug_reason_t::type.

Referenced by rz_debug_step().

◆ rz_debug_step_over()

RZ_API int rz_debug_step_over ( RzDebug dbg,
int  steps 
)

Definition at line 1033 of file debug.c.

1033  {
1034  RzAnalysisOp op;
1035  ut64 buf_pc, pc, ins_size;
1036  ut8 buf[DBG_BUF_SIZE];
1037  int steps_taken = 0;
1038 
1039  if (rz_debug_is_dead(dbg)) {
1040  return steps_taken;
1041  }
1042 
1043  if (steps < 1) {
1044  steps = 1;
1045  }
1046 
1047  if (dbg->cur && dbg->cur->step_over) {
1048  for (; steps_taken < steps; steps_taken++) {
1050  dbg->session->cnum++;
1051  dbg->session->maxcnum++;
1053  }
1054  if (!dbg->cur->step_over(dbg)) {
1055  return steps_taken;
1056  }
1059  }
1060  }
1061  return steps_taken;
1062  }
1063 
1064  if (!dbg->analysis || !dbg->reg) {
1065  return steps_taken;
1066  }
1067 
1068  // Initial refill
1070  dbg->iob.read_at(dbg->iob.io, buf_pc, buf, sizeof(buf));
1071 
1072  for (; steps_taken < steps; steps_taken++) {
1074  // Try to keep the buffer full
1075  if (pc - buf_pc > sizeof(buf)) {
1076  buf_pc = pc;
1077  dbg->iob.read_at(dbg->iob.io, buf_pc, buf, sizeof(buf));
1078  }
1079  // Analyze the opcode
1080  if (rz_analysis_op(dbg->analysis, &op, pc, buf + (pc - buf_pc), sizeof(buf) - (pc - buf_pc), RZ_ANALYSIS_OP_MASK_BASIC) < 1) {
1081  eprintf("debug-step-over: Decode error at %" PFMT64x "\n", pc);
1082  return steps_taken;
1083  }
1084  if (op.fail == -1) {
1085  ins_size = pc + op.size;
1086  } else {
1087  // Use op.fail here instead of pc+op.size to enforce analysis backends to fill in this field
1088  ins_size = op.fail;
1089  }
1090  // Skip over all the subroutine calls
1091  if (isStepOverable(op.type)) {
1092  if (!rz_debug_continue_until(dbg, ins_size)) {
1093  eprintf("Could not step over call @ 0x%" PFMT64x "\n", pc);
1094  return steps_taken;
1095  }
1097  // eprintf ("REP: skip to next instruction...\n");
1098  if (!rz_debug_continue_until(dbg, ins_size)) {
1099  eprintf("step over failed over rep\n");
1100  return steps_taken;
1101  }
1102  } else {
1103  rz_debug_step(dbg, 1);
1104  }
1105  }
1106 
1107  return steps_taken;
1108 }
static bool isStepOverable(ut64 opType)
Definition: debug.c:1022
RZ_API int rz_debug_continue_until(RzDebug *dbg, ut64 addr)
Definition: debug.c:1434
@ RZ_ANALYSIS_OP_PREFIX_REP
Definition: rz_analysis.h:348
@ RZ_ANALYSIS_OP_PREFIX_LOCK
Definition: rz_analysis.h:350
@ RZ_ANALYSIS_OP_PREFIX_REPNE
Definition: rz_analysis.h:349
int(* step_over)(RzDebug *dbg)
Definition: rz_debug.h:382

References rz_debug_t::analysis, rz_debug_session_t::cnum, rz_debug_t::cur, dbg, DBG_BUF_SIZE, eprintf, rz_io_bind_t::io, rz_debug_t::iob, isStepOverable(), rz_debug_session_t::maxcnum, rz_reg_t::name, op, pc, PFMT64x, rz_io_bind_t::read_at, rz_debug_t::recoil_mode, rz_debug_t::reg, rz_analysis_op(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_PREFIX_LOCK, RZ_ANALYSIS_OP_PREFIX_REP, RZ_ANALYSIS_OP_PREFIX_REPNE, RZ_DBG_RECOIL_NONE, rz_debug_continue_until(), rz_debug_is_dead(), rz_debug_reg_get(), rz_debug_step(), rz_debug_trace_ins_after(), rz_debug_trace_ins_before(), RZ_REG_NAME_PC, rz_debug_t::session, rz_debug_plugin_t::step_over, and ut64().

Referenced by rz_cmd_debug_step_prog_handler(), rz_core_debug_step_over(), rz_core_debug_step_until_frame(), rz_debug_continue_until_optype(), and step_until_inst().

◆ rz_debug_step_soft()

RZ_API int rz_debug_step_soft ( RzDebug dbg)

Definition at line 787 of file debug.c.

787  {
788  ut8 buf[32];
789  ut64 pc, sp, r;
790  ut64 next[2];
792  int br, i, ret;
793  union {
794  ut64 r64;
795  ut32 r32[2];
796  } sp_top;
797  union {
798  ut64 r64;
799  ut32 r32[2];
800  } memval;
801 
804  }
805 
806  if (rz_debug_is_dead(dbg)) {
807  return false;
808  }
809 
810  const bool has_lr_reg = rz_reg_get_name(dbg->reg, RZ_REG_NAME_LR);
811  const bool arch_ret_is_pop = !strcmp(dbg->arch, "arm") && dbg->bits <= RZ_SYS_BITS_32;
812 
815 
816  if (!dbg->iob.read_at) {
817  return false;
818  }
819  if (!dbg->iob.read_at(dbg->iob.io, pc, buf, sizeof(buf))) {
820  return false;
821  }
822  if (rz_analysis_op(dbg->analysis, &op, pc, buf, sizeof(buf), RZ_ANALYSIS_OP_MASK_BASIC) < 1) {
823  return false;
824  }
825  if (op.type == RZ_ANALYSIS_OP_TYPE_ILL) {
826  return false;
827  }
828  switch (op.type) {
830  if (arch_ret_is_pop && op.stackop == RZ_ANALYSIS_STACK_INC) {
831  dbg->iob.read_at(dbg->iob.io, sp - op.stackptr - 4, (ut8 *)&sp_top, 4);
832  next[0] = sp_top.r32[0];
833  } else if (has_lr_reg) {
835  } else {
836  dbg->iob.read_at(dbg->iob.io, sp, (ut8 *)&sp_top, 8);
837  next[0] = (dbg->bits <= RZ_SYS_BITS_32) ? sp_top.r32[0] : sp_top.r64;
838  }
839  br = 1;
840  break;
843  next[0] = op.jump;
844  next[1] = op.fail;
845  br = 2;
846  break;
849  next[0] = op.jump;
850  br = 1;
851  break;
854  r = rz_debug_reg_get(dbg, op.reg);
855  next[0] = r;
856  br = 1;
857  break;
860  r = rz_debug_reg_get(dbg, op.reg);
861  if (!dbg->iob.read_at(dbg->iob.io, r, (ut8 *)&memval, 8)) {
862  next[0] = op.addr + op.size;
863  } else {
864  next[0] = (dbg->bits <= RZ_SYS_BITS_32) ? memval.r32[0] : memval.r64;
865  }
866  br = 1;
867  break;
871  if (op.ireg) {
872  r = rz_debug_reg_get(dbg, op.ireg);
873  } else {
874  r = 0;
875  }
876  if (!dbg->iob.read_at(dbg->iob.io, r * op.scale + op.disp, (ut8 *)&memval, 8)) {
877  next[0] = op.addr + op.size;
878  } else {
879  next[0] = (dbg->bits <= RZ_SYS_BITS_32) ? memval.r32[0] : memval.r64;
880  }
881  br = 1;
882  break;
883  default:
884  next[0] = op.addr + op.size;
885  br = 1;
886  break;
887  }
888 
890  for (i = 0; i < br; i++) {
891  if (align > 1) {
892  next[i] = next[i] - (next[i] % align);
893  }
894  RzBreakpointItem *bpi = rz_bp_add_sw(dbg->bp, next[i], 0, RZ_PERM_X);
895  if (bpi) {
896  bpi->swstep = true;
897  }
898  }
899 
900  ret = rz_debug_continue(dbg);
901 
902  for (i = 0; i < br; i++) {
903  rz_bp_del(dbg->bp, next[i]);
904  }
905 
906  return ret;
907 }
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query)
Definition: analysis.c:449
#define r
Definition: crypto_rc6.c:12
uint32_t ut32
RZ_API const char * rz_reg_get_name(RzReg *reg, int role)
Definition: reg.c:147
#define RZ_ANALYSIS_ARCHINFO_ALIGN
Definition: rz_analysis.h:100
@ RZ_ANALYSIS_STACK_INC
Definition: rz_analysis.h:457
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_MJMP
Definition: rz_analysis.h:375
@ RZ_ANALYSIS_OP_TYPE_CCALL
Definition: rz_analysis.h:383
@ RZ_ANALYSIS_OP_TYPE_IRJMP
Definition: rz_analysis.h:372
@ RZ_ANALYSIS_OP_TYPE_RJMP
Definition: rz_analysis.h:370
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_IRCALL
Definition: rz_analysis.h:382
@ RZ_REG_NAME_LR
Definition: rz_reg.h:47
#define br(opcode, mask, lose, flags)
bool swstep
Definition: rz_bp.h:48
static int sp
Definition: z80asm.c:91

References rz_debug_t::analysis, rz_debug_t::arch, rz_debug_t::bits, rz_debug_t::bp, br, dbg, i, rz_io_bind_t::io, rz_debug_t::iob, rz_reg_t::name, op, pc, r, rz_io_bind_t::read_at, rz_debug_t::recoil_mode, rz_debug_t::reg, rz_analysis_archinfo(), RZ_ANALYSIS_ARCHINFO_ALIGN, rz_analysis_op(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CCALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_ILL, RZ_ANALYSIS_OP_TYPE_IRCALL, RZ_ANALYSIS_OP_TYPE_IRJMP, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_MJMP, RZ_ANALYSIS_OP_TYPE_RCALL, RZ_ANALYSIS_OP_TYPE_RET, RZ_ANALYSIS_OP_TYPE_RJMP, RZ_ANALYSIS_OP_TYPE_UCALL, RZ_ANALYSIS_OP_TYPE_UJMP, RZ_ANALYSIS_STACK_INC, rz_bp_add_sw(), rz_bp_del(), RZ_DBG_RECOIL_NONE, RZ_DBG_RECOIL_STEP, rz_debug_continue(), rz_debug_is_dead(), rz_debug_reg_get(), RZ_PERM_X, rz_reg_get_name(), RZ_REG_NAME_LR, RZ_REG_NAME_PC, RZ_REG_NAME_SP, RZ_SYS_BITS_32, sp, rz_bp_item_t::swstep, and ut64().

Referenced by rz_debug_step().

◆ rz_debug_stop()

RZ_API int rz_debug_stop ( RzDebug dbg)

Definition at line 458 of file debug.c.

458  {
459  if (dbg && dbg->cur && dbg->cur->stop) {
460  return dbg->cur->stop(dbg);
461  }
462  return false;
463 }
int(* stop)(RzDebug *dbg)
Definition: rz_debug.h:380

References rz_debug_t::cur, dbg, and rz_debug_plugin_t::stop.

Referenced by rz_core_static_debug_stop(), and rz_debug_wait().

◆ rz_debug_stop_reason()

RZ_API RzDebugReasonType rz_debug_stop_reason ( RzDebug dbg)

Definition at line 670 of file debug.c.

670  {
671  // TODO: return reason to stop debugging
672  // - new process
673  // - trap instruction
674  // - illegal instruction
675  // - fpu exception
676  // return dbg->reason
677  return dbg->reason.type;
678 }

References dbg, rz_debug_t::reason, and rz_debug_reason_t::type.

Referenced by rz_cmd_debug().

◆ rz_debug_str_callback()

static const char* rz_debug_str_callback ( RzNum userptr,
ut64  off,
int ok 
)
static

Definition at line 349 of file debug.c.

349  {
350  // RzDebug *dbg = (RzDebug *)userptr;
351  eprintf("rz_debug_str_callback has been called. this should not happen\n");
352  return NULL;
353 }

References eprintf, and NULL.

Referenced by rz_debug_new().

◆ rz_debug_syscall()

RZ_API int rz_debug_syscall ( RzDebug dbg,
int  num 
)

Definition at line 1583 of file debug.c.

1583  {
1584  bool ret = true;
1585  if (dbg->cur->contsc) {
1586  ret = dbg->cur->contsc(dbg, dbg->pid, num);
1587  }
1588  eprintf("TODO: show syscall information\n");
1589  /* rz_testc task? ala inject? */
1590  return (int)ret;
1591 }

References rz_debug_plugin_t::contsc, rz_debug_t::cur, dbg, eprintf, num, and rz_debug_t::pid.

◆ rz_debug_tracenodes_reset()

RZ_API void rz_debug_tracenodes_reset ( RzDebug dbg)

Definition at line 411 of file debug.c.

411  {
412  ht_up_free(dbg->tracenodes);
413  dbg->tracenodes = ht_up_new(NULL, free_tracenodes_kv, NULL);
414 }

References dbg, free_tracenodes_kv(), NULL, and rz_debug_t::tracenodes.

Referenced by rz_cmd_debug_traces_reset_handler().

◆ rz_debug_wait()

RZ_API RzDebugReasonType rz_debug_wait ( RzDebug dbg,
RzBreakpointItem **  bp 
)

Definition at line 685 of file debug.c.

685  {
687  if (!dbg) {
688  return reason;
689  }
690 
691  if (bp) {
692  *bp = NULL;
693  }
694  /* default to unknown */
696  if (rz_debug_is_dead(dbg)) {
697  return RZ_DEBUG_REASON_DEAD;
698  }
699 
700  /* if our debugger plugin has wait */
701  if (dbg->cur && dbg->cur->wait) {
702  reason = dbg->cur->wait(dbg, dbg->pid);
703  if (reason == RZ_DEBUG_REASON_DEAD) {
704  eprintf("\n==> Process finished\n\n");
706  .pid = dbg->pid
707  };
709  // XXX(jjd): TODO: handle fallback or something else
710  // rz_debug_select (dbg, -1, -1);
711  return RZ_DEBUG_REASON_DEAD;
712  }
713 
714 #if __linux__
715  // Letting other threads running will cause ptrace commands to fail
716  // when writing to the same process memory to set/unset breakpoints
717  // and is problematic in Linux.
718  if (dbg->continue_all_threads) {
720  }
721 #endif
722 
723  /* propagate errors from the plugin */
724  if (reason == RZ_DEBUG_REASON_ERROR) {
725  return RZ_DEBUG_REASON_ERROR;
726  }
727 
728  /* read general purpose registers */
729  if (!rz_debug_reg_sync(dbg, RZ_REG_TYPE_GPR, false)) {
730  return RZ_DEBUG_REASON_ERROR;
731  }
732 
733  bool libs_bp = (dbg->glob_libs || dbg->glob_unlibs) ? true : false;
734  /* if the underlying stop reason is a breakpoint, call the handlers */
735  if (reason == RZ_DEBUG_REASON_BREAKPOINT ||
736  reason == RZ_DEBUG_REASON_STEP ||
737  (libs_bp && ((reason == RZ_DEBUG_REASON_NEW_LIB) || (reason == RZ_DEBUG_REASON_EXIT_LIB)))) {
738  RzRegItem *pc_ri;
740  ut64 pc;
741 
742  /* get the program coounter */
743  pc_ri = rz_reg_get(dbg->reg, dbg->reg->name[RZ_REG_NAME_PC], -1);
744  if (!pc_ri) { /* couldn't find PC?! */
745  eprintf("Couldn't find PC!\n");
746  return RZ_DEBUG_REASON_ERROR;
747  }
748 
749  /* get the value */
750  pc = rz_reg_get_value(dbg->reg, pc_ri);
751 
752  if (!rz_debug_bp_hit(dbg, pc_ri, pc, &b)) {
753  return RZ_DEBUG_REASON_ERROR;
754  }
755 
756  if (bp) {
757  *bp = b;
758  }
759 
760  if (b && reason == RZ_DEBUG_REASON_STEP) {
762  }
763  /* if we hit a tracing breakpoint, we need to continue in
764  * whatever mode the user desired. */
765  if (dbg->corebind.core && b && b->cond) {
766  reason = RZ_DEBUG_REASON_COND;
767  }
768  if (b && b->trace) {
770  }
771  }
772 
773  dbg->reason.type = reason;
774  if (reason == RZ_DEBUG_REASON_SIGNAL && dbg->reason.signum != -1) {
775  /* handle signal on continuations here */
776  int what = rz_debug_signal_what(dbg, dbg->reason.signum);
777  const char *name = rz_signal_to_string(dbg->reason.signum);
778  if (name && strcmp("SIGTRAP", name)) {
779  rz_cons_printf("[+] signal %d aka %s received %d\n",
780  dbg->reason.signum, name, what);
781  }
782  }
783  }
784  return reason;
785 }
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API int rz_debug_stop(RzDebug *dbg)
Definition: debug.c:458
static int rz_debug_bp_hit(RzDebug *dbg, RzRegItem *pc_ri, ut64 pc, RzBreakpointItem **pb)
Definition: debug.c:66
RZ_API void rz_event_send(RzEvent *ev, int type, void *data)
Definition: event.c:115
@ RZ_EVENT_DEBUG_PROCESS_FINISHED
Definition: rz_event.h:41
Definition: z80asm.h:102
RzDebugReasonType(* wait)(RzDebug *dbg, int pid)
Definition: rz_debug.h:384
RzEvent * ev
Definition: rz_debug.h:302

References b, rz_debug_t::continue_all_threads, rz_core_bind_t::core, rz_debug_t::corebind, rz_debug_t::cur, dbg, eprintf, rz_debug_t::ev, rz_debug_t::glob_libs, rz_debug_t::glob_unlibs, rz_reg_t::name, NULL, pc, rz_debug_t::pid, rz_event_debug_process_finished_t::pid, rz_debug_t::reason, rz_debug_t::reg, rz_cons_printf(), rz_debug_bp_hit(), rz_debug_is_dead(), RZ_DEBUG_REASON_BREAKPOINT, RZ_DEBUG_REASON_COND, RZ_DEBUG_REASON_DEAD, RZ_DEBUG_REASON_ERROR, RZ_DEBUG_REASON_EXIT_LIB, RZ_DEBUG_REASON_NEW_LIB, RZ_DEBUG_REASON_SIGNAL, RZ_DEBUG_REASON_STEP, RZ_DEBUG_REASON_TRACEPOINT, RZ_DEBUG_REASON_UNKNOWN, rz_debug_reg_sync(), rz_debug_signal_what(), rz_debug_stop(), RZ_EVENT_DEBUG_PROCESS_FINISHED, rz_event_send(), rz_reg_get(), rz_reg_get_value(), RZ_REG_NAME_PC, RZ_REG_TYPE_GPR, rz_signal_to_string(), rz_debug_reason_t::signum, rz_debug_reason_t::type, ut64(), and rz_debug_plugin_t::wait.

Referenced by rz_debug_continue_kill(), rz_debug_continue_syscalls(), and rz_debug_step_hard().

◆ RZ_LIB_VERSION()

RZ_LIB_VERSION ( rz_debug  )

◆ show_syscall()

static int show_syscall ( RzDebug dbg,
const char *  sysreg 
)
static

Definition at line 1476 of file debug.c.

1476  {
1477  const char *sysname;
1478  char regname[32];
1479  int reg, i, args;
1480  RzSyscallItem *si;
1481  reg = (int)rz_debug_reg_get(dbg, sysreg);
1483  if (si) {
1484  sysname = si->name ? si->name : "unknown";
1485  args = si->args;
1486  } else {
1487  sysname = "unknown";
1488  args = 3;
1489  }
1490  eprintf("--> %s 0x%08" PFMT64x " syscall %d %s (", sysreg,
1491  rz_debug_reg_get(dbg, "PC"), reg, sysname);
1492  for (i = 0; i < args; i++) {
1493  ut64 val;
1494  snprintf(regname, sizeof(regname) - 1, "A%d", i);
1496  if (((st64)val < 0) && ((st64)val > -0xffff)) {
1497  eprintf("%" PFMT64d "%s", val, (i + 1 == args) ? "" : " ");
1498  } else {
1499  eprintf("0x%" PFMT64x "%s", val, (i + 1 == args) ? "" : " ");
1500  }
1501  }
1502  eprintf(")\n");
1504  return reg;
1505 }
si
ut16 val
Definition: armass64_const.h:6
snprintf
Definition: kernel.h:364
int args
Definition: mipsasm.c:18
#define PFMT64d
Definition: rz_types.h:394
#define st64
Definition: rz_types_base.h:10
static int
Definition: sfsocketcall.h:114
RzSyscall * syscall
Definition: rz_analysis.h:570
RZ_API void rz_syscall_item_free(RzSyscallItem *si)
Definition: syscall.c:325
RZ_API RzSyscallItem * rz_syscall_get(RzSyscall *s, int num, int swi)
Definition: syscall.c:345
static char * regname(int reg)
Definition: dis.c:71

References rz_debug_t::analysis, args, dbg, eprintf, i, int, PFMT64d, PFMT64x, reg, regname(), rz_debug_reg_get(), rz_syscall_get(), rz_syscall_item_free(), si, snprintf, st64, rz_analysis_t::syscall, ut64(), and val.

Referenced by rz_debug_continue_syscalls().