Reuse R_PERM in RAnalVarAccess.type instead of custom enum ##analysis

This commit is contained in:
pancake 2024-07-09 13:36:24 +02:00 committed by GitHub
parent c9b159c265
commit 668984c309
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 45 additions and 44 deletions

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2010-2023 - pancake, oddcoder */ /* radare - LGPL - Copyright 2010-2024 - pancake, oddcoder */
#define R_LOG_ORIGIN "anal.var" #define R_LOG_ORIGIN "anal.var"
@ -632,7 +632,7 @@ R_API RAnalVar *r_anal_var_get_dst_var(RAnalVar *var) {
r_return_val_if_fail (var, NULL); r_return_val_if_fail (var, NULL);
RAnalVarAccess *acc; RAnalVarAccess *acc;
r_vector_foreach (&var->accesses, acc) { r_vector_foreach (&var->accesses, acc) {
if (!(acc->type & R_ANAL_VAR_ACCESS_TYPE_READ)) { if (!(acc->type & R_PERM_R)) {
continue; continue;
} }
ut64 addr = var->fcn->addr + acc->offset; ut64 addr = var->fcn->addr + acc->offset;
@ -644,7 +644,7 @@ R_API RAnalVar *r_anal_var_get_dst_var(RAnalVar *var) {
continue; continue;
} }
RAnalVarAccess *other_acc = r_anal_var_get_access_at (used_var, addr); RAnalVarAccess *other_acc = r_anal_var_get_access_at (used_var, addr);
if (other_acc && other_acc->type & R_ANAL_VAR_ACCESS_TYPE_WRITE) { if (other_acc && other_acc->type & R_PERM_W) {
return used_var; return used_var;
} }
} }
@ -1003,7 +1003,7 @@ static void extract_arg(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, const char
} }
const int maxarg = 32; // TODO: use maxarg ? const int maxarg = 32; // TODO: use maxarg ?
int rw = (op->direction == R_ANAL_OP_DIR_WRITE) ? R_ANAL_VAR_ACCESS_TYPE_WRITE : R_ANAL_VAR_ACCESS_TYPE_READ; int rw = (op->direction == R_ANAL_OP_DIR_WRITE) ? R_PERM_W : R_PERM_R;
if (*sign == '+') { if (*sign == '+') {
const bool isarg = type == R_ANAL_VAR_KIND_SPV ? ptr >= fcn->stack : ptr >= fcn->bp_off; const bool isarg = type == R_ANAL_VAR_KIND_SPV ? ptr >= fcn->stack : ptr >= fcn->bp_off;
const char *pfx = isarg ? ARGPREFIX : VARPREFIX; const char *pfx = isarg ? ARGPREFIX : VARPREFIX;
@ -1348,7 +1348,7 @@ R_API void r_anal_extract_rarg(RAnal *anal, RAnalOp *op, RAnalFunction *fcn, int
reg_set[i] = 1; reg_set[i] = 1;
} }
if (var) { if (var) {
r_anal_var_set_access (var, var->regname, op->addr, R_ANAL_VAR_ACCESS_TYPE_READ, 0); r_anal_var_set_access (var, var->regname, op->addr, R_PERM_R, 0);
r_meta_set_string (anal, R_META_TYPE_VARTYPE, op->addr, var->name); r_meta_set_string (anal, R_META_TYPE_VARTYPE, op->addr, var->name);
} }
} }
@ -1367,7 +1367,7 @@ R_API void r_anal_extract_rarg(RAnal *anal, RAnalOp *op, RAnalFunction *fcn, int
} }
RAnalVar *newvar = r_anal_function_set_var (fcn, delta, R_ANAL_VAR_KIND_REG, 0, size, true, vname); RAnalVar *newvar = r_anal_function_set_var (fcn, delta, R_ANAL_VAR_KIND_REG, 0, size, true, vname);
if (newvar) { if (newvar) {
r_anal_var_set_access (newvar, newvar->regname, op->addr, R_ANAL_VAR_ACCESS_TYPE_READ, 0); r_anal_var_set_access (newvar, newvar->regname, op->addr, R_PERM_R, 0);
} }
r_meta_set_string (anal, R_META_TYPE_VARTYPE, op->addr, vname); r_meta_set_string (anal, R_META_TYPE_VARTYPE, op->addr, vname);
free (vname); free (vname);
@ -1392,7 +1392,7 @@ R_API void r_anal_extract_rarg(RAnal *anal, RAnalOp *op, RAnalFunction *fcn, int
} }
RAnalVar *newvar = r_anal_function_set_var (fcn, delta, R_ANAL_VAR_KIND_REG, 0, size, true, vname); RAnalVar *newvar = r_anal_function_set_var (fcn, delta, R_ANAL_VAR_KIND_REG, 0, size, true, vname);
if (newvar) { if (newvar) {
r_anal_var_set_access (newvar, newvar->regname, op->addr, R_ANAL_VAR_ACCESS_TYPE_READ, 0); r_anal_var_set_access (newvar, newvar->regname, op->addr, R_PERM_R, 0);
} }
r_meta_set_string (anal, R_META_TYPE_VARTYPE, op->addr, vname); r_meta_set_string (anal, R_META_TYPE_VARTYPE, op->addr, vname);
free (vname); free (vname);

View File

@ -5228,10 +5228,12 @@ typedef struct {
ut64 initial_sp; ut64 initial_sp;
} EsilBreakCtx; } EsilBreakCtx;
static const char *reg_name_for_access(RAnalOp* op, RAnalVarAccessType type) { typedef int RPerm;
static const char *reg_name_for_access(RAnalOp* op, RPerm type) {
RAnalValue *dst = r_vector_at (&op->dsts, 0); RAnalValue *dst = r_vector_at (&op->dsts, 0);
RAnalValue *src = r_vector_at (&op->srcs, 0); RAnalValue *src = r_vector_at (&op->srcs, 0);
if (type == R_ANAL_VAR_ACCESS_TYPE_WRITE) { if (type == R_PERM_W) {
if (dst) { if (dst) {
return dst->reg; return dst->reg;
} }
@ -5241,11 +5243,11 @@ static const char *reg_name_for_access(RAnalOp* op, RAnalVarAccessType type) {
return NULL; return NULL;
} }
static ut64 delta_for_access(RAnalOp *op, RAnalVarAccessType type) { static ut64 delta_for_access(RAnalOp *op, RPerm type) {
RAnalValue *dst = r_vector_at (&op->dsts, 0); RAnalValue *dst = r_vector_at (&op->dsts, 0);
RAnalValue *src0 = r_vector_at (&op->srcs, 0); RAnalValue *src0 = r_vector_at (&op->srcs, 0);
RAnalValue *src1 = r_vector_at (&op->srcs, 1); RAnalValue *src1 = r_vector_at (&op->srcs, 1);
if (type == R_ANAL_VAR_ACCESS_TYPE_WRITE) { if (type == R_PERM_W) {
if (dst) { if (dst) {
return dst->imm + dst->delta; return dst->imm + dst->delta;
} }
@ -5260,10 +5262,8 @@ static ut64 delta_for_access(RAnalOp *op, RAnalVarAccessType type) {
return 0; return 0;
} }
static void handle_var_stack_access(REsil *esil, ut64 addr, RAnalVarAccessType type, int len) { static void handle_var_stack_access(REsil *esil, ut64 addr, RPerm type, int len) {
if (!esil || !esil->user) { R_RETURN_IF_FAIL (esil && esil->user);
return;
}
EsilBreakCtx *ctx = esil->user; EsilBreakCtx *ctx = esil->user;
const char *regname = reg_name_for_access (ctx->op, type); const char *regname = reg_name_for_access (ctx->op, type);
if (ctx->fcn && regname) { if (ctx->fcn && regname) {
@ -5303,7 +5303,7 @@ static bool is_stack(RIO *io, ut64 addr) {
static bool esilbreak_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len) { static bool esilbreak_mem_write(REsil *esil, ut64 addr, const ut8 *buf, int len) {
RCore *core = esil->anal->coreb.core; RCore *core = esil->anal->coreb.core;
handle_var_stack_access (esil, addr, R_ANAL_VAR_ACCESS_TYPE_WRITE, len); handle_var_stack_access (esil, addr, R_PERM_W, len);
// ignore writes in stack // ignore writes in stack
if (myvalid (core->io, addr) && r_io_read_at (core->io, addr, (ut8*)buf, len)) { if (myvalid (core->io, addr) && r_io_read_at (core->io, addr, (ut8*)buf, len)) {
if (!is_stack (core->io, addr)) { if (!is_stack (core->io, addr)) {
@ -5329,7 +5329,7 @@ static bool esilbreak_mem_read(REsil *esil, ut64 addr, ut8 *buf, int len) {
if (addr != UT64_MAX) { if (addr != UT64_MAX) {
esilbreak_last_read = addr; esilbreak_last_read = addr;
} }
handle_var_stack_access (esil, addr, R_ANAL_VAR_ACCESS_TYPE_READ, len); handle_var_stack_access (esil, addr, R_PERM_R, len);
if (myvalid (core->io, addr) && r_io_read_at (core->io, addr, (ut8*)buf, len)) { if (myvalid (core->io, addr) && r_io_read_at (core->io, addr, (ut8*)buf, len)) {
ut64 refptr = UT64_MAX; ut64 refptr = UT64_MAX;
bool trace = true; bool trace = true;
@ -5376,14 +5376,12 @@ static bool esilbreak_mem_read(REsil *esil, ut64 addr, ut8 *buf, int len) {
} }
static bool esilbreak_reg_write(REsil *esil, const char *name, ut64 *val) { static bool esilbreak_reg_write(REsil *esil, const char *name, ut64 *val) {
if (!esil || !esil->anal || !esil->user) { R_RETURN_VAL_IF_FAIL (esil && esil->anal && esil->user, false);
return false;
}
RAnal *anal = esil->anal; RAnal *anal = esil->anal;
EsilBreakCtx *ctx = esil->user; EsilBreakCtx *ctx = esil->user;
RAnalOp *op = ctx->op; RAnalOp *op = ctx->op;
RCore *core = anal->coreb.core; RCore *core = anal->coreb.core;
handle_var_stack_access (esil, *val, R_ANAL_VAR_ACCESS_TYPE_PTR, esil->anal->config->bits / 8); handle_var_stack_access (esil, *val, R_PERM_NONE, esil->anal->config->bits / 8);
const bool is_arm = !strcmp (core->anal->config->arch, "arm"); const bool is_arm = !strcmp (core->anal->config->arch, "arm");
//specific case to handle blx/bx cases in arm through emulation //specific case to handle blx/bx cases in arm through emulation
// XXX this thing creates a lot of false positives // XXX this thing creates a lot of false positives

View File

@ -1517,7 +1517,7 @@ static void list_vars(RCore *core, RAnalFunction *fcn, PJ *pj, int type, const c
r_cons_printf ("* %s\n", var->name); r_cons_printf ("* %s\n", var->name);
RAnalVarAccess *acc; RAnalVarAccess *acc;
r_vector_foreach (&var->accesses, acc) { r_vector_foreach (&var->accesses, acc) {
if (!(acc->type & R_ANAL_VAR_ACCESS_TYPE_READ)) { if (!(acc->type & R_PERM_R)) {
continue; continue;
} }
r_cons_printf ("R 0x%"PFMT64x" ", fcn->addr + acc->offset); r_cons_printf ("R 0x%"PFMT64x" ", fcn->addr + acc->offset);
@ -1525,7 +1525,7 @@ static void list_vars(RCore *core, RAnalFunction *fcn, PJ *pj, int type, const c
r_core_print_disasm_instructions (core, 0, 1); r_core_print_disasm_instructions (core, 0, 1);
} }
r_vector_foreach (&var->accesses, acc) { r_vector_foreach (&var->accesses, acc) {
if (!(acc->type & R_ANAL_VAR_ACCESS_TYPE_WRITE)) { if (!(acc->type & R_PERM_W)) {
continue; continue;
} }
r_cons_printf ("W 0x%"PFMT64x" ", fcn->addr + acc->offset); r_cons_printf ("W 0x%"PFMT64x" ", fcn->addr + acc->offset);
@ -1551,7 +1551,7 @@ static void list_vars(RCore *core, RAnalFunction *fcn, PJ *pj, int type, const c
r_list_free (list); r_list_free (list);
return; return;
} }
int access_type = type == 'R' ? R_ANAL_VAR_ACCESS_TYPE_READ : R_ANAL_VAR_ACCESS_TYPE_WRITE; int access_type = type == 'R' ? R_PERM_R : R_PERM_W;
if (pj) { if (pj) {
pj_a (pj); pj_a (pj);
} }
@ -2049,7 +2049,7 @@ static int var_cmd(RCore *core, const char *str) {
res = false; res = false;
break; break;
} }
int rw = (str[1] == 'g') ? R_ANAL_VAR_ACCESS_TYPE_READ : R_ANAL_VAR_ACCESS_TYPE_WRITE; int rw = (str[1] == 'g') ? R_PERM_R : R_PERM_W;
int ptr = *var->type == 's' ? idx - fcn->maxstack : idx; int ptr = *var->type == 's' ? idx - fcn->maxstack : idx;
RAnalOp *op = r_core_anal_op (core, addr, 0); RAnalOp *op = r_core_anal_op (core, addr, 0);
const char *ireg = op ? op->ireg : NULL; const char *ireg = op ? op->ireg : NULL;

View File

@ -7,6 +7,7 @@
// still required by core in lot of places // still required by core in lot of places
#define USE_VARSUBS 0 #define USE_VARSUBS 0
#include <r_cons.h>
#include <r_types.h> #include <r_types.h>
#include <r_io.h> #include <r_io.h>
#include <r_esil.h> #include <r_esil.h>
@ -503,17 +504,19 @@ typedef enum {
#define VARPREFIX "var" #define VARPREFIX "var"
#define ARGPREFIX "arg" #define ARGPREFIX "arg"
#if 0
typedef enum { typedef enum {
R_ANAL_VAR_ACCESS_TYPE_PTR = 0, R_ANAL_VAR_ACCESS_TYPE_PTR = 0,
R_ANAL_VAR_ACCESS_TYPE_READ = (1 << 0), R_ANAL_VAR_ACCESS_TYPE_READ = (1 << 0),
R_ANAL_VAR_ACCESS_TYPE_WRITE = (1 << 1) R_ANAL_VAR_ACCESS_TYPE_WRITE = (1 << 1)
} RAnalVarAccessType; } RAnalVarAccessType;
#endif
typedef struct r_anal_var_access_t { typedef struct r_anal_var_access_t {
const char *reg; // register used for access const char *reg; // register used for access
st64 offset; // relative to the function's entrypoint st64 offset; // relative to the function's entrypoint
st64 stackptr; // delta added to register to get the var, e.g. [rbp - 0x10] st64 stackptr; // delta added to register to get the var, e.g. [rbp - 0x10]
ut8 type; // RAnalVarAccessType bits ut8 type; // R_PERM_{R/W/NONE} // TODO: R2_600 what about using rwx instead of custom enum?
} RAnalVarAccess; } RAnalVarAccess;
typedef struct r_anal_var_constraint_t { typedef struct r_anal_var_constraint_t {
@ -608,7 +611,8 @@ typedef struct r_anal_bb_t {
ut8 *op_bytes; ut8 *op_bytes;
ut8 *parent_reg_arena; ut8 *parent_reg_arena;
int parent_reg_arena_size; int parent_reg_arena_size;
#if R2_590 #if R2_600
// for the oppos
USE RVec USE RVec
#else #else
ut16 *op_pos; // offsets of instructions in this block, count is ninstr - 1 (first is always 0) ut16 *op_pos; // offsets of instructions in this block, count is ninstr - 1 (first is always 0)
@ -620,7 +624,6 @@ typedef struct r_anal_bb_t {
ut64 cmpval; ut64 cmpval;
const char *cmpreg; const char *cmpreg;
ut32 bbhash; // calculated with xxhash ut32 bbhash; // calculated with xxhash
RList *fcns; RList *fcns;
RAnal *anal; RAnal *anal;
char *esil; char *esil;
@ -721,17 +724,17 @@ enum {
R_ANAL_ESIL_DFG_TAG_MEM = 64, R_ANAL_ESIL_DFG_TAG_MEM = 64,
R_ANAL_ESIL_DFG_TAG_MERGE = 128, R_ANAL_ESIL_DFG_TAG_MERGE = 128,
R_ANAL_ESIL_DFG_TAG_SIBLING = 256, R_ANAL_ESIL_DFG_TAG_SIBLING = 256,
}; //RAnalEsilDFGTagType }; // RAnalEsilDFGTagType
typedef struct r_anal_esil_dfg_t { typedef struct r_anal_esil_dfg_t {
ut32 idx; ut32 idx;
int fd; int fd;
RIOBind iob; RIOBind iob;
RReg *reg; RReg *reg;
Sdb *regs; //resolves regnames to intervals Sdb *regs; // resolves regnames to intervals
RRBTree *vars; //vars represented in regs and mem RRBTree *vars; // vars represented in regs and mem
RQueue *todo; //todo-queue allocated in this struct for perf RQueue *todo; // todo-queue allocated in this struct for perf
void *insert; //needed for setting regs in dfg void *insert; // needed for setting regs in dfg
RGraph *flow; RGraph *flow;
RGraphNode *cur; RGraphNode *cur;
RGraphNode *old; RGraphNode *old;
@ -787,7 +790,7 @@ typedef struct r_anal_plugin_t {
} RAnalPlugin; } RAnalPlugin;
/*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/
int * (r_anal_compare) (RAnalFunction , RAnalFunction ); int * (r_anal_compare) (RAnalFunction , RAnalFunction);
/*----------------------------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------------------------*/
#ifdef R_API #ifdef R_API
@ -1021,7 +1024,6 @@ R_API int r_anal_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int le
R_API int r_anal_opasm(RAnal *anal, ut64 pc, const char *s, ut8 *outbuf, int outlen); R_API int r_anal_opasm(RAnal *anal, ut64 pc, const char *s, ut8 *outbuf, int outlen);
R_API char *r_anal_op_tostring(RAnal *anal, RAnalOp *op); R_API char *r_anal_op_tostring(RAnal *anal, RAnalOp *op);
/* pin */ /* pin */
R_API void r_anal_pin_init(RAnal *a); R_API void r_anal_pin_init(RAnal *a);
R_API void r_anal_pin_fini(RAnal *a); R_API void r_anal_pin_fini(RAnal *a);
@ -1249,7 +1251,6 @@ R_API int r_anal_data_type(RAnal *a, ut64 da);
R_API RAnalData *r_anal_data_new_string(ut64 addr, const char *p, int size, int wide); R_API RAnalData *r_anal_data_new_string(ut64 addr, const char *p, int size, int wide);
R_API RAnalData *r_anal_data_new(ut64 addr, int type, ut64 n, const ut8 *buf, int len); R_API RAnalData *r_anal_data_new(ut64 addr, int type, ut64 n, const ut8 *buf, int len);
R_API void r_anal_data_free(RAnalData *d); R_API void r_anal_data_free(RAnalData *d);
#include <r_cons.h>
R_API char *r_anal_data_tostring(RAnalData *d, RConsPrintablePalette *pal); R_API char *r_anal_data_tostring(RAnalData *d, RConsPrintablePalette *pal);
/* meta /* meta

View File

@ -79,6 +79,7 @@
#define R_PERM_R 4 #define R_PERM_R 4
#define R_PERM_W 2 #define R_PERM_W 2
#define R_PERM_X 1 #define R_PERM_X 1
#define R_PERM_NONE 0
#define R_PERM_RW (R_PERM_R|R_PERM_W) #define R_PERM_RW (R_PERM_R|R_PERM_W)
#define R_PERM_RX (R_PERM_R|R_PERM_X) #define R_PERM_RX (R_PERM_R|R_PERM_X)
#define R_PERM_RWX (R_PERM_R|R_PERM_W|R_PERM_X) #define R_PERM_RWX (R_PERM_R|R_PERM_W|R_PERM_X)
@ -88,6 +89,7 @@
#define R_PERM_PRIV 16 #define R_PERM_PRIV 16
#define R_PERM_ACCESS 32 #define R_PERM_ACCESS 32
#define R_PERM_CREAT 64 #define R_PERM_CREAT 64
// R2_600 typedef int RPerm;
// HACK to fix capstone-android-mips build // HACK to fix capstone-android-mips build

View File

@ -95,10 +95,10 @@ bool test_r_anal_var(void) {
// accesses // accesses
r_anal_var_set_access (a, "rsp", 0x120, R_ANAL_VAR_ACCESS_TYPE_READ, 42); r_anal_var_set_access (a, "rsp", 0x120, R_PERM_R, 42);
r_anal_var_set_access (a, "rbp", 0x130, R_ANAL_VAR_ACCESS_TYPE_WRITE, 13); r_anal_var_set_access (a, "rbp", 0x130, R_PERM_W, 13);
r_anal_var_set_access (b, "rsp", 0x120, R_ANAL_VAR_ACCESS_TYPE_WRITE, 123); r_anal_var_set_access (b, "rsp", 0x120, R_PERM_W, 123);
r_anal_var_set_access (b, "rbp", 0x10, R_ANAL_VAR_ACCESS_TYPE_WRITE, -100); r_anal_var_set_access (b, "rbp", 0x10, R_PERM_W, -100);
st64 stackptr = r_anal_function_get_var_stackptr_at (fcn, -0x10, 0x12345); st64 stackptr = r_anal_function_get_var_stackptr_at (fcn, -0x10, 0x12345);
mu_assert_eq (stackptr, ST64_MAX, "unset stackptr"); mu_assert_eq (stackptr, ST64_MAX, "unset stackptr");
@ -135,14 +135,14 @@ bool test_r_anal_var(void) {
used_vars = r_anal_function_get_vars_used_at (fcn, 0xffffffffffff0130UL); // addresses should stay the same used_vars = r_anal_function_get_vars_used_at (fcn, 0xffffffffffff0130UL); // addresses should stay the same
mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars)); mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars));
r_anal_var_set_access (a, "rbp", 0xffffffffffff0130UL, R_ANAL_VAR_ACCESS_TYPE_READ, 42); r_anal_var_set_access (a, "rbp", 0xffffffffffff0130UL, R_PERM_R, 42);
used_vars = r_anal_function_get_vars_used_at (fcn, 0xffffffffffff0130UL); used_vars = r_anal_function_get_vars_used_at (fcn, 0xffffffffffff0130UL);
mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count"); mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count");
mu_assert ("used vars", r_pvector_contains (used_vars, a)); mu_assert ("used vars", r_pvector_contains (used_vars, a));
used_vars = r_anal_function_get_vars_used_at (fcn, 0x123); used_vars = r_anal_function_get_vars_used_at (fcn, 0x123);
mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars)); mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars));
r_anal_var_set_access (a, "rbp" , 0x123, R_ANAL_VAR_ACCESS_TYPE_READ, 42); r_anal_var_set_access (a, "rbp" , 0x123, R_PERM_R, 42);
used_vars = r_anal_function_get_vars_used_at (fcn, 0x123); used_vars = r_anal_function_get_vars_used_at (fcn, 0x123);
mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count"); mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count");
mu_assert ("used vars", r_pvector_contains (used_vars, a)); mu_assert ("used vars", r_pvector_contains (used_vars, a));
@ -167,7 +167,7 @@ bool test_r_anal_var(void) {
used_vars = r_anal_function_get_vars_used_at (fcn, 0x8000000000000100); used_vars = r_anal_function_get_vars_used_at (fcn, 0x8000000000000100);
mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars)); mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars));
r_anal_var_set_access (a, "rbp", 0x8000000000000100, R_ANAL_VAR_ACCESS_TYPE_READ, 987321); r_anal_var_set_access (a, "rbp", 0x8000000000000100, R_PERM_R, 987321);
used_vars = r_anal_function_get_vars_used_at (fcn, 0x8000000000000100); used_vars = r_anal_function_get_vars_used_at (fcn, 0x8000000000000100);
mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count"); mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count");
mu_assert ("used vars", r_pvector_contains (used_vars, a)); mu_assert ("used vars", r_pvector_contains (used_vars, a));
@ -176,7 +176,7 @@ bool test_r_anal_var(void) {
used_vars = r_anal_function_get_vars_used_at (fcn, 0x7ffffffffffffe00); used_vars = r_anal_function_get_vars_used_at (fcn, 0x7ffffffffffffe00);
mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars)); mu_assert ("no used vars", !used_vars || r_pvector_length (used_vars));
r_anal_var_set_access (a, "rbp", 0x7ffffffffffffe00, R_ANAL_VAR_ACCESS_TYPE_READ, 777); r_anal_var_set_access (a, "rbp", 0x7ffffffffffffe00, R_PERM_R, 777);
used_vars = r_anal_function_get_vars_used_at (fcn, 0x7ffffffffffffe00); used_vars = r_anal_function_get_vars_used_at (fcn, 0x7ffffffffffffe00);
mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count"); mu_assert_eq (r_pvector_length (used_vars), 1, "used vars count");
mu_assert ("used vars", r_pvector_contains (used_vars, a)); mu_assert ("used vars", r_pvector_contains (used_vars, a));