Rizin
unix-like reverse engineering framework and cli tools
function.c File Reference
#include <rz_analysis.h>

Go to the source code of this file.

Classes

struct  InstVarsRelocateCtx
 

Macros

#define MIN_MATCH_LEN   4
 

Functions

static bool get_functions_block_cb (RzAnalysisBlock *block, void *user)
 
RZ_API RzListrz_analysis_get_functions_in (RzAnalysis *analysis, ut64 addr)
 
static bool __fcn_exists (RzAnalysis *analysis, const char *name, ut64 addr)
 
RZ_IPI void rz_analysis_var_free (RzAnalysisVar *av)
 
static void inst_vars_kv_free (HtUPKv *kv)
 
static void labels_kv_free (HtUPKv *kv)
 
static void label_addrs_kv_free (HtPPKv *kv)
 
RZ_API RzAnalysisFunctionrz_analysis_function_new (RzAnalysis *analysis)
 
RZ_API void rz_analysis_function_free (void *_fcn)
 
RZ_API bool rz_analysis_add_function (RzAnalysis *analysis, RzAnalysisFunction *fcn)
 
RZ_API RzAnalysisFunctionrz_analysis_create_function (RzAnalysis *analysis, const char *name, ut64 addr, int type, RzAnalysisDiff *diff)
 
RZ_API bool rz_analysis_function_delete (RzAnalysisFunction *fcn)
 
RZ_API RzAnalysisFunctionrz_analysis_get_function_at (RzAnalysis *analysis, ut64 addr)
 
static bool inst_vars_relocate_cb (void *user, const ut64 k, const void *v)
 
RZ_API bool rz_analysis_function_relocate (RzAnalysisFunction *fcn, ut64 addr)
 
RZ_API bool rz_analysis_function_rename (RzAnalysisFunction *fcn, const char *name)
 
RZ_API void rz_analysis_function_add_block (RzAnalysisFunction *fcn, RzAnalysisBlock *bb)
 
RZ_API void rz_analysis_function_remove_block (RzAnalysisFunction *fcn, RzAnalysisBlock *bb)
 
static void ensure_fcn_range (RzAnalysisFunction *fcn)
 
RZ_API ut64 rz_analysis_function_linear_size (RzAnalysisFunction *fcn)
 
RZ_API ut64 rz_analysis_function_min_addr (RzAnalysisFunction *fcn)
 
RZ_API ut64 rz_analysis_function_max_addr (RzAnalysisFunction *fcn)
 
RZ_API ut64 rz_analysis_function_size_from_entry (RzAnalysisFunction *fcn)
 
RZ_API ut64 rz_analysis_function_realsize (const RzAnalysisFunction *fcn)
 
static bool fcn_in_cb (RzAnalysisBlock *block, void *user)
 
RZ_API bool rz_analysis_function_contains (RzAnalysisFunction *fcn, ut64 addr)
 
RZ_API bool rz_analysis_function_was_modified (RzAnalysisFunction *fcn)
 
RZ_API RZ_BORROW RzListrz_analysis_function_list (RzAnalysis *analysis)
 
static RZ_OWN char * function_name_try_guess (RzTypeDB *typedb, RZ_NONNULL char *name)
 
static bool is_auto_named (char *func_name, size_t slen)
 
static bool has_rz_prefixes (char *func_name, int offset, size_t slen)
 
static char * strip_rz_prefixes (char *func_name, size_t slen)
 
static char * strip_common_prefixes_stdlib (char *func_name)
 
static char * strip_dll_prefix (char *func_name)
 
static void clean_function_name (char *func_name)
 
RZ_API bool rz_analysis_function_is_autonamed (RZ_NONNULL char *name)
 Checks if the function name was generated by Rizin automatically. More...
 
RZ_API RZ_OWN char * rz_analysis_function_name_guess (RzTypeDB *typedb, RZ_NONNULL char *name)
 Checks if varions function name variations present in the database. More...
 

Macro Definition Documentation

◆ MIN_MATCH_LEN

#define MIN_MATCH_LEN   4

Definition at line 383 of file function.c.

Function Documentation

◆ __fcn_exists()

static bool __fcn_exists ( RzAnalysis analysis,
const char *  name,
ut64  addr 
)
static

Definition at line 29 of file function.c.

29  {
30  // check if name is already registered
31  bool found = false;
32  if (addr == UT64_MAX) {
33  RZ_LOG_ERROR("Invalid function address (-1) '%s'\n", name);
34  return true;
35  }
36  if (!name) {
37  RZ_LOG_INFO("Empty function name, we must auto generate one\n");
38  return true;
39  }
40  RzAnalysisFunction *f = ht_pp_find(analysis->ht_name_fun, name, &found);
41  if (f && found) {
42  RZ_LOG_ERROR("Invalid function name '%s' at 0x%08" PFMT64x "\n", name, addr);
43  return true;
44  }
45  // check if there's a function already in the given address
46  found = false;
47  f = ht_up_find(analysis->ht_addr_fun, addr, &found);
48  if (f && found) {
49  RZ_LOG_ERROR("Function already defined in 0x%08" PFMT64x "\n", addr);
50  return true;
51  }
52  return false;
53 }
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define PFMT64x
Definition: rz_types.h:393
#define UT64_MAX
Definition: rz_types_base.h:86
#define f(i)
Definition: sha256.c:46
Definition: z80asm.h:102
HtUP * ht_addr_fun
Definition: rz_analysis.h:566
HtPP * ht_name_fun
Definition: rz_analysis.h:567
static int addr
Definition: z80asm.c:58

References addr, f, found, rz_analysis_t::ht_addr_fun, rz_analysis_t::ht_name_fun, PFMT64x, RZ_LOG_ERROR, RZ_LOG_INFO, and UT64_MAX.

Referenced by rz_analysis_add_function().

◆ clean_function_name()

static void clean_function_name ( char *  func_name)
static

Definition at line 432 of file function.c.

432  {
433  char *last = (char *)rz_str_lchr(func_name, '_');
434  if (!last || !rz_str_isnumber(last + 1)) {
435  return;
436  }
437  *last = '\0';
438 }
RZ_API const char * rz_str_lchr(const char *str, char chr)
Definition: str.c:669
RZ_API bool rz_str_isnumber(const char *str)
Definition: str.c:3550

References rz_str_isnumber(), and rz_str_lchr().

Referenced by rz_analysis_function_name_guess().

◆ ensure_fcn_range()

static void ensure_fcn_range ( RzAnalysisFunction fcn)
static

Definition at line 298 of file function.c.

298  {
299  if (fcn->meta._min != UT64_MAX) { // recalculate only if invalid
300  return;
301  }
302  ut64 minval = UT64_MAX;
303  ut64 maxval = UT64_MIN;
304  RzAnalysisBlock *block;
305  RzListIter *iter;
306  rz_list_foreach (fcn->bbs, iter, block) {
307  if (block->addr < minval) {
308  minval = block->addr;
309  }
310  if (block->addr + block->size > maxval) {
311  maxval = block->addr + block->size;
312  }
313  }
314  fcn->meta._min = minval;
315  fcn->meta._max = minval == UT64_MAX ? UT64_MAX : maxval;
316 }
#define UT64_MIN
Definition: rz_types_base.h:89
RzAnalysisFcnMeta meta
Definition: rz_analysis.h:265
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References rz_analysis_fcn_meta_t::_max, rz_analysis_fcn_meta_t::_min, rz_analysis_bb_t::addr, rz_analysis_function_t::bbs, rz_analysis_function_t::meta, rz_analysis_bb_t::size, ut64(), UT64_MAX, and UT64_MIN.

Referenced by rz_analysis_function_linear_size(), rz_analysis_function_max_addr(), rz_analysis_function_min_addr(), and rz_analysis_function_size_from_entry().

◆ fcn_in_cb()

static bool fcn_in_cb ( RzAnalysisBlock block,
void *  user 
)
static

Definition at line 350 of file function.c.

350  {
351  RzListIter *iter;
352  RzAnalysisFunction *fcn;
353  rz_list_foreach (block->fcns, iter, fcn) {
354  if (fcn == user) {
355  return false;
356  }
357  }
358  return true;
359 }

References rz_analysis_bb_t::fcns.

Referenced by rz_analysis_function_contains().

◆ function_name_try_guess()

static RZ_OWN char* function_name_try_guess ( RzTypeDB typedb,
RZ_NONNULL char *  name 
)
static

Definition at line 385 of file function.c.

385  {
386  if (strlen(name) < MIN_MATCH_LEN) {
387  return NULL;
388  }
389  if (rz_type_func_exist(typedb, name)) {
390  return strdup(name);
391  }
392  return NULL;
393 }
#define MIN_MATCH_LEN
Definition: function.c:383
#define NULL
Definition: cris-opc.c:27
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")
RZ_API bool rz_type_func_exist(RzTypeDB *typedb, RZ_NONNULL const char *name)
Checks if the RzCallable type exists in the database given the name.
Definition: function.c:203

References MIN_MATCH_LEN, NULL, rz_type_func_exist(), and strdup().

Referenced by rz_analysis_function_name_guess().

◆ get_functions_block_cb()

static bool get_functions_block_cb ( RzAnalysisBlock block,
void *  user 
)
static

Definition at line 7 of file function.c.

7  {
8  RzList *list = user;
10  RzAnalysisFunction *fcn;
11  rz_list_foreach (block->fcns, iter, fcn) {
12  if (rz_list_contains(list, fcn)) {
13  continue;
14  }
15  rz_list_push(list, fcn);
16  }
17  return true;
18 }
static void list(RzEgg *egg)
Definition: rz-gg.c:52
RZ_API RZ_BORROW RzListIter * rz_list_contains(RZ_NONNULL const RzList *list, RZ_NONNULL const void *ptr)
Returns the RzListIter of the given pointer, if found.
Definition: list.c:592
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60

References rz_analysis_bb_t::fcns, list(), rz_list_contains(), and rz_list_push().

Referenced by rz_analysis_get_functions_in().

◆ has_rz_prefixes()

static bool has_rz_prefixes ( char *  func_name,
int  offset,
size_t  slen 
)
inlinestatic

Definition at line 399 of file function.c.

399  {
400  return slen > 4 && (offset + 3 < slen) && func_name[offset + 3] == '.';
401 }
voidpf uLong offset
Definition: ioapi.h:144

Referenced by rz_analysis_function_is_autonamed(), and strip_rz_prefixes().

◆ inst_vars_kv_free()

static void inst_vars_kv_free ( HtUPKv *  kv)
static

Definition at line 57 of file function.c.

57  {
58  rz_pvector_free(kv->value);
59 }
RZ_API void rz_pvector_free(RzPVector *vec)
Definition: vector.c:336

References rz_pvector_free().

Referenced by rz_analysis_function_new(), and rz_analysis_function_relocate().

◆ inst_vars_relocate_cb()

static bool inst_vars_relocate_cb ( void *  user,
const ut64  k,
const void *  v 
)
static

Definition at line 198 of file function.c.

198  {
199  InstVarsRelocateCtx *ctx = user;
200  ht_up_insert(ctx->inst_vars_new, k - ctx->delta, (void *)v);
201  return true;
202 }
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12

References k, and v.

Referenced by rz_analysis_function_relocate().

◆ is_auto_named()

static bool is_auto_named ( char *  func_name,
size_t  slen 
)
inlinestatic

Definition at line 395 of file function.c.

395  {
396  return slen > 4 && (rz_str_startswith(func_name, "fcn.") || rz_str_startswith(func_name, "loc."));
397 }
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
Definition: str.c:3286

References rz_str_startswith().

Referenced by rz_analysis_function_is_autonamed(), and rz_analysis_function_name_guess().

◆ label_addrs_kv_free()

static void label_addrs_kv_free ( HtPPKv *  kv)
static

Definition at line 65 of file function.c.

65  {
66  free(kv->key);
67  free(kv->value);
68 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130

References free().

Referenced by rz_analysis_function_new().

◆ labels_kv_free()

static void labels_kv_free ( HtUPKv *  kv)
static

Definition at line 61 of file function.c.

61  {
62  free(kv->value);
63 }

References free().

Referenced by rz_analysis_function_new().

◆ rz_analysis_add_function()

RZ_API bool rz_analysis_add_function ( RzAnalysis analysis,
RzAnalysisFunction fcn 
)

Definition at line 129 of file function.c.

129  {
130  if (__fcn_exists(analysis, fcn->name, fcn->addr)) {
131  return false;
132  }
133  if (analysis->cb.on_fcn_new) {
134  analysis->cb.on_fcn_new(analysis, analysis->core, fcn);
135  }
136  if (analysis->flg_fcn_set) {
137  analysis->flg_fcn_set(analysis->flb.f, fcn->name, fcn->addr, rz_analysis_function_size_from_entry(fcn));
138  }
139  fcn->is_noreturn = rz_analysis_noreturn_at_addr(analysis, fcn->addr);
140  rz_list_append(analysis->fcns, fcn);
141  ht_pp_insert(analysis->ht_name_fun, fcn->name, fcn);
142  ht_up_insert(analysis->ht_addr_fun, fcn->addr, fcn);
143  return true;
144 }
RZ_API ut64 rz_analysis_function_size_from_entry(RzAnalysisFunction *fcn)
Definition: function.c:333
static bool __fcn_exists(RzAnalysis *analysis, const char *name, ut64 addr)
Definition: function.c:29
RZ_API bool rz_analysis_noreturn_at_addr(RzAnalysis *analysis, ut64 addr)
Definition: analysis.c:557
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
int(* on_fcn_new)(struct rz_analysis_t *, void *user, RzAnalysisFunction *fcn)
Definition: rz_analysis.h:498
RzAnalysisCallbacks cb
Definition: rz_analysis.h:607
RzList * fcns
Definition: rz_analysis.h:565
RzFlagBind flb
Definition: rz_analysis.h:575
RzFlagSet flg_fcn_set
Definition: rz_analysis.h:578
RzFlag * f
Definition: rz_flag.h:78

References __fcn_exists(), rz_analysis_function_t::addr, rz_analysis_t::cb, rz_analysis_t::core, rz_flag_bind_t::f, rz_analysis_t::fcns, rz_analysis_t::flb, rz_analysis_t::flg_fcn_set, rz_analysis_t::ht_addr_fun, rz_analysis_t::ht_name_fun, rz_analysis_function_t::is_noreturn, rz_analysis_function_t::name, rz_analysis_callbacks_t::on_fcn_new, rz_analysis_function_size_from_entry(), rz_analysis_noreturn_at_addr(), and rz_list_append().

Referenced by __core_analysis_fcn(), and rz_analysis_create_function().

◆ rz_analysis_create_function()

RZ_API RzAnalysisFunction* rz_analysis_create_function ( RzAnalysis analysis,
const char *  name,
ut64  addr,
int  type,
RzAnalysisDiff diff 
)

Definition at line 146 of file function.c.

146  {
148  if (!fcn) {
149  return NULL;
150  }
151  fcn->addr = addr;
152  fcn->type = type;
153  fcn->cc = rz_str_constpool_get(&analysis->constpool, rz_analysis_cc_default(analysis));
154  fcn->bits = analysis->bits;
155  if (name) {
156  free(fcn->name);
157  fcn->name = strdup(name);
158  } else {
159  const char *fcnprefix = analysis->coreb.cfgGet ? analysis->coreb.cfgGet(analysis->coreb.core, "analysis.fcnprefix") : NULL;
160  if (!fcnprefix) {
161  fcnprefix = "fcn";
162  }
163  fcn->name = rz_str_newf("%s.%08" PFMT64x, fcnprefix, fcn->addr);
164  }
165  if (diff) {
166  fcn->diff->type = diff->type;
167  fcn->diff->addr = diff->addr;
168  RZ_FREE(fcn->diff->name);
169  if (diff->name) {
170  fcn->diff->name = strdup(diff->name);
171  }
172  }
173  if (!rz_analysis_add_function(analysis, fcn)) {
175  return NULL;
176  }
177  return fcn;
178 }
RZ_API bool rz_analysis_add_function(RzAnalysis *analysis, RzAnalysisFunction *fcn)
Definition: function.c:129
RZ_API RzAnalysisFunction * rz_analysis_function_new(RzAnalysis *analysis)
Definition: function.c:70
RZ_API void rz_analysis_function_free(void *_fcn)
Definition: function.c:92
RZ_API const char * rz_analysis_cc_default(RzAnalysis *analysis)
Definition: cc.c:200
int type
Definition: mipsasm.c:17
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API const char * rz_str_constpool_get(RzStrConstPool *pool, const char *str)
Definition: str_constpool.c:19
#define RZ_FREE(x)
Definition: rz_types.h:369
RzAnalysisDiff * diff
Definition: rz_analysis.h:263
RzStrConstPool constpool
Definition: rz_analysis.h:620
RzCoreBind coreb
Definition: rz_analysis.h:580
RzCoreConfigGet cfgGet
Definition: rz_bind.h:44
void * core
Definition: rz_bind.h:31

References addr, rz_analysis_diff_t::addr, rz_analysis_function_t::addr, rz_analysis_function_t::bits, rz_analysis_t::bits, rz_analysis_function_t::cc, rz_core_bind_t::cfgGet, rz_analysis_t::constpool, rz_core_bind_t::core, rz_analysis_t::coreb, rz_analysis_function_t::diff, free(), rz_analysis_diff_t::name, rz_analysis_function_t::name, NULL, PFMT64x, rz_analysis_add_function(), rz_analysis_cc_default(), rz_analysis_function_free(), rz_analysis_function_new(), RZ_FREE, rz_str_constpool_get(), rz_str_newf(), strdup(), type, rz_analysis_diff_t::type, and rz_analysis_function_t::type.

Referenced by rz_analysis_function_create_handler().

◆ rz_analysis_function_add_block()

RZ_API void rz_analysis_function_add_block ( RzAnalysisFunction fcn,
RzAnalysisBlock bb 
)

Definition at line 264 of file function.c.

264  {
265  if (rz_list_contains(bb->fcns, fcn)) {
266  return;
267  }
268  rz_list_append(bb->fcns, fcn); // associate the given fcn with this bb
270  rz_list_append(fcn->bbs, bb);
271 
272  if (fcn->meta._min != UT64_MAX) {
273  if (bb->addr + bb->size > fcn->meta._max) {
274  fcn->meta._max = bb->addr + bb->size;
275  }
276  if (bb->addr < fcn->meta._min) {
277  fcn->meta._min = bb->addr;
278  }
279  }
280 
281  if (fcn->analysis->cb.on_fcn_bb_new) {
282  fcn->analysis->cb.on_fcn_bb_new(fcn->analysis, fcn->analysis->core, fcn, bb);
283  }
284 }
RZ_API void rz_analysis_block_ref(RzAnalysisBlock *bb)
Definition: block.c:40
int(* on_fcn_bb_new)(struct rz_analysis_t *, void *user, RzAnalysisFunction *fcn, struct rz_analysis_bb_t *bb)
Definition: rz_analysis.h:501
struct rz_analysis_t * analysis
Definition: rz_analysis.h:267

References rz_analysis_fcn_meta_t::_max, rz_analysis_fcn_meta_t::_min, rz_analysis_bb_t::addr, rz_analysis_function_t::analysis, rz_analysis_function_t::bbs, rz_analysis_t::cb, rz_analysis_t::core, rz_analysis_bb_t::fcns, rz_analysis_function_t::meta, rz_analysis_callbacks_t::on_fcn_bb_new, rz_analysis_block_ref(), rz_list_append(), rz_list_contains(), rz_analysis_bb_t::size, and UT64_MAX.

Referenced by fcn_append_basic_block(), fcn_takeover_block_recursive_followthrough_cb(), function_load_cb(), module_match_buffer(), rz_analysis_block_split(), rz_analysis_fcn_add_bb(), and rz_core_analysis_fcn_merge().

◆ rz_analysis_function_contains()

RZ_API bool rz_analysis_function_contains ( RzAnalysisFunction fcn,
ut64  addr 
)

Definition at line 361 of file function.c.

361  {
362  // fcn_in_cb breaks with false if it finds the fcn
364 }
static bool fcn_in_cb(RzAnalysisBlock *block, void *user)
Definition: function.c:350
RZ_API bool rz_analysis_blocks_foreach_in(RzAnalysis *analysis, ut64 addr, RzAnalysisBlockCb cb, void *user)
Definition: block.c:122

References addr, rz_analysis_function_t::analysis, fcn_in_cb(), and rz_analysis_blocks_foreach_in().

Referenced by analyze_noreturn_function(), ds_setup_pre(), fcn_print_trace_info(), fcnIn(), print_meta_list(), rz_analysis_fcn_del_locs(), rz_analysis_get_fcn_in_bounds(), rz_analysis_trim_jmprefs(), rz_core_analysis_fcn(), and rz_core_analysis_fcn_clean().

◆ rz_analysis_function_delete()

RZ_API bool rz_analysis_function_delete ( RzAnalysisFunction fcn)

Definition at line 180 of file function.c.

180  {
181  return rz_list_delete_data(fcn->analysis->fcns, fcn);
182 }
RZ_API bool rz_list_delete_data(RZ_NONNULL RzList *list, void *ptr)
Deletes an entry in the list by searching for a pointer.
Definition: list.c:148

References rz_analysis_function_t::analysis, rz_analysis_t::fcns, and rz_list_delete_data().

Referenced by module_match_buffer(), rz_analysis_fcn_del(), rz_analysis_fcn_del_locs(), rz_core_analysis_fcn_clean(), rz_core_analysis_fcn_merge(), and rz_core_gdiff_2_files().

◆ rz_analysis_function_free()

RZ_API void rz_analysis_function_free ( void *  _fcn)

Definition at line 92 of file function.c.

92  {
93  RzAnalysisFunction *fcn = _fcn;
94  if (!_fcn) {
95  return;
96  }
97 
98  RzAnalysisBlock *block;
100  rz_list_foreach (fcn->bbs, iter, block) {
101  rz_list_delete_data(block->fcns, fcn);
103  }
104  rz_list_free(fcn->bbs);
105 
106  RzAnalysis *analysis = fcn->analysis;
107  if (ht_up_find(analysis->ht_addr_fun, fcn->addr, NULL) == _fcn) {
108  ht_up_delete(analysis->ht_addr_fun, fcn->addr);
109  }
110  if (ht_pp_find(analysis->ht_name_fun, fcn->name, NULL) == _fcn) {
111  ht_pp_delete(analysis->ht_name_fun, fcn->name);
112  }
113 
114  ht_up_free(fcn->inst_vars);
115  fcn->inst_vars = NULL;
117 
118  ht_up_free(fcn->labels);
119  ht_pp_free(fcn->label_addrs);
120 
121  free(fcn->name);
122  fcn->bbs = NULL;
123  free(fcn->fingerprint);
125  rz_list_free(fcn->imports);
126  free(fcn);
127 }
RZ_API void rz_analysis_diff_free(RzAnalysisDiff *diff)
Definition: diff.c:22
RZ_API void rz_analysis_block_unref(RzAnalysisBlock *bb)
Definition: block.c:370
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_function_delete_all_vars(RzAnalysisFunction *fcn)
Definition: var.c:220

References rz_analysis_function_t::addr, rz_analysis_function_t::analysis, rz_analysis_function_t::bbs, rz_analysis_function_t::diff, rz_analysis_bb_t::fcns, rz_analysis_function_t::fingerprint, free(), rz_analysis_t::ht_addr_fun, rz_analysis_t::ht_name_fun, rz_analysis_function_t::imports, rz_analysis_function_t::inst_vars, rz_analysis_function_t::label_addrs, rz_analysis_function_t::labels, rz_analysis_function_t::name, NULL, rz_analysis_block_unref(), rz_analysis_diff_free(), rz_analysis_function_delete_all_vars(), rz_list_delete_data(), and rz_list_free().

Referenced by __core_analysis_fcn(), rz_analysis_create_function(), rz_analysis_new(), and rz_analysis_purge().

◆ rz_analysis_function_is_autonamed()

RZ_API bool rz_analysis_function_is_autonamed ( RZ_NONNULL char *  name)

Checks if the function name was generated by Rizin automatically.

Definition at line 443 of file function.c.

443  {
444  size_t len = strlen(name);
445  return (len >= MIN_MATCH_LEN) && (is_auto_named(name, len) || has_rz_prefixes(name, 0, len));
446 }
size_t len
Definition: 6502dis.c:15
static bool is_auto_named(char *func_name, size_t slen)
Definition: function.c:395
static bool has_rz_prefixes(char *func_name, int offset, size_t slen)
Definition: function.c:399

References has_rz_prefixes(), is_auto_named(), len, and MIN_MATCH_LEN.

Referenced by rz_analysis_fcn_vars_add_types().

◆ rz_analysis_function_linear_size()

◆ rz_analysis_function_list()

RZ_API RZ_BORROW RzList* rz_analysis_function_list ( RzAnalysis analysis)

Definition at line 378 of file function.c.

378  {
379  rz_return_val_if_fail(analysis, NULL);
380  return analysis->fcns;
381 }
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108

References rz_analysis_t::fcns, NULL, and rz_return_val_if_fail.

Referenced by rz_analysis_function_list_ascii_handler(), rz_analysis_function_list_calls_handler(), and rz_analysis_function_list_handler().

◆ rz_analysis_function_max_addr()

◆ rz_analysis_function_min_addr()

◆ rz_analysis_function_name_guess()

RZ_API RZ_OWN char* rz_analysis_function_name_guess ( RzTypeDB typedb,
RZ_NONNULL char *  name 
)

Checks if varions function name variations present in the database.

Tries to remove different prefixes from the Rizin autonames, standard libraries prefixes, various Windows-specific prefixes and checks every attempt in the function database. If there is a match - returns it.

Parameters
typedbRzTypeDB instance
nameFunction name to check

Definition at line 458 of file function.c.

458  {
459  rz_return_val_if_fail(typedb && name, NULL);
460  char *str = name;
461  char *result = NULL;
462 
463  size_t slen = strlen(str);
464  if (slen < MIN_MATCH_LEN || is_auto_named(str, slen)) {
465  return NULL;
466  }
467 
468  str = strip_rz_prefixes(str, slen);
471 
472  if ((result = function_name_try_guess(typedb, str))) {
473  return result;
474  }
475 
476  str = strdup(str);
478 
479  if (*str == '_' && (result = function_name_try_guess(typedb, str + 1))) {
480  free(str);
481  return result;
482  }
483 
484  free(str);
485  return result;
486 }
static char * strip_common_prefixes_stdlib(char *func_name)
Definition: function.c:412
static RZ_OWN char * function_name_try_guess(RzTypeDB *typedb, RZ_NONNULL char *name)
Definition: function.c:385
static char * strip_rz_prefixes(char *func_name, size_t slen)
Definition: function.c:403
static char * strip_dll_prefix(char *func_name)
Definition: function.c:424
static void clean_function_name(char *func_name)
Definition: function.c:432
const char * name
Definition: op.c:541

References clean_function_name(), free(), function_name_try_guess(), is_auto_named(), MIN_MATCH_LEN, name, NULL, rz_return_val_if_fail, cmd_descs_generate::str, strdup(), strip_common_prefixes_stdlib(), strip_dll_prefix(), and strip_rz_prefixes().

Referenced by ds_print_calls_hints(), extract_arg(), propagate_types_among_used_variables(), resolve_fcn_name(), rz_analysis_extract_rarg(), rz_analysis_fcn_format_sig(), rz_analysis_function_clone_type(), rz_analysis_noreturn_add(), and rz_analysis_noreturn_at_name().

◆ rz_analysis_function_new()

RZ_API RzAnalysisFunction* rz_analysis_function_new ( RzAnalysis analysis)

Definition at line 70 of file function.c.

70  {
72  if (!fcn) {
73  return NULL;
74  }
75  fcn->analysis = analysis;
76  fcn->addr = UT64_MAX;
77  fcn->cc = rz_str_constpool_get(&analysis->constpool, rz_analysis_cc_default(analysis));
78  fcn->bits = analysis->bits;
79  fcn->bbs = rz_list_new();
80  fcn->diff = rz_analysis_diff_new();
81  fcn->has_changed = true;
82  fcn->bp_frame = true;
83  fcn->is_noreturn = false;
84  fcn->meta._min = UT64_MAX;
85  rz_pvector_init(&fcn->vars, NULL);
86  fcn->inst_vars = ht_up_new(NULL, inst_vars_kv_free, NULL);
87  fcn->labels = ht_up_new(NULL, labels_kv_free, NULL);
88  fcn->label_addrs = ht_pp_new(NULL, label_addrs_kv_free, NULL);
89  return fcn;
90 }
RZ_API RZ_OWN RzAnalysisDiff * rz_analysis_diff_new(void)
Definition: diff.c:9
static void inst_vars_kv_free(HtUPKv *kv)
Definition: function.c:57
static void label_addrs_kv_free(HtPPKv *kv)
Definition: function.c:65
static void labels_kv_free(HtUPKv *kv)
Definition: function.c:61
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
#define RZ_NEW0(x)
Definition: rz_types.h:284
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
Definition: vector.c:298

References rz_analysis_fcn_meta_t::_min, rz_analysis_function_t::addr, rz_analysis_function_t::analysis, rz_analysis_function_t::bbs, rz_analysis_function_t::bits, rz_analysis_t::bits, rz_analysis_function_t::bp_frame, rz_analysis_function_t::cc, rz_analysis_t::constpool, rz_analysis_function_t::diff, rz_analysis_function_t::has_changed, rz_analysis_function_t::inst_vars, inst_vars_kv_free(), rz_analysis_function_t::is_noreturn, rz_analysis_function_t::label_addrs, label_addrs_kv_free(), rz_analysis_function_t::labels, labels_kv_free(), rz_analysis_function_t::meta, NULL, rz_analysis_cc_default(), rz_analysis_diff_new(), rz_list_new(), RZ_NEW0, rz_pvector_init(), rz_str_constpool_get(), UT64_MAX, and rz_analysis_function_t::vars.

Referenced by __core_analysis_fcn(), function_load_cb(), and rz_analysis_create_function().

◆ rz_analysis_function_realsize()

◆ rz_analysis_function_relocate()

RZ_API bool rz_analysis_function_relocate ( RzAnalysisFunction fcn,
ut64  addr 
)

Definition at line 204 of file function.c.

204  {
205  if (fcn->addr == addr) {
206  return true;
207  }
209  return false;
210  }
211  ht_up_delete(fcn->analysis->ht_addr_fun, fcn->addr);
212 
213  // relocate the var accesses (their addrs are relative to the function addr)
214  st64 delta = (st64)addr - (st64)fcn->addr;
215  void **it;
216  rz_pvector_foreach (&fcn->vars, it) {
217  RzAnalysisVar *var = *it;
218  RzAnalysisVarAccess *acc;
219  rz_vector_foreach(&var->accesses, acc) {
220  acc->offset -= delta;
221  }
222  }
224  .inst_vars_new = ht_up_new(NULL, inst_vars_kv_free, NULL),
225  .delta = delta
226  };
227  if (ctx.inst_vars_new) {
228  ht_up_foreach(fcn->inst_vars, inst_vars_relocate_cb, &ctx);
229  // Do not free the elements of the Ht, because they were moved to ctx.inst_vars_new
230  fcn->inst_vars->opt.freefn = NULL;
231  ht_up_free(fcn->inst_vars);
232  fcn->inst_vars = ctx.inst_vars_new;
233  }
234 
235  fcn->addr = addr;
236  ht_up_insert(fcn->analysis->ht_addr_fun, addr, fcn);
237  return true;
238 }
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
Definition: function.c:184
static bool inst_vars_relocate_cb(void *user, const ut64 k, const void *v)
Definition: function.c:198
#define st64
Definition: rz_types_base.h:10
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
static st64 delta
Definition: vmenus.c:2425

References rz_analysis_var_t::accesses, addr, rz_analysis_function_t::addr, rz_analysis_function_t::analysis, delta, rz_analysis_t::ht_addr_fun, rz_analysis_function_t::inst_vars, inst_vars_kv_free(), inst_vars_relocate_cb(), NULL, rz_analysis_var_access_t::offset, rz_analysis_get_function_at(), rz_pvector_foreach, rz_vector_foreach, st64, and rz_analysis_function_t::vars.

Referenced by __rebase_everything(), and rz_core_analysis_fcn_merge().

◆ rz_analysis_function_remove_block()

◆ rz_analysis_function_rename()

RZ_API bool rz_analysis_function_rename ( RzAnalysisFunction fcn,
const char *  name 
)

Definition at line 240 of file function.c.

240  {
241  RzAnalysis *analysis = fcn->analysis;
242  RzAnalysisFunction *existing = ht_pp_find(analysis->ht_name_fun, name, NULL);
243  if (existing) {
244  if (existing == fcn) {
245  // fcn->name == name, nothing to do
246  return true;
247  }
248  return false;
249  }
250  char *newname = strdup(name);
251  if (!newname) {
252  return false;
253  }
254  bool in_tree = ht_pp_delete(analysis->ht_name_fun, fcn->name);
255  free(fcn->name);
256  fcn->name = newname;
257  if (in_tree) {
258  // only re-insert if it really was in the tree before
259  ht_pp_insert(analysis->ht_name_fun, fcn->name, fcn);
260  }
261  return true;
262 }

References rz_analysis_function_t::analysis, free(), rz_analysis_t::ht_name_fun, rz_analysis_function_t::name, NULL, and strdup().

Referenced by module_match_buffer(), rz_analysis_dwarf_integrate_functions(), rz_core_analysis_function_rename(), and set_fcn_name_from_flag().

◆ rz_analysis_function_size_from_entry()

◆ rz_analysis_function_was_modified()

RZ_API bool rz_analysis_function_was_modified ( RzAnalysisFunction fcn)

Definition at line 366 of file function.c.

366  {
367  rz_return_val_if_fail(fcn, false);
368  RzListIter *it;
369  RzAnalysisBlock *bb;
370  rz_list_foreach (fcn->bbs, it, bb) {
372  return true;
373  }
374  }
375  return false;
376 }
RZ_API bool rz_analysis_block_was_modified(RzAnalysisBlock *block)
Definition: block.c:680

References rz_analysis_function_t::bbs, rz_analysis_block_was_modified(), and rz_return_val_if_fail.

Referenced by check_function_modified().

◆ rz_analysis_get_function_at()

RZ_API RzAnalysisFunction* rz_analysis_get_function_at ( RzAnalysis analysis,
ut64  addr 
)

◆ rz_analysis_get_functions_in()

RZ_API RzList* rz_analysis_get_functions_in ( RzAnalysis analysis,
ut64  addr 
)

◆ rz_analysis_var_free()

RZ_IPI void rz_analysis_var_free ( RzAnalysisVar av)

◆ strip_common_prefixes_stdlib()

static char* strip_common_prefixes_stdlib ( char *  func_name)
static

Definition at line 412 of file function.c.

412  {
413  // strip common prefixes from standard lib functions
414  if (rz_str_startswith(func_name, "__isoc99_")) {
415  func_name += 9;
416  } else if (rz_str_startswith(func_name, "__libc_") && !strstr(func_name, "_main")) {
417  func_name += 7;
418  } else if (rz_str_startswith(func_name, "__GI_")) {
419  func_name += 5;
420  }
421  return func_name;
422 }

References rz_str_startswith().

Referenced by rz_analysis_function_name_guess().

◆ strip_dll_prefix()

static char* strip_dll_prefix ( char *  func_name)
static

Definition at line 424 of file function.c.

424  {
425  char *tmp = strstr(func_name, "dll_");
426  if (tmp) {
427  return tmp + 3;
428  }
429  return func_name;
430 }

References autogen_x86imm::tmp.

Referenced by rz_analysis_function_name_guess().

◆ strip_rz_prefixes()

static char* strip_rz_prefixes ( char *  func_name,
size_t  slen 
)
static

Definition at line 403 of file function.c.

403  {
404  // strip rizin prefixes (sym, sym.imp, etc')
405  int offset = 0;
406  while (has_rz_prefixes(func_name, offset, slen)) {
407  offset += 4;
408  }
409  return func_name + offset;
410 }

References has_rz_prefixes().

Referenced by rz_analysis_function_name_guess().