Easier API for creating global variable (#3655)

This commit is contained in:
Anton Kochkov 2023-07-11 20:53:34 +08:00 committed by GitHub
parent 3599ba226f
commit 8e41d975bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 9 deletions

View file

@ -9,7 +9,6 @@
*
* \param name variable name
* \param addr variable address
* \param comment variable comment
* \return RzAnalysisVarGlobal *
*/
RZ_API RZ_OWN RzAnalysisVarGlobal *rz_analysis_var_global_new(RZ_NONNULL const char *name, ut64 addr) {
@ -25,7 +24,7 @@ RZ_API RZ_OWN RzAnalysisVarGlobal *rz_analysis_var_global_new(RZ_NONNULL const c
return glob;
}
int global_var_node_cmp(const void *incoming, const RBNode *in_tree, void *user) {
static int global_var_node_cmp(const void *incoming, const RBNode *in_tree, void *user) {
ut64 ia = *(ut64 *)incoming;
ut64 ta = container_of(in_tree, const RzAnalysisVarGlobal, rb)->addr;
if (ia < ta) {
@ -36,6 +35,15 @@ int global_var_node_cmp(const void *incoming, const RBNode *in_tree, void *user)
return 0;
}
static void global_var_set_type(RzAnalysisVarGlobal *glob, RzType *type) {
glob->type = type;
RzFlagItem *flag = rz_analysis_var_global_get_flag_item(glob);
if (flag) {
flag->size = rz_type_db_get_bitsize(glob->analysis->typedb, glob->type) / 8;
}
}
/**
* \brief Add the global variable into hashtable
*
@ -43,7 +51,7 @@ int global_var_node_cmp(const void *incoming, const RBNode *in_tree, void *user)
* \param global_var Global variable instance
* \return true if succeed
*/
RZ_API RZ_OWN bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *global_var) {
RZ_API bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *global_var) {
rz_return_val_if_fail(analysis && global_var, false);
RzAnalysisVarGlobal *existing_glob = NULL;
@ -70,6 +78,33 @@ RZ_API RZ_OWN bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL R
return true;
}
/**
* \brief Create the global variable and add into hashtable
*
* \param analysis RzAnalysis
* \param name Global variable name
* \param type Global variable type
* \param addr Global variable address
* \return true if succeed
*/
RZ_API bool rz_analysis_var_global_create(RzAnalysis *analysis, RZ_NONNULL const char *name, RZ_NONNULL RZ_BORROW RzType *type, ut64 addr) {
rz_return_val_if_fail(analysis && name && type, false);
RzAnalysisVarGlobal *glob = rz_analysis_var_global_new(name, addr);
if (!glob) {
return false;
}
global_var_set_type(glob, type);
if (!rz_analysis_var_global_add(analysis, glob)) {
rz_analysis_var_global_free(glob);
return false;
}
return true;
}
/**
* \brief Free the global variable instance
*
@ -302,12 +337,8 @@ RZ_API bool rz_analysis_var_global_rename(RzAnalysis *analysis, RZ_NONNULL const
RZ_API void rz_analysis_var_global_set_type(RzAnalysisVarGlobal *glob, RZ_NONNULL RZ_BORROW RzType *type) {
rz_return_if_fail(glob && type);
rz_type_free(glob->type);
glob->type = type;
RzFlagItem *flag = rz_analysis_var_global_get_flag_item(glob);
if (flag) {
flag->size = rz_type_db_get_bitsize(glob->analysis->typedb, glob->type) / 8;
}
global_var_set_type(glob, type);
}
/**

View file

@ -1708,7 +1708,8 @@ RZ_API void rz_analysis_fcn_vars_add_types(RzAnalysis *analysis, RZ_NONNULL RzAn
// Global vars
RZ_API RZ_OWN RzAnalysisVarGlobal *rz_analysis_var_global_new(RZ_NONNULL const char *name, ut64 addr);
RZ_API RZ_OWN bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *global_var);
RZ_API bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *global_var);
RZ_API bool rz_analysis_var_global_create(RzAnalysis *analysis, RZ_NONNULL const char *name, RZ_NONNULL RZ_BORROW RzType *type, ut64 addr);
RZ_API void rz_analysis_var_global_free(RzAnalysisVarGlobal *glob);
RZ_API RZ_NULLABLE RzFlagItem *rz_analysis_var_global_get_flag_item(RzAnalysisVarGlobal *glob);
RZ_API bool rz_analysis_var_global_delete(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *glob);

View file

@ -132,6 +132,23 @@ bool test_rz_analysis_global_var() {
glob = rz_analysis_var_global_get_byname(analysis, "bar");
mu_assert_null(glob, "get deleted global var");
// create global
typ = rz_type_parse_string_single(parser, "int", &errmsg);
mu_assert_notnull(typ, "parsed type");
mu_assert_true(rz_analysis_var_global_create(analysis, "crab", typ, 0x125418),
"create global var");
glob = rz_analysis_var_global_get_byname(analysis, "crab");
mu_assert_notnull(glob, "create a global variable");
mu_assert_streq(glob->name, "crab", "global var name");
mu_assert_eq(glob->addr, 0x125418, "global var address");
mu_assert_streq(glob->type->identifier.name, "int", "global var type");
flag = rz_analysis_var_global_get_flag_item(glob);
mu_assert_notnull(flag, "global var flag_item");
mu_assert_eq(flag->offset, glob->addr, "flag item addr");
mu_assert_streq(flag->name, "crab", "flag item name");
rz_type_parser_free(parser);
rz_core_free(core);
mu_end;