diff --git a/libr/core/cmd_log.inc.c b/libr/core/cmd_log.inc.c index 954e33c6e6f8d..e32173748c500 100644 --- a/libr/core/cmd_log.inc.c +++ b/libr/core/cmd_log.inc.c @@ -17,7 +17,7 @@ static RCoreHelpMessage help_msg_L = { "Usage:", "L[acio]", "[-name][ file]", "L", "", "show this help", "L", " blah."R_LIB_EXT, "load plugin file", - "L-", "duk", "unload core plugin by name", + "L-", "duk", "unload core plugin by name or file name", "La", "[qj]", "list arch plugins", "LA", "[qj]", "list analysis plugins", "Lb", "[qj]", "list bin plugins", @@ -623,6 +623,15 @@ static int cmd_plugins(void *data, const char *input) { r_list_foreach (core->rcmd->plist, iter, cp) { pj_o (pj); r_lib_meta_pj (pj, &cp->meta); + if (cp->meta.name) { + bool found; + RLibPlugin *plugin = ht_pp_find (core->lib->plugins_ht, cp->meta.name, &found); + if (found && plugin) { + if (plugin->file) { + pj_ks (pj, "path", plugin->file); + } + } + } pj_end (pj); } pj_end (pj); diff --git a/libr/core/core.c b/libr/core/core.c index 2389bdf14e389..ff373e15ee39e 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -2855,6 +2855,7 @@ R_API void r_core_fini(RCore *c) { r_list_free (c->watchers); r_list_free (c->scriptstack); r_core_task_scheduler_fini (&c->tasks); + r_lib_free (c->lib); c->rcmd = r_cmd_free (c->rcmd); r_list_free (c->cmd_descriptors); /* @@ -2864,7 +2865,6 @@ R_API void r_core_fini(RCore *c) { if (c->anal->esil) { c->anal->esil->anal = NULL; } - r_lib_free (c->lib); r_anal_free (c->anal); r_asm_free (c->rasm); c->rasm = NULL; diff --git a/libr/core/libs.c b/libr/core/libs.c index 2f12fb545d8e4..432ac5e68d66f 100644 --- a/libr/core/libs.c +++ b/libr/core/libs.c @@ -3,34 +3,38 @@ #include "r_core.h" #include "config.h" -#define CB(x, y)\ - static int __lib_ ## x ## _cb (RLibPlugin * pl, void *user, void *data) {\ - struct r_ ## x ## _plugin_t *hand = (struct r_ ## x ## _plugin_t *)data;\ - RCore *core = (RCore *) user;\ +#define CB(x, y) \ + static int __lib_ ## x ## _cb (RLibPlugin *pl, void *user, void *data) { \ + struct r_ ## x ## _plugin_t *hand = (struct r_ ## x ## _plugin_t *)data; \ + RCore *core = (RCore *)user; \ pl->free = NULL; \ - r_ ## x ## _plugin_add (core->y, hand);\ - return true;\ - }\ - static int __lib_ ## x ## _dt (RLibPlugin * pl, void *user, void *data) { \ + pl->name = strdup (hand->meta.name); \ + r_ ## x ## _plugin_add (core->y, hand); \ + return true; \ + } \ + static int __lib_ ## x ## _dt (RLibPlugin *pl, void *user, void *data) { \ struct r_ ## x ## _plugin_t *hand = (struct r_ ## x ## _plugin_t *)data; \ - RCore *core = (RCore *) user; \ + RCore *core = (RCore *)user; \ + free (pl->name); \ return r_ ## x ## _plugin_remove (core->y, hand); \ } // TODO: deprecate this -#define CB_COPY(x, y)\ - static int __lib_ ## x ## _cb (RLibPlugin * pl, void *user, void *data) {\ - struct r_ ## x ## _plugin_t *hand = (struct r_ ## x ## _plugin_t *)data;\ - struct r_ ## x ## _plugin_t *instance;\ - RCore *core = (RCore *) user;\ - instance = R_NEW (struct r_ ## x ## _plugin_t);\ - memcpy (instance, hand, sizeof (struct r_ ## x ## _plugin_t));\ - r_ ## x ## _plugin_add (core->y, instance);\ - return true;\ - }\ +#define CB_COPY(x, y) \ + static int __lib_ ## x ## _cb (RLibPlugin *pl, void *user, void *data) { \ + struct r_ ## x ## _plugin_t *hand = (struct r_ ## x ## _plugin_t *)data; \ + struct r_ ## x ## _plugin_t *instance; \ + RCore *core = (RCore *)user; \ + instance = R_NEW (struct r_ ## x ## _plugin_t); \ + memcpy (instance, hand, sizeof (struct r_ ## x ## _plugin_t)); \ + pl->name = strdup (hand->meta.name); \ + r_ ## x ## _plugin_add (core->y, instance); \ + return true; \ + } \ static int __lib_ ## x ## _dt (RLibPlugin *pl, void *user, void *data) { \ struct r_ ## x ## _plugin_t *hand = (struct r_ ## x ## _plugin_t *)data; \ - RCore *core = (RCore *) user; \ + RCore *core = (RCore *)user; \ + free (pl->name); \ return r_ ## x ## _plugin_remove (core->y, hand); \ } diff --git a/libr/include/r_lib.h b/libr/include/r_lib.h index f3315f6addf3e..524c88b2dfb73 100644 --- a/libr/include/r_lib.h +++ b/libr/include/r_lib.h @@ -62,9 +62,7 @@ typedef struct r_lib_plugin_t { struct r_lib_handler_t *handler; void *dl_handler; // DL HANDLER void (*free)(void *data); -#if 0 - RPluginMeta meta; -#endif + char *name; // From the RPluginMeta's name } RLibPlugin; /* store list of initialized plugin handlers */ @@ -111,7 +109,6 @@ enum { R_LIB_TYPE_LAST }; -typedef int (*RLibLifeCycleCallback)(RLibPlugin *, void *, void *); typedef struct r_lib_t { /* linked list with all the plugin handler */ diff --git a/libr/util/lib.c b/libr/util/lib.c index 1feefdd845282..36b84b9395ecd 100644 --- a/libr/util/lib.c +++ b/libr/util/lib.c @@ -216,25 +216,40 @@ R_API RLibHandler *r_lib_get_handler(RLib *lib, int type) { return lib->handlers_bytype[type]; } +static int delete_plugin(RLib *lib, RLibPlugin *plugin) { + + int ret = -1; + bool found; + ht_pp_find (lib->plugins_ht, plugin->name, &found); + if (found) { + ht_pp_delete (lib->plugins_ht, plugin->name); + } + + if (plugin->handler && plugin->handler->destructor) { + // some plugins will return true here for sucess + ret = plugin->handler->destructor (plugin, plugin->handler->user, plugin->data); + } + + if (plugin->free) { + plugin->free (plugin->data); + } + + free (plugin->file); + return ret; +} + R_API int r_lib_close(RLib *lib, const char *file) { RLibPlugin *p; RListIter *iter, *iter2; r_list_foreach_safe (lib->plugins, iter, iter2, p) { - if ((!file || !strcmp (file, p->file))) { + if ((!file || !strcmp (file, p->file) || !strcmp (file, p->name))) { int ret = 0; - if (p->handler && p->handler->destructor) { - ret = p->handler->destructor (p, p->handler->user, p->data); - } - if (p->free) { - p->free (p->data); - } - free (p->file); + ret = delete_plugin (lib, p); r_list_delete (lib->plugins, iter); if (file) { return ret; } - break; } } if (!file) { @@ -245,31 +260,21 @@ R_API int r_lib_close(RLib *lib, const char *file) { R_LOG_DEBUG ("similar p->file: %s", p->file); if (strstr (p->file, file)) { int ret = 0; - if (p->handler && p->handler->destructor) { - ret = p->handler->destructor (p, - p->handler->user, p->data); - } R_LOG_DEBUG ("similar deleting: %s", p->file); - free (p->file); + ret = delete_plugin (lib, p); r_list_delete (lib->plugins, iter); - { - const char *file_name = r_str_rstr (file, R_SYS_DIR); - if (file_name) { - ht_pp_delete (lib->plugins_ht, file_name + 1); - } - } return ret; } } return -1; } -static bool already_loaded(RLib *lib, const char *file) { - const char *fileName = r_str_rstr (file, R_SYS_DIR); - if (fileName) { +static bool already_loaded(RLib *lib, const char *name) { + if (name) { bool found; - RLibPlugin *p = ht_pp_find (lib->plugins_ht, fileName + 1, &found); + RLibPlugin *p = ht_pp_find (lib->plugins_ht, name, &found); if (found && p) { + R_LOG_ERROR ("Not loading library because it has already been loaded from '%s'", p->file); return true; } } @@ -283,32 +288,33 @@ R_API int r_lib_open(RLib *lib, const char *file) { return -1; } - if (already_loaded (lib, file)) { - R_LOG_ERROR ("Not loading library because it has already been loaded from '%s'", file); - return -1; - } - - void *handler = r_lib_dl_open (file); - if (!handler) { + void *handle = r_lib_dl_open (file); + if (!handle) { R_LOG_DEBUG ("Cannot open library: '%s'", file); return -1; } - RLibStructFunc strf = (RLibStructFunc) r_lib_dl_sym (handler, lib->symnamefunc); + RLibStructFunc strf = (RLibStructFunc)r_lib_dl_sym (handle, lib->symnamefunc); RLibStruct *stru = NULL; if (strf) { stru = strf (); } if (!stru) { - stru = (RLibStruct *) r_lib_dl_sym (handler, lib->symname); + stru = (RLibStruct *)r_lib_dl_sym (handle, lib->symname); } if (!stru) { R_LOG_DEBUG ("Cannot find symbol '%s' in library '%s'", lib->symname, file); - r_lib_dl_close (handler); + r_lib_dl_close (handle); return -1; } - int res = r_lib_open_ptr (lib, file, handler, stru); + RPluginMeta *meta = (RPluginMeta *)(stru->data); + if (already_loaded (lib, meta->name)) { + r_lib_dl_close (handle); + return -1; + } + + int res = r_lib_open_ptr (lib, file, handle, stru); if (strf) { free (stru); } @@ -327,7 +333,7 @@ char *major_minor(const char *s) { return a; } -R_API int r_lib_open_ptr(RLib *lib, const char *file, void *handler, RLibStruct *stru) { +R_API int r_lib_open_ptr(RLib *lib, const char *file, void *handle, RLibStruct *stru) { R_RETURN_VAL_IF_FAIL (lib && file && stru, -1); if (stru->version && !lib->ignore_version) { char *mm0 = major_minor (stru->version); @@ -356,7 +362,7 @@ R_API int r_lib_open_ptr(RLib *lib, const char *file, void *handler, RLibStruct p->type = stru->type; p->data = stru->data; p->file = strdup (file); - p->dl_handler = handler; + p->dl_handler = handle; p->handler = r_lib_get_handler (lib, p->type); p->free = stru->free; @@ -365,13 +371,15 @@ R_API int r_lib_open_ptr(RLib *lib, const char *file, void *handler, RLibStruct if (ret == -1) { R_LOG_DEBUG ("Library handler has failed for '%s'", file); free (p->file); + if (p->name) { + free (p->name); + } free (p); - r_lib_dl_close (handler); + r_lib_dl_close (handle); } else { r_list_append (lib->plugins, p); - const char *fileName = r_str_rstr (file, R_SYS_DIR); - if (fileName) { - ht_pp_insert (lib->plugins_ht, strdup (fileName + 1), p); + if (p->name) { + ht_pp_insert (lib->plugins_ht, strdup (p->name), p); } } return ret; @@ -447,7 +455,7 @@ R_API bool r_lib_opendir(RLib *lib, const char *path) { return true; } -#define LibCB RLibLifeCycleCallback +#define LibCB RLibCallback R_API bool r_lib_add_handler(RLib *lib, int type, const char *desc, LibCB cb, LibCB dt, void *user) { R_RETURN_VAL_IF_FAIL (lib && desc, false); // TODO r2_590 resolve using lib->handlers_ht