diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/module.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/util/module.c b/util/module.c index f0ed05fbd0..0c0f258923 100644 --- a/util/module.c +++ b/util/module.c @@ -110,7 +110,7 @@ void module_call_init(module_init_type type) } #ifdef CONFIG_MODULES -static int module_load_file(const char *fname, bool mayfail) +static int module_load_file(const char *fname, bool mayfail, bool export_symbols) { GModule *g_module; void (*sym)(void); @@ -118,7 +118,7 @@ static int module_load_file(const char *fname, bool mayfail) int len = strlen(fname); int suf_len = strlen(dsosuf); ModuleEntry *e, *next; - int ret; + int ret, flags; if (len <= suf_len || strcmp(&fname[len - suf_len], dsosuf)) { /* wrong suffix */ @@ -132,7 +132,11 @@ static int module_load_file(const char *fname, bool mayfail) assert(QTAILQ_EMPTY(&dso_init_list)); - g_module = g_module_open(fname, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + flags = G_MODULE_BIND_LAZY; + if (!export_symbols) { + flags |= G_MODULE_BIND_LOCAL; + } + g_module = g_module_open(fname, flags); if (!g_module) { if (!mayfail) { fprintf(stderr, "Failed to open module: %s\n", @@ -167,6 +171,12 @@ static int module_load_file(const char *fname, bool mayfail) out: return ret; } + +static const struct { + const char *name; + const char *dep; +} module_deps[] = { +}; #endif bool module_load_one(const char *prefix, const char *lib_name, bool mayfail) @@ -182,7 +192,8 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail) char *dirs[5]; char *module_name; int i = 0, n_dirs = 0; - int ret; + int ret, dep; + bool export_symbols = false; static GHashTable *loaded_modules; if (!g_module_supported()) { @@ -196,6 +207,17 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail) module_name = g_strdup_printf("%s%s", prefix, lib_name); + for (dep = 0; dep < ARRAY_SIZE(module_deps); dep++) { + if (strcmp(module_name, module_deps[dep].name) == 0) { + /* we depend on another module */ + module_load_one("", module_deps[dep].dep, false); + } + if (strcmp(module_name, module_deps[dep].dep) == 0) { + /* another module depends on us */ + export_symbols = true; + } + } + if (!g_hash_table_add(loaded_modules, module_name)) { g_free(module_name); return true; @@ -220,7 +242,7 @@ bool module_load_one(const char *prefix, const char *lib_name, bool mayfail) for (i = 0; i < n_dirs; i++) { fname = g_strdup_printf("%s/%s%s", dirs[i], module_name, CONFIG_HOST_DSOSUF); - ret = module_load_file(fname, mayfail); + ret = module_load_file(fname, mayfail, export_symbols); g_free(fname); fname = NULL; /* Try loading until loaded a module file */ |