Skip to content

Commit

Permalink
Fix #22445 - Store plugins by name rather than path ##core
Browse files Browse the repository at this point in the history
- Print plugin path with Lcj
- Use plugin name as opposed to the filename to detect if a plugin has already been loaded
- Refactor r_lib_close and allow L- (remove plugin) to work with the plugin's name in addition to file names
  • Loading branch information
MewtR authored and trufae committed Nov 28, 2024
1 parent 55afe17 commit 4b2234e
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 68 deletions.
11 changes: 10 additions & 1 deletion libr/core/cmd_log.inc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion libr/core/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
/*
Expand All @@ -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;
Expand Down
44 changes: 24 additions & 20 deletions libr/core/libs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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); \
}

Expand Down
5 changes: 1 addition & 4 deletions libr/include/r_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down
92 changes: 50 additions & 42 deletions libr/util/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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;
}
}
Expand All @@ -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);
}
Expand All @@ -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);
Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 4b2234e

Please sign in to comment.