https://sourceware.org/bugzilla/show_bug.cgi?id=34985
Bug ID: 34985
Summary: [2.46 Regression] ld fails to build on hosts without
<dlfcn.h>: implicit declaration of dlopen in plugin.c
Product: binutils
Version: 2.48 (HEAD)
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: binutils
Assignee: unassigned at sourceware dot org
Reporter: yegorslists at googlemail dot com
Target Milestone: ---
ld no longer builds on a host whose C library does not provide <dlfcn.h>,
even when configured with --disable-plugins. We hit this in Buildroot when
cross-compiling binutils to run on an ARM Cortex-M7 (no MMU) target with a
static-only uClibc-ng. uClibc-ng does not install <dlfcn.h> when it is built
without shared library support. The failure is:
plugin.c: In function 'plugin_opt_plugin':
plugin.c:252:23: error: implicit declaration of function 'dlopen'; did you
mean 'open'? [-Wimplicit-function-declaration]
252 | newplug->dlhandle = dlopen (plugin, RTLD_NOW);
| ^~~~~~
plugin.c:252:39: error: 'RTLD_NOW' undeclared (first use in this function)
plugin.c: In function 'plugin_load_plugins':
plugin.c:1134:37: error: implicit declaration of function 'dlsym'
[-Wimplicit-function-declaration]
plugin.c: In function 'plugin_call_cleanup':
plugin.c:1410:11: error: implicit declaration of function 'dlclose'; did you
mean 'gzclose'? [-Wimplicit-function-declaration]
binutils 2.45.1 builds fine in the same configuration.
Analysis:
Until 2.45, the body of ld/plugin.c was wrapped in "#if BFD_SUPPORTS_PLUGINS",
so it compiled to nothing when plugins were disabled. Commit 7e432e93f8aa
("Limit BFD_SUPPORTS_PLUGINS check to plugin.h and targets.c") removed that
guard, so plugin.c is now always compiled. Plugin availability is checked at
run time through bfd_plugin_enabled() instead.
plugin.c only gets dlopen, dlsym, dlclose and RTLD_NOW from <dlfcn.h>
(HAVE_DLFCN_H). On Windows (HAVE_WINDOWS_H) it uses local wrappers around
LoadLibrary, GetProcAddress and FreeLibrary. With neither header, those
symbols are undefined, and the file no longer compiles.
AC_PLUGINS in config/plugins.m4 already handles this host: with neither
dlfcn.h nor windows.h, plugins default to "no", and --enable-plugins is
rejected with "Building with plugin support requires a host that supports
dlopen". So configure works, and only the unconditional compilation of
ld/plugin.c breaks. At run time the dl* calls cannot be reached:
-plugin and -plugin-opt are ignored in lexsup.c when bfd_plugin_enabled()
returns false.
A possible fix would be for plugin.c to provide do-nothing fallbacks for
dlopen, dlsym, dlclose and RTLD_NOW when neither <dlfcn.h> nor <windows.h>
is available, next to the existing Windows wrappers. Another option is to
restore a guard around the dl*-dependent code.
How to reproduce:
Configure binutils 2.46 or later for a host whose sysroot has no
<dlfcn.h>, for example uClibc-ng built with HAVE_SHARED disabled, then run
"make all-ld":
./configure --host=arm-buildroot-uclinux-uclibcgnueabi \
--target=arm-buildroot-uclinux-uclibcgnueabi \
--disable-plugins --disable-shared --enable-static \
--disable-gdb --disable-sim --disable-gprofng
make all-ld
The generated ld/config.h contains "/* #undef HAVE_DLFCN_H */", and the
build stops on ld/plugin.c as shown above.
Buildroot autobuilder failure:
https://autobuild.buildroot.org/results/ee94fc7c8d5d76a8f359ee35fb03bc6dfc82986c
--
You are receiving this mail because:
You are on the CC list for the bug.