plugin-loader: Properly support compilation without dlopen()/dlsym() etc.

This only works if plugins are built monolithically and linked statically.

Closes strongswan/strongswan#2615
This commit is contained in:
Tobias Brunner
2025-01-13 17:51:14 +01:00
parent 41538cf259
commit d860c26e95
+24 -4
View File
@@ -191,10 +191,12 @@ struct plugin_entry_t {
*/ */
bool critical; bool critical;
#ifdef HAVE_DLADDR
/** /**
* dlopen handle, if in separate lib * dlopen handle, if in separate lib
*/ */
void *handle; void *handle;
#endif
/** /**
* List of features, as provided_feature_t * List of features, as provided_feature_t
@@ -208,10 +210,12 @@ struct plugin_entry_t {
static void plugin_entry_destroy(plugin_entry_t *entry) static void plugin_entry_destroy(plugin_entry_t *entry)
{ {
DESTROY_IF(entry->plugin); DESTROY_IF(entry->plugin);
#ifdef HAVE_DLADDR
if (entry->handle) if (entry->handle)
{ {
dlclose(entry->handle); dlclose(entry->handle);
} }
#endif
entry->features->destroy(entry->features); entry->features->destroy(entry->features);
free(entry); free(entry);
} }
@@ -369,11 +373,14 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle,
{ {
constructor = plugin_constructors->get(plugin_constructors, name); constructor = plugin_constructors->get(plugin_constructors, name);
} }
#elif defined(HAVE_DLADDR)
if (!constructor) if (!constructor)
#endif
{ {
constructor = dlsym(handle, create); constructor = dlsym(handle, create);
} }
#else
#error Neither dynamic linking nor static plugin constructors are supported!
#endif
if (!constructor) if (!constructor)
{ {
return NOT_FOUND; return NOT_FOUND;
@@ -412,8 +419,12 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
{ {
char create[128]; char create[128];
plugin_entry_t *entry; plugin_entry_t *entry;
void *handle; void *handle = NULL;
#ifdef HAVE_DLADDR
int flag = RTLD_LAZY; int flag = RTLD_LAZY;
handle = RTLD_DEFAULT;
#endif
if (snprintf(create, sizeof(create), "%s_plugin_create", if (snprintf(create, sizeof(create), "%s_plugin_create",
name) >= sizeof(create)) name) >= sizeof(create))
@@ -421,7 +432,7 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
return NULL; return NULL;
} }
translate(create, "-", "_"); translate(create, "-", "_");
switch (create_plugin(this, RTLD_DEFAULT, name, create, FALSE, critical, switch (create_plugin(this, handle, name, create, FALSE, critical,
&entry)) &entry))
{ {
case SUCCESS: case SUCCESS:
@@ -447,6 +458,7 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
return NULL; return NULL;
} }
} }
#ifdef HAVE_DLADDR
if (lib->settings->get_bool(lib->settings, "%s.dlopen_use_rtld_now", if (lib->settings->get_bool(lib->settings, "%s.dlopen_use_rtld_now",
FALSE, lib->ns)) FALSE, lib->ns))
{ {
@@ -480,6 +492,9 @@ static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
entry->handle = handle; entry->handle = handle;
this->plugins->insert_last(this->plugins, entry); this->plugins->insert_last(this->plugins, entry);
return entry; return entry;
#else
return NULL;
#endif
} }
CALLBACK(feature_filter, bool, CALLBACK(feature_filter, bool,
@@ -1347,10 +1362,12 @@ METHOD(plugin_loader_t, unload, void,
unload_features(this); unload_features(this);
while (this->plugins->remove_last(this->plugins, (void**)&entry) == SUCCESS) while (this->plugins->remove_last(this->plugins, (void**)&entry) == SUCCESS)
{ {
#ifdef HAVE_DLADDR
if (lib->leak_detective) if (lib->leak_detective)
{ /* keep handle to report leaks properly */ { /* keep handle to report leaks properly */
entry->handle = NULL; entry->handle = NULL;
} }
#endif
unregister_features(this, entry); unregister_features(this, entry);
plugin_entry_destroy(entry); plugin_entry_destroy(entry);
} }
@@ -1474,9 +1491,12 @@ plugin_loader_t *plugin_loader_create()
.features = hashlist_create( .features = hashlist_create(
(hashtable_hash_t)registered_feature_hash, (hashtable_hash_t)registered_feature_hash,
(hashtable_equals_t)registered_feature_equals, 64), (hashtable_equals_t)registered_feature_equals, 64),
.get_features = dlsym(RTLD_DEFAULT, "plugin_loader_feature_filter"),
); );
#ifdef HAVE_DLADDR
this->get_features = dlsym(RTLD_DEFAULT, "plugin_loader_feature_filter");
#endif
if (!this->get_features) if (!this->get_features)
{ {
this->get_features = get_features_default; this->get_features = get_features_default;