Rizin
unix-like reverse engineering framework and cli tools
disasm_stackptr.inc
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2019 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #define USE_BB_STACKPTR 0
5 #define USE_BB_LINEAR 1
6 
7 static void ds_update_stackptr(RzDisasmState *ds, RzAnalysisOp *op) {
8  if (!ds->show_stackptr) {
9  return;
10  }
11  ds->ostackptr = ds->stackptr;
12  switch (op->stackop) {
13 
15  ds->stackptr = 0;
16  break;
18  ds->stackptr += op->stackptr;
19  break;
20  default:
21  /* nothing to do here */
22  break;
23  }
24  /* XXX if we reset the stackptr 'ret 0x4' has not effect.
25  * Use RzAnalysisFunction->RzAnalysisOp->stackptr? */
26  if (op->type == RZ_ANALYSIS_OP_TYPE_RET) {
27  ds->stackptr = 0;
28  }
29 }
30 
31 static int _stackptr_range(RzDisasmState *ds, ut64 addr, ut64 addr_end, int stackptr, int *ostackptr) {
32  ut64 at = addr;
33  ut64 end = addr_end;
34  while (at < end) {
35  int sz = 1;
36  RzAnalysisOp *op = rz_core_analysis_op(ds->core, at, 0);
37  if (op) {
38  *ostackptr = stackptr;
39  switch (op->stackop) {
41  stackptr = 0;
42  break;
44  stackptr += op->stackptr;
45  break;
46  default:
47  /* nothing to do here */
48  break;
49  }
50  if (op->size > 0) {
51  sz = op->size;
52  }
54  }
55  at += sz;
56  }
57  return stackptr;
58 }
59 
60 static int ds_ostackptr_atfcn(RzDisasmState *ds, int *ostackptr) {
61  if (!ds->show_stackptr) {
62  return 0;
63  }
64 #if USE_BB_LINEAR
65  if (ds->at >= ds->fcn->addr) {
66  return _stackptr_range(ds, ds->fcn->addr, ds->at, 0, ostackptr);
67  }
68  return ds->stackptr;
69 #else
70  int stackptr = 0;
71  // SLOW, recursive emulation is more correct, but slow to find paths
72  // return stackptr;
73  ut64 addr = ds->at;
74  RzList *paths = rz_core_analysis_graph_to(ds->core, addr, 2);
75  if (paths) {
76  RzAnalysisBlock *bb;
77  RzList *path;
78  RzListIter *pathi;
79  RzListIter *bbi;
80  rz_list_foreach (paths, pathi, path) {
81  rz_list_foreach (path, bbi, bb) {
82  ut64 end = bb->addr + bb->size;
83  if (addr >= bb->addr && addr < bb->addr + bb->size) {
84  end = addr;
85  }
86  stackptr = _stackptr_range(ds, bb->addr, end, stackptr, ostackptr);
87  }
88  }
89  rz_list_free(paths);
90  }
91  return stackptr;
92 #endif
93 }
94 
95 static int ds_ostackptr_at(RzDisasmState *ds, int *ostackptr) {
96 #if USE_BB_STACKPTR
97  // XXX doesnt works because bb->stackptr returns the maximum increment of the bb instead of the initial stackptr value
98  *ostackptr = ds->ostackptr;
100  if (fcn) {
102  if (bb) {
103  return bb->stackptr;
104  } else {
106  }
107  }
108  return 0;
109 #else
110  if (ds->fcn) {
111  return ds_ostackptr_atfcn(ds, ostackptr);
112  }
113  *ostackptr = ds->ostackptr;
114  return ds->stackptr;
115 #endif
116 }
117 
118 static void ds_print_stackptr(RzDisasmState *ds) {
119  int ostackptr = 0;
120  int stackptr = ds_ostackptr_at(ds, &ostackptr);
121  if (ds->show_stackptr) {
122  rz_cons_printf("%5d%s", stackptr,
124  : stackptr > ostackptr ? "+"
125  : stackptr < ostackptr ? "-"
126  : " ");
127  ds_update_stackptr(ds, &ds->analysis_op);
128  }
129 }
RZ_API RzList * rz_core_analysis_graph_to(RzCore *core, ut64 addr, int n)
Definition: canalysis.c:2895
RZ_API RzAnalysisOp * rz_core_analysis_op(RzCore *core, ut64 addr, int mask)
Definition: canalysis.c:1033
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
static void ds_print_stackptr(RzDisasmState *ds)
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1687
RZ_API RzAnalysisBlock * rz_analysis_fcn_bbget_in(const RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr)
Definition: fcn.c:2042
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API void rz_analysis_op_free(void *op)
Definition: op.c:61
@ RZ_ANALYSIS_FCN_TYPE_NULL
Definition: rz_analysis.h:192
@ RZ_ANALYSIS_STACK_RESET
Definition: rz_analysis.h:460
@ RZ_ANALYSIS_STACK_ALIGN
Definition: rz_analysis.h:461
@ RZ_ANALYSIS_STACK_INC
Definition: rz_analysis.h:457
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
#define rz_warn_if_reached()
Definition: rz_assert.h:29
RzAnalysisOp analysis_op
Definition: disasm.c:278
int stackptr
Definition: disasm.c:271
int ostackptr
Definition: disasm.c:271
bool show_stackptr
Definition: disasm.c:177
RzAnalysisFunction * fcn
Definition: disasm.c:279
RzCore * core
Definition: disasm.c:87
RzAnalysisStackOp stackop
Definition: rz_analysis.h:817
RzAnalysis * analysis
Definition: rz_core.h:322
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58