radare2/libr/core/libs.c
Ole André Vadla Ravnås abc9187e14 Fix invalid free() on teardown for io plugins (#5722)
For example given a plugin defined like this:

RIOPlugin r_io_plugin_foo = {
	.name = "foo",
	...snip...
};

#ifndef CORELIB
RLibStruct radare_plugin = {
	.type = R_LIB_TYPE_IO,
	.data = &r_io_plugin_foo,
	.version = R2_VERSION
};
#endif

We will try to `free(&r_io_plugin_foo)`, which was not allocated on the
heap. Static io plugins are OTOH allocated like this, so we need to do
the same for dynamically loaded io plugins. However, this is not the same
across the different plugin types, so we need to special-case io plugins
here.
2016-09-09 19:30:23 +02:00

102 lines
3.1 KiB
C

/* radare - LGPL - Copyright 2009-2016 - pancake */
#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; \
r_##x##_add (core->y, hand); \
return true; \
}\
static int __lib_##x##_dt(RLibPlugin *pl, void *p, void *u) { 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)); \
r_##x##_add (core->y, instance); \
return true; \
}\
static int __lib_##x##_dt(RLibPlugin *pl, void *p, void *u) { return true; }
// XXX api consistency issues
#define r_io_add r_io_plugin_add
CB_COPY (io, io)
#define r_core_add r_core_plugin_add
CB (core, rcmd)
#define r_debug_add r_debug_plugin_add
CB (debug, dbg)
#define r_bp_add r_bp_plugin_add
CB (bp, dbg->bp)
CB (lang, lang)
CB (anal, anal)
CB (asm, assembler)
CB (parse, parser)
CB (bin, bin)
CB (egg, egg)
CB (fs, fs)
R_API void r_core_loadlibs_init(RCore *core) {
ut64 prev = r_sys_now();
#define DF(x,y,z) r_lib_add_handler(core->lib, R_LIB_TYPE_##x,y,&__lib_##z##_cb, &__lib_##z##_dt, core);
core->lib = r_lib_new ("radare_plugin");
DF (IO, "io plugins", io);
DF (CORE, "core plugins", core);
DF (DBG, "debugger plugins", debug);
DF (BP, "debugger breakpoint plugins", bp);
DF (LANG, "language plugins", lang);
DF (ANAL, "analysis plugins", anal);
DF (ASM, "(dis)assembler plugins", asm);
DF (PARSE, "parsing plugins", parse);
DF (BIN, "bin plugins", bin);
DF (EGG, "egg plugins", egg);
DF (FS, "fs plugins", fs);
core->times->loadlibs_init_time = r_sys_now () - prev;
}
R_API int r_core_loadlibs(RCore *core, int where, const char *path) {
char *p = NULL;
ut64 prev = r_sys_now();
#if R2_LOADLIBS
/* TODO: all those default plugin paths should be defined in r_lib */
if (!r_config_get_i (core->config, "cfg.plugins")) {
core->times->loadlibs_time = 0;
return false;
}
if (!where) where = -1;
if (path) r_lib_opendir (core->lib, path);
if (where & R_CORE_LOADLIBS_CONFIG) {
r_lib_opendir (core->lib, r_config_get (core->config, "dir.plugins"));
}
if (where & R_CORE_LOADLIBS_ENV) {
p = r_sys_getenv (R_LIB_ENV);
if (p && *p)
r_lib_opendir (core->lib, p);
free (p);
}
if (where & R_CORE_LOADLIBS_HOME) {
char *homeplugindir = r_str_home (R2_HOMEDIR"/plugins");
// eprintf ("OPENDIR (%s)\n", homeplugindir);
r_lib_opendir (core->lib, homeplugindir);
free (homeplugindir);
}
if (where & R_CORE_LOADLIBS_SYSTEM) {
#if __WINDOWS__
r_lib_opendir (core->lib, "plugins");
r_lib_opendir (core->lib, "share/radare2/"R2_VERSION"/plugins");
#else
r_lib_opendir (core->lib, R2_LIBDIR"/radare2/"R2_VERSION);
r_lib_opendir (core->lib, R2_LIBDIR"/radare2-extras/"R2_VERSION);
r_lib_opendir (core->lib, R2_LIBDIR"/radare2-bindings/"R2_VERSION);
#endif
}
#endif
core->times->loadlibs_time = r_sys_now() - prev;
return true;
}