diff --git a/librz/analysis/cc.c b/librz/analysis/cc.c index 07dd5a67b43..2e895dbc29f 100644 --- a/librz/analysis/cc.c +++ b/librz/analysis/cc.c @@ -26,6 +26,7 @@ RZ_API void rz_analysis_cc_del(RzAnalysis *analysis, const char *name) { sdb_unset(DB, name, 0); cc_sdb_unsetf(DB, "cc.%s.ret", name); cc_sdb_unsetf(DB, "cc.%s.argn", name); + cc_sdb_unsetf(DB, "cc.%s.maxargs", name); for (int i = 0; i < RZ_ANALYSIS_CC_MAXARG; i++) { cc_sdb_unsetf(DB, "cc.%s.arg%d", name, i); } @@ -77,6 +78,11 @@ RZ_API bool rz_analysis_cc_set(RzAnalysis *analysis, const char *expr) { n++; } } + { + char maxargs[256]; + rz_strf(maxargs, "%d", n); + cc_sdb_setf(DB, maxargs, "cc.%s.maxargs", ccname); + } rz_list_free(ccArgs); free(e); free(args); @@ -197,27 +203,18 @@ RZ_API void rz_analysis_cc_set_error(RzAnalysis *analysis, const char *conventio } RZ_API int rz_analysis_cc_max_arg(RzAnalysis *analysis, const char *cc) { - int i = 0; rz_return_val_if_fail(analysis && DB && cc, 0); - static void *oldDB = NULL; - static char *oldCC = NULL; - static int oldArg = 0; - if (oldDB == DB && !strcmp(cc, oldCC)) { - return oldArg; + char *query = rz_str_newf("cc.%s.maxargs", cc); + if (!query) { + return 0; } - oldDB = DB; - free(oldCC); - oldCC = strdup(cc); - for (i = 0; i < RZ_ANALYSIS_CC_MAXARG; i++) { - char *query = rz_str_newf("cc.%s.arg%d", cc, i); - const char *res = query ? sdb_const_get(DB, query, 0) : NULL; - free(query); - if (!res) { - break; - } + const char *res = sdb_const_get(DB, query, 0); + free(query); + int maxargs = res ? atoi(res) : 0; + if (maxargs < 0 || maxargs > RZ_ANALYSIS_CC_MAXARG) { + return 0; } - oldArg = i; - return i; + return maxargs; } RZ_API const char *rz_analysis_cc_ret(RzAnalysis *analysis, const char *convention) { diff --git a/librz/analysis/var.c b/librz/analysis/var.c index 753c391ca0e..a4770049557 100644 --- a/librz/analysis/var.c +++ b/librz/analysis/var.c @@ -779,9 +779,11 @@ RZ_API int rz_analysis_var_get_argnum(RzAnalysisVar *var) { if (!reg) { return -1; } - int i; - int arg_max = var->fcn->cc ? rz_analysis_cc_max_arg(analysis, var->fcn->cc) : 0; - for (i = 0; i < arg_max; i++) { + int arg_max = 0; + if (RZ_STR_ISNOTEMPTY(var->fcn->cc)) { + arg_max = rz_analysis_cc_max_arg(analysis, var->fcn->cc); + } + for (int i = 0; i < arg_max; i++) { const char *reg_arg = rz_analysis_cc_arg(analysis, var->fcn->cc, i); if (reg_arg && !strcmp(reg->name, reg_arg)) { return i; diff --git a/test/unit/test_analysis_cc.c b/test/unit/test_analysis_cc.c index 1cfffd8310d..5f92edc47eb 100644 --- a/test/unit/test_analysis_cc.c +++ b/test/unit/test_analysis_cc.c @@ -12,6 +12,7 @@ static Sdb *ref_db() { sdb_set(db, "cc.sectarian.arg1", "rcx", 0); sdb_set(db, "cc.sectarian.arg0", "rdx", 0); sdb_set(db, "cc.sectarian.argn", "stack", 0); + sdb_set(db, "cc.sectarian.maxargs", "2", 0); sdb_set(db, "sectarian", "cc", 0); return db; } @@ -24,6 +25,7 @@ static Sdb *ref_db_self_err() { sdb_set(db, "cc.sectarian.arg1", "rcx", 0); sdb_set(db, "cc.sectarian.arg0", "rdx", 0); sdb_set(db, "cc.sectarian.argn", "stack", 0); + sdb_set(db, "cc.sectarian.maxargs", "2", 0); sdb_set(db, "sectarian", "cc", 0); return db; } diff --git a/test/unit/test_serialize_analysis.c b/test/unit/test_serialize_analysis.c index efaa9aa4794..a957ec97af1 100644 --- a/test/unit/test_serialize_analysis.c +++ b/test/unit/test_serialize_analysis.c @@ -1266,6 +1266,7 @@ static Sdb *cc_ref_db() { sdb_set(db, "cc.sectarian.arg1", "rcx", 0); sdb_set(db, "cc.sectarian.arg0", "rdx", 0); sdb_set(db, "cc.sectarian.argn", "stack", 0); + sdb_set(db, "cc.sectarian.maxargs", "2", 0); sdb_set(db, "sectarian", "cc", 0); return db; } @@ -1352,6 +1353,7 @@ Sdb *analysis_ref_db() { sdb_set(cc, "cc.sectarian.arg1", "rcx", 0); sdb_set(cc, "cc.sectarian.arg0", "rdx", 0); sdb_set(cc, "cc.sectarian.argn", "stack", 0); + sdb_set(cc, "cc.sectarian.maxargs", "2", 0); sdb_set(cc, "sectarian", "cc", 0); sdb_ns(db, "types", true);