From adebf3ea6c2eb5c7df45c3ef043f7ad66d18dd35 Mon Sep 17 00:00:00 2001 From: Rot127 Date: Thu, 24 Oct 2024 13:59:17 -0500 Subject: [PATCH] Implement handling of core plugin configurations --- librz/arch/asm.c | 4 ++-- librz/core/canalysis.c | 2 +- librz/core/cautocmpl.c | 2 +- librz/core/cmd/cmd_eval.c | 6 +++--- librz/core/core.c | 2 +- librz/core/cplugin.c | 38 +++++++++++++++++++++++++++++--------- librz/core/p/core_dex.c | 5 +++-- librz/core/p/core_java.c | 5 +++-- librz/include/rz_core.h | 23 +++++++++++++++++++++-- 9 files changed, 64 insertions(+), 23 deletions(-) diff --git a/librz/arch/asm.c b/librz/arch/asm.c index 6310e3b5471..e7b062a779d 100644 --- a/librz/arch/asm.c +++ b/librz/arch/asm.c @@ -425,7 +425,7 @@ RZ_API bool rz_asm_use_assembler(RzAsm *a, const char *name) { static void set_plugin_configs(RZ_BORROW RzCore *core, const char *plugin_name, RZ_OWN RzConfig *pcfg) { rz_return_if_fail(pcfg && core); rz_config_lock(pcfg, 1); - if (!ht_sp_insert(core->plugin_configs, plugin_name, pcfg)) { + if (!ht_sp_insert(core->plugins_config, plugin_name, pcfg)) { RZ_LOG_WARN("Plugin '%s' was already added.\n", plugin_name); } } @@ -438,7 +438,7 @@ static void set_plugin_configs(RZ_BORROW RzCore *core, const char *plugin_name, */ static void remove_plugin_config(RZ_BORROW RzCore *core, const char *plugin_name) { rz_return_if_fail(core && plugin_name); - ht_sp_delete(core->plugin_configs, plugin_name); + ht_sp_delete(core->plugins_config, plugin_name); } // TODO: this can be optimized using rz_str_hash() diff --git a/librz/core/canalysis.c b/librz/core/canalysis.c index 0e3f76afd74..33e0d464cec 100644 --- a/librz/core/canalysis.c +++ b/librz/core/canalysis.c @@ -3944,7 +3944,7 @@ static void core_analysis_using_plugins(RzCore *core) { rz_iterator_foreach(it, val) { RzCorePlugin *plugin = *val; if (plugin->analysis) { - plugin->analysis(core); + plugin->analysis(core, NULL); } } rz_iterator_free(it); diff --git a/librz/core/cautocmpl.c b/librz/core/cautocmpl.c index d3e0be1b526..e1a06fea182 100644 --- a/librz/core/cautocmpl.c +++ b/librz/core/cautocmpl.c @@ -557,7 +557,7 @@ static void autocmplt_cmd_arg_eval_key(RzCore *core, RzLineNSCompletionResult *r } } RzConfig **plugin_cfg; - RzIterator *it = ht_sp_as_iter(core->plugin_configs); + RzIterator *it = ht_sp_as_iter(core->plugins_config); rz_iterator_foreach(it, plugin_cfg) { rz_list_foreach ((*plugin_cfg)->nodes, iter, bt) { if (!strncmp(bt->name, s, len)) { diff --git a/librz/core/cmd/cmd_eval.c b/librz/core/cmd/cmd_eval.c index d83ab48652e..a5c0a7f8399 100644 --- a/librz/core/cmd/cmd_eval.c +++ b/librz/core/cmd/cmd_eval.c @@ -352,7 +352,7 @@ static void print_all_plugin_configs(const RzCore *core) { RzConfig **cfg; RzCmdStateOutput state = { 0 }; rz_cmd_state_output_init(&state, RZ_OUTPUT_MODE_QUIET); - RzIterator *it = ht_sp_as_iter(core->plugin_configs); + RzIterator *it = ht_sp_as_iter(core->plugins_config); rz_iterator_foreach(it, cfg) { rz_core_config_print_all(*cfg, "", &state); } @@ -376,10 +376,10 @@ static RZ_BORROW RzConfig *eval_get_config_obj_by_key(const RzCore *core, const const char *second_dot = strchr(first_dot + 1, '.'); bool cfg_found = false; if (!second_dot) { - cfg = ht_sp_find(core->plugin_configs, first_dot + 1, &cfg_found); + cfg = ht_sp_find(core->plugins_config, first_dot + 1, &cfg_found); } else { char *config_name = rz_sub_str_ptr(config_str, first_dot + 1, second_dot - 1); - cfg = ht_sp_find(core->plugin_configs, config_name, &cfg_found); + cfg = ht_sp_find(core->plugins_config, config_name, &cfg_found); free(config_name); } if (!cfg_found) { diff --git a/librz/core/core.c b/librz/core/core.c index ac47f72c350..38ee28f3241 100644 --- a/librz/core/core.c +++ b/librz/core/core.c @@ -1508,7 +1508,7 @@ RZ_API bool rz_core_init(RzCore *core) { core->cmdremote = 0; core->incomment = false; core->config = NULL; - core->plugin_configs = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_config_free); + core->plugins_config = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_config_free); core->http_up = false; ZERO_FILL(core->root_cmd_descriptor); core->print = rz_print_new(); diff --git a/librz/core/cplugin.c b/librz/core/cplugin.c index d1c9b6bb450..756e83921c2 100644 --- a/librz/core/cplugin.c +++ b/librz/core/cplugin.c @@ -7,6 +7,7 @@ #include #include #include "rz_core_plugins.h" +#include static RzCorePlugin *core_static_plugins[] = { RZ_CORE_STATIC_PLUGINS }; @@ -18,12 +19,15 @@ RZ_API bool rz_core_plugin_fini(RzCore *core) { rz_iterator_foreach(iter, val) { RzCorePlugin *plugin = *val; if (plugin->fini) { - plugin->fini(core); + bool found = false; + void *pdata = ht_sp_find(core->plugins_data, plugin->name, &found); + plugin->fini(core, found ? &pdata : NULL); } } rz_iterator_free(iter); ht_sp_free(core->plugins); - ht_sp_free(core->plugin_configs); + ht_sp_free(core->plugins_data); + ht_sp_free(core->plugins_config); core->plugins = NULL; return true; } @@ -31,31 +35,47 @@ RZ_API bool rz_core_plugin_fini(RzCore *core) { RZ_API bool rz_core_plugin_add(RzCore *core, RZ_NONNULL RzCorePlugin *plugin) { rz_return_val_if_fail(core, false); rz_return_val_if_fail(plugin && plugin->init && plugin->name && plugin->author && plugin->license, false); - // TODO: Add config from core plugin. - if (!ht_sp_insert(core->plugins, plugin->name, plugin)) { + bool found = false; + if (found) { RZ_LOG_WARN("Plugin '%s' was already added.\n", plugin->name); + return true; } - if (!plugin->init(core)) { + + ht_sp_insert(core->plugins, plugin->name, plugin); + ht_sp_insert(core->plugins_data, plugin->name, NULL); + HtSPKv *pdata = ht_sp_find_kv(core->plugins_data, plugin->name, NULL); + if (!plugin->init(core, &pdata->value)) { ht_sp_delete(core->plugins, plugin->name); + ht_sp_delete(core->plugins_data, plugin->name); return false; } + + if (plugin->get_config) { + RzConfig *pcfg = plugin->get_config(pdata->value); + rz_config_lock(pcfg, 1); + ht_sp_insert(core->plugins_config, plugin->name, pcfg); + } return true; } RZ_API bool rz_core_plugin_del(RzCore *core, RZ_NONNULL RzCorePlugin *plugin) { rz_return_val_if_fail(core && plugin, false); - ht_sp_delete(core->plugin_configs, plugin->name); - if (plugin->fini && !plugin->fini(core)) { + ht_sp_delete(core->plugins_config, plugin->name); + HtSPKv *pdata = ht_sp_find_kv(core->plugins_data, plugin->name, NULL); + if (plugin->fini && !plugin->fini(core, &pdata->value)) { return false; } + ht_sp_delete(core->plugins_data, plugin->name); + ht_sp_delete(core->plugins_config, plugin->name); return ht_sp_delete(core->plugins, plugin->name); } RZ_API bool rz_core_plugin_init(RzCore *core) { - int i; bool res = true; core->plugins = ht_sp_new(HT_STR_DUP, NULL, NULL); - for (i = 0; i < RZ_ARRAY_SIZE(core_static_plugins); i++) { + core->plugins_data = ht_sp_new(HT_STR_DUP, NULL, NULL); + core->plugins_config = ht_sp_new(HT_STR_DUP, NULL, (HtSPFreeValue)rz_config_free); + for (size_t i = 0; i < RZ_ARRAY_SIZE(core_static_plugins); i++) { if (!rz_core_plugin_add(core, core_static_plugins[i])) { RZ_LOG_ERROR("core: error loading core plugin '%s'\n", core_static_plugins[i]->name); res = false; diff --git a/librz/core/p/core_dex.c b/librz/core/p/core_dex.c index 6b172d80e29..fd4c021bfbb 100644 --- a/librz/core/p/core_dex.c +++ b/librz/core/p/core_dex.c @@ -290,7 +290,7 @@ static const RzCmdDescHelp dex_usage = { static_description_without_args(dexs, "prints the dex structure"); static_description_without_args(dexe, "prints the dex exported methods"); -static bool rz_cmd_dex_init_handler(RzCore *core) { +static bool rz_cmd_dex_init_handler(RzCore *core, void **private_data) { RzCmd *rcmd = core->rcmd; RzCmdDesc *root_cd = rz_cmd_get_root(rcmd); if (!root_cd) { @@ -309,7 +309,7 @@ static bool rz_cmd_dex_init_handler(RzCore *core) { return true; } -static bool rz_cmd_dex_fini_handler(RzCore *core) { +static bool rz_cmd_dex_fini_handler(RzCore *core, void **private_data) { RzCmd *rcmd = core->rcmd; RzCmdDesc *cd = rz_cmd_get_desc(rcmd, "dex"); rz_return_val_if_fail(cd, false); @@ -324,6 +324,7 @@ RzCorePlugin rz_core_plugin_dex = { .version = "1.0", .init = rz_cmd_dex_init_handler, .fini = rz_cmd_dex_fini_handler, + .get_config = NULL, }; #ifndef RZ_PLUGIN_INCORE diff --git a/librz/core/p/core_java.c b/librz/core/p/core_java.c index 97a294f54b2..2e922877ee6 100644 --- a/librz/core/p/core_java.c +++ b/librz/core/p/core_java.c @@ -291,7 +291,7 @@ static const RzCmdDescHelp name_help(javar) = { .args = name_args(javar), }; -static bool rz_cmd_java_init_handler(RzCore *core) { +static bool rz_cmd_java_init_handler(RzCore *core, void **private_data) { RzCmd *rcmd = core->rcmd; RzCmdDesc *root_cd = rz_cmd_get_root(rcmd); if (!root_cd) { @@ -315,7 +315,7 @@ static bool rz_cmd_java_init_handler(RzCore *core) { return true; } -static bool rz_cmd_java_fini_handler(RzCore *core) { +static bool rz_cmd_java_fini_handler(RzCore *core, void **private_data) { RzCmd *rcmd = core->rcmd; RzCmdDesc *cd = rz_cmd_get_desc(rcmd, "java"); rz_return_val_if_fail(cd, false); @@ -330,6 +330,7 @@ RzCorePlugin rz_core_plugin_java = { .version = "1.0", .init = rz_cmd_java_init_handler, .fini = rz_cmd_java_fini_handler, + .get_config = NULL, }; #ifndef RZ_PLUGIN_INCORE diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index 2c172833971..194cfaa8af8 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -95,7 +95,24 @@ typedef enum { RZ_CORE_WRITE_OP_SHIFT_RIGHT, ///< Write the shift right of existing byte and argument value } RzCoreWriteOp; -typedef bool (*RzCorePluginCallback)(RzCore *core); +/** + * \brief RzCore plugin callback. + * + * \param core the Core this plugin is assigned to. + * \param plugin_data Memory location to place the plugins private data pointer. + * + * \example + * ``` + * void plugin_init(RzCore *core, void **plugin_data) { + * *plugin_data = malloc(sizeof(PrivatePluginData)); + * } + * + * void plugin_fini(RzCore *core, void **plugin_data) { + * free(*plugin_data); + * } + * ``` + */ +typedef bool (*RzCorePluginCallback)(RzCore *core, void **plugin_data); typedef struct rz_core_plugin_t { const char *name; @@ -106,6 +123,7 @@ typedef struct rz_core_plugin_t { RzCorePluginCallback init; ///< Is called when the plugin is loaded by rizin RzCorePluginCallback fini; ///< Is called when the plugin is unloaded by rizin RzCorePluginCallback analysis; ///< Is called when automatic analysis is performed. + RZ_OWN RzConfig *(*get_config)(void *plugin_data); ///< Return private configuration of this plugin. } RzCorePlugin; typedef struct rz_core_rtr_host_t RzCoreRtrHost; @@ -253,8 +271,9 @@ struct rz_core_t { // They are used in pointer passing hacks in rz_types.h. RzIO *io; HtSP /**/ *plugins; ///< List of registered core plugins + HtSP /**/ *plugins_data; ///< Core plugins private data. + HtSP /*: RzConfig>*/ *plugins_config; ///< Pointers to plugin configurations. Indexed by "plugins." RzConfig *config; - HtSP /*: RzConfig>*/ *plugin_configs; ///< Pointers to plugin configurations. Indexed by "plugins." ut64 offset; // current seek ut64 prompt_offset; // temporarily set to offset to have $$ in expressions always stay the same during temp seeks ut32 blocksize;