Rizin
unix-like reverse engineering framework and cli tools
var_global.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2021 Basstorm <basstorm@nyist.edu.cn>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_analysis.h>
5 #include <rz_list.h>
6 
18  if (!glob) {
19  return NULL;
20  }
21  glob->name = strdup(name);
22  glob->addr = addr;
23  glob->analysis = NULL;
24 
25  return glob;
26 }
27 
28 int global_var_node_cmp(const void *incoming, const RBNode *in_tree, void *user) {
29  ut64 ia = *(ut64 *)incoming;
30  ut64 ta = container_of(in_tree, const RzAnalysisVarGlobal, rb)->addr;
31  if (ia < ta) {
32  return -1;
33  } else if (ia > ta) {
34  return 1;
35  }
36  return 0;
37 }
38 
47  rz_return_val_if_fail(analysis && global_var, false);
48 
49  RzAnalysisVarGlobal *existing_glob = NULL;
50  if ((existing_glob = rz_analysis_var_global_get_byaddr_in(analysis, global_var->addr))) {
51  RZ_LOG_ERROR("Global variable %s at 0x%" PFMT64x " already exists!\n", existing_glob->name, existing_glob->addr);
52  return false;
53  }
54  if ((existing_glob = rz_analysis_var_global_get_byname(analysis, global_var->name))) {
55  RZ_LOG_ERROR("Global variable %s at 0x%" PFMT64x " already exists!\n", existing_glob->name, existing_glob->addr);
56  return false;
57  }
58  if (!ht_pp_insert(analysis->ht_global_var, global_var->name, global_var)) {
59  return false;
60  }
61  if (!rz_rbtree_aug_insert(&analysis->global_var_tree, &global_var->addr, &global_var->rb, global_var_node_cmp, NULL, NULL)) {
62  return false;
63  }
64 
65  global_var->analysis = analysis;
66  rz_flag_space_push(global_var->analysis->flb.f, "globals");
67  rz_flag_set(global_var->analysis->flb.f, global_var->name, global_var->addr, rz_type_db_get_bitsize(global_var->analysis->typedb, global_var->type) / 8);
68  rz_flag_space_pop(global_var->analysis->flb.f);
69 
70  return true;
71 }
72 
80  if (!glob) {
81  return;
82  }
84  if (flag) {
85  rz_flag_unset(glob->analysis->flb.f, flag);
86  }
87  RZ_FREE(glob->name);
88  rz_type_free(glob->type);
90  RZ_FREE(glob);
91 }
92 
103  RzAnalysis *a = glob->analysis;
104  if (!a) {
105  return NULL;
106  }
107  RzFlagItem *r = rz_flag_get(a->flb.f, glob->name);
108  if (r && r->offset != glob->addr) {
109  return NULL;
110  }
111  return r;
112 }
113 
122  rz_return_val_if_fail(analysis && glob, false);
123 
124  // We need to delete RBTree first because ht_pp_delete will free its member
125  bool deleted = rz_rbtree_delete(&analysis->global_var_tree, &glob->addr, global_var_node_cmp, NULL, NULL, NULL);
126  return deleted ? ht_pp_delete(analysis->ht_global_var, glob->name) : deleted;
127 }
128 
137  rz_return_val_if_fail(analysis && name, false);
139  if (!glob) {
140  RZ_LOG_ERROR("No global variable found having name %s\n", name);
141  return false;
142  }
143 
144  return rz_analysis_var_global_delete(analysis, glob);
145 }
146 
155  rz_return_val_if_fail(analysis, false);
157  if (!glob) {
158  RZ_LOG_ERROR("No global variable found at 0x%" PFMT64x "\n", addr);
159  return false;
160  }
161 
162  return rz_analysis_var_global_delete(analysis, glob);
163 }
164 
173  rz_return_val_if_fail(analysis, false);
175  if (!glob) {
176  RZ_LOG_ERROR("No global variable found in 0x%" PFMT64x "\n", addr);
177  return false;
178  }
179 
180  return rz_analysis_var_global_delete(analysis, glob);
181 }
182 
191  rz_return_val_if_fail(analysis && name, NULL);
192  return (RzAnalysisVarGlobal *)ht_pp_find(analysis->ht_global_var, name, NULL);
193 }
194 
195 struct list_addr {
196  RzList /* <RzAnalysisVarGlobal> */ *list;
198 };
199 
208  rz_return_val_if_fail(analysis, NULL);
209 
211  if (!node) {
212  return NULL;
213  }
215  if (!var) {
216  return NULL;
217  }
218  return var;
219 }
220 
229  rz_return_val_if_fail(analysis, NULL);
230 
232  if (!node) {
233  return NULL;
234  }
236  if (!var) {
237  return NULL;
238  }
239  ut64 size = rz_type_db_get_bitsize(analysis->typedb, var->type) / 8;
240  if (addr >= var->addr + size) {
241  return NULL;
242  }
243  return var;
244 }
245 
246 static bool global_var_collect_cb(void *user, const void *k, const void *v) {
247  RzList *l = user;
249  rz_list_append(l, glob);
250  return true;
251 }
252 
259 RZ_API RZ_OWN RzList /*<RzAnalysisVarGlobal *>*/ *rz_analysis_var_global_get_all(RzAnalysis *analysis) {
260  rz_return_val_if_fail(analysis, NULL);
261  RzList *globals = rz_list_new();
262  if (!globals) {
263  return NULL;
264  }
265  ht_pp_foreach(analysis->ht_global_var, global_var_collect_cb, globals);
266  return globals;
267 }
268 
277 RZ_API bool rz_analysis_var_global_rename(RzAnalysis *analysis, RZ_NONNULL const char *old_name, RZ_NONNULL const char *newname) {
278  rz_return_val_if_fail(analysis && old_name && newname, false);
279  RzAnalysisVarGlobal *glob = rz_analysis_var_global_get_byname(analysis, old_name);
280  if (!glob) {
281  RZ_LOG_ERROR("Global variable '%s' does not exist!\n", old_name);
282  return false;
283  }
284 
286  if (flag) {
287  rz_flag_rename(analysis->flb.f, flag, newname);
288  }
289 
290  RZ_FREE(glob->name);
291  glob->name = strdup(newname);
292  return ht_pp_update_key(analysis->ht_global_var, old_name, newname);
293 }
294 
303  rz_return_if_fail(glob && type);
304  rz_type_free(glob->type);
305  glob->type = type;
306 
308  if (flag) {
309  flag->size = rz_type_db_get_bitsize(glob->analysis->typedb, glob->type) / 8;
310  }
311 }
312 
321  rz_return_if_fail(glob && constraint);
322  rz_vector_push(&glob->constraints, constraint);
323 }
324 
332  size_t n = glob->constraints.len;
333  if (!n) {
334  return NULL;
335  }
336  bool low = false, high = false;
337  RzStrBuf sb;
338  rz_strbuf_init(&sb);
339  size_t i;
340  for (i = 0; i < n; i += 1) {
342  switch (constr->cond) {
343  case RZ_TYPE_COND_LE:
344  if (high) {
345  rz_strbuf_append(&sb, " && ");
346  }
347  rz_strbuf_appendf(&sb, "<= 0x%" PFMT64x "", constr->val);
348  low = true;
349  break;
350  case RZ_TYPE_COND_LT:
351  if (high) {
352  rz_strbuf_append(&sb, " && ");
353  }
354  rz_strbuf_appendf(&sb, "< 0x%" PFMT64x "", constr->val);
355  low = true;
356  break;
357  case RZ_TYPE_COND_GE:
358  rz_strbuf_appendf(&sb, ">= 0x%" PFMT64x "", constr->val);
359  high = true;
360  break;
361  case RZ_TYPE_COND_GT:
362  rz_strbuf_appendf(&sb, "> 0x%" PFMT64x "", constr->val);
363  high = true;
364  break;
365  default:
366  break;
367  }
368  if (low && high && i != n - 1) {
369  rz_strbuf_append(&sb, " || ");
370  low = false;
371  high = false;
372  }
373  }
374  return rz_strbuf_drain_nofree(&sb);
375 }
lzma_index ** i
Definition: index.h:629
static SblHeader sb
Definition: bin_mbn.c:26
#define RZ_API
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
const char * k
Definition: dsignal.c:11
const char * v
Definition: dsignal.c:12
RZ_API int rz_flag_rename(RzFlag *f, RzFlagItem *item, const char *name)
Definition: flag.c:587
RZ_API RzFlagItem * rz_flag_get(RzFlag *f, const char *name)
Definition: flag.c:310
RZ_API RzFlagItem * rz_flag_set(RzFlag *f, const char *name, ut64 off, ut32 size)
Definition: flag.c:521
RZ_API bool rz_flag_unset(RzFlag *f, RzFlagItem *item)
Definition: flag.c:597
voidpf void uLong size
Definition: ioapi.h:138
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int n
Definition: mipsasm.c:19
int type
Definition: mipsasm.c:17
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API RBNode * rz_rbtree_find(RBNode *root, void *data, RBComparator cmp, void *user)
Definition: rbtree.c:267
RZ_API bool rz_rbtree_delete(RBNode **root, void *data, RBComparator cmp, void *cmp_user, RBNodeFree freefn, void *free_user)
Returns true if a node with an equal key is deleted.
Definition: rbtree.c:263
RZ_API bool rz_rbtree_aug_insert(RBNode **root, void *data, RBNode *node, RBComparator cmp, void *cmp_user, RBNodeSum sum)
Returns true if the node was inserted successfully.
Definition: rbtree.c:163
RZ_API RBNode * rz_rbtree_upper_bound(RBNode *root, void *data, RBComparator cmp, void *user)
Definition: rbtree.c:313
RZ_API RZ_OWN char * rz_strbuf_drain_nofree(RzStrBuf *sb)
Definition: strbuf.c:349
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
@ RZ_TYPE_COND_LE
Less or equal.
Definition: rz_type.h:188
@ RZ_TYPE_COND_GE
Greater or equal.
Definition: rz_type.h:186
@ RZ_TYPE_COND_GT
Greater than.
Definition: rz_type.h:187
@ RZ_TYPE_COND_LT
Less than.
Definition: rz_type.h:189
#define RZ_NULLABLE
Definition: rz_types.h:65
#define RZ_OWN
Definition: rz_types.h:62
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_NONNULL
Definition: rz_types.h:64
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define container_of(ptr, type, member)
Definition: rz_types.h:650
#define RZ_BORROW
Definition: rz_types.h:63
static void * rz_vector_index_ptr(RzVector *vec, size_t index)
Definition: rz_vector.h:88
RZ_API void * rz_vector_push(RzVector *vec, void *x)
Definition: vector.c:197
RZ_API void rz_vector_fini(RzVector *vec)
Definition: vector.c:61
#define a(i)
Definition: sha256.c:41
ut64 addr
Definition: var_global.c:197
RzList * list
Definition: var_global.c:196
Definition: z80asm.h:102
HtPP * ht_global_var
Definition: rz_analysis.h:624
RzFlagBind flb
Definition: rz_analysis.h:575
RzTypeDB * typedb
Definition: rz_analysis.h:602
RBTree global_var_tree
Definition: rz_analysis.h:625
Global variables.
Definition: rz_analysis.h:744
RZ_BORROW RzAnalysis * analysis
analysis pertaining to this global variable
Definition: rz_analysis.h:750
RzType * type
type of the variable
Definition: rz_analysis.h:748
ut64 addr
address of the global variable
Definition: rz_analysis.h:747
char * name
name of the variable
Definition: rz_analysis.h:746
RzFlag * f
Definition: rz_flag.h:78
type constrained by the type conditions
Definition: rz_type.h:209
RzTypeCond cond
Definition: rz_type.h:210
size_t len
Definition: rz_vector.h:47
RZ_API ut64 rz_type_db_get_bitsize(const RzTypeDB *typedb, RZ_NONNULL RzType *type)
Returns the type size in bits (target dependent)
Definition: type.c:779
RZ_API void rz_type_free(RZ_NULLABLE RzType *type)
Frees the RzType.
Definition: type.c:1273
RZ_API RZ_OWN char * rz_analysis_var_global_get_constraints_readable(RzAnalysisVarGlobal *glob)
Get the pritable string of global variable constraints.
Definition: var_global.c:331
RZ_API void rz_analysis_var_global_set_type(RzAnalysisVarGlobal *glob, RZ_NONNULL RZ_BORROW RzType *type)
Set the type of the global variable.
Definition: var_global.c:302
RZ_API RZ_BORROW RzAnalysisVarGlobal * rz_analysis_var_global_get_byaddr_at(RzAnalysis *analysis, ut64 addr)
Get the instance of global variable at the address.
Definition: var_global.c:207
RZ_API RZ_OWN RzAnalysisVarGlobal * rz_analysis_var_global_new(RZ_NONNULL const char *name, ut64 addr)
Create a new instance of global variable.
Definition: var_global.c:15
RZ_API bool rz_analysis_var_global_delete_byaddr_at(RzAnalysis *analysis, ut64 addr)
Same as rz_analysis_var_global_delete_byname at the address.
Definition: var_global.c:154
RZ_API bool rz_analysis_var_global_delete(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *glob)
Delete and free the global variable.
Definition: var_global.c:121
RZ_API RZ_OWN RzList * rz_analysis_var_global_get_all(RzAnalysis *analysis)
Get all of the added global variables.
Definition: var_global.c:259
RZ_API RZ_BORROW RzAnalysisVarGlobal * rz_analysis_var_global_get_byname(RzAnalysis *analysis, RZ_NONNULL const char *name)
Get the instance of global variable by its name.
Definition: var_global.c:190
RZ_API void rz_analysis_var_global_free(RzAnalysisVarGlobal *glob)
Free the global variable instance.
Definition: var_global.c:79
RZ_API bool rz_analysis_var_global_delete_byname(RzAnalysis *analysis, RZ_NONNULL const char *name)
Delete and free the global variable by its name.
Definition: var_global.c:136
RZ_API bool rz_analysis_var_global_delete_byaddr_in(RzAnalysis *analysis, ut64 addr)
Same as rz_analysis_var_global_delete_byname in the address.
Definition: var_global.c:172
RZ_API RZ_OWN bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *global_var)
Add the global variable into hashtable.
Definition: var_global.c:46
int global_var_node_cmp(const void *incoming, const RBNode *in_tree, void *user)
Definition: var_global.c:28
RZ_API RZ_NULLABLE RzFlagItem * rz_analysis_var_global_get_flag_item(RzAnalysisVarGlobal *glob)
Get the flag item corresponding to the given variable.
Definition: var_global.c:101
static bool global_var_collect_cb(void *user, const void *k, const void *v)
Definition: var_global.c:246
RZ_API RZ_BORROW RzAnalysisVarGlobal * rz_analysis_var_global_get_byaddr_in(RzAnalysis *analysis, ut64 addr)
Get the instance of global variable contains the address.
Definition: var_global.c:228
RZ_API bool rz_analysis_var_global_rename(RzAnalysis *analysis, RZ_NONNULL const char *old_name, RZ_NONNULL const char *newname)
Rename the global variable.
Definition: var_global.c:277
RZ_API void rz_analysis_var_global_add_constraint(RzAnalysisVarGlobal *glob, RzTypeConstraint *constraint)
Add a constaint to global variable.
Definition: var_global.c:320
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58