gmodule-dl: fix G_MODULE_BIND_LOCAL on Darwin

According to POSIX, the default behavior of `dlopen` is unspecified when
its flags include neither `RTLD_LOCAL` nor `RTLD_GLOBAL`. Consequently,
different platforms have different default behavior.

The default on Linux is `RTLD_LOCAL`, but the default on Darwin is
`RTLD_GLOBAL`. By passing `0` to `dlopen`, this results in the opposite
of the caller's intent when using `G_MODULE_BIND_LOCAL`.

Passing `RTLD_LOCAL` for `G_MODULE_BIND_LOCAL` allows the correct
behavior to be observed regardless of the platform's default.
This commit is contained in:
Randy Eckenrode 2024-07-10 18:27:53 -04:00
parent 4a73fbda8b
commit 73d913519d
No known key found for this signature in database
GPG Key ID: 64C1CD4EC2A600D9
2 changed files with 33 additions and 1 deletions

View File

@ -136,7 +136,7 @@ _g_module_open (const gchar *file_name,
lock_dlerror ();
handle = dlopen (file_name,
(bind_local ? 0 : RTLD_GLOBAL) | (bind_lazy ? RTLD_LAZY : RTLD_NOW));
(bind_local ? RTLD_LOCAL : RTLD_GLOBAL) | (bind_lazy ? RTLD_LAZY : RTLD_NOW));
if (!handle)
{
const gchar *message = fetch_dlerror (TRUE);

View File

@ -233,6 +233,37 @@ test_module_invalid_libtool_archive (void)
g_free (la_filename);
}
static void
test_local_binding (void)
{
gchar *plugin = NULL;
GModule *module_plugin = NULL, *module_self = NULL;
GError *error = NULL;
gboolean found_symbol = FALSE;
gpointer symbol = NULL;
g_test_summary ("Test that binding a library's symbols locally does not add them globally");
plugin = g_test_build_filename (G_TEST_BUILT, MODULE_FILENAME_PREFIX "moduletestplugin_a_" MODULE_TYPE, NULL);
module_plugin = g_module_open_full (plugin, G_MODULE_BIND_LOCAL, &error);
g_assert_no_error (error);
g_assert_nonnull (module_plugin);
module_self = g_module_open_full (NULL, 0, &error);
g_assert_no_error (error);
g_assert_nonnull (module_self);
found_symbol = g_module_symbol (module_self, "gplugin_say_boo_func", &symbol);
g_assert_false (found_symbol);
g_assert_null (symbol);
g_module_close (module_self);
g_module_close (module_plugin);
g_free (plugin);
}
int
main (int argc, char *argv[])
{
@ -240,6 +271,7 @@ main (int argc, char *argv[])
g_test_add_func ("/module/basics", test_module_basics);
g_test_add_func ("/module/invalid-libtool-archive", test_module_invalid_libtool_archive);
g_test_add_func ("/module/local-binding", test_local_binding);
return g_test_run ();
}