On Sat, Jan 27, 2024 at 09:22:59PM -0800, Steve Kargl wrote:
> On Sat, Jan 27, 2024 at 10:29:34PM +0100, Dimitry Andric wrote:
> > On 27 Jan 2024, at 18:08, Steve Kargl
> > wrote:
> > >
> > > In an attempt to cleanup a bit of src/lib/msun, I ran into
> > > a small issue that I cannot explain at the moment. If I have
> > > /usr/bin/ld in my path prior to /usr/local/bin/ld everything
> > > works
> > >
> > > % which ld
> > > /usr/bin/ld
> > > % make clean && make cleandepend
> > > % make
> > >
> > > and I have a libm.so.5. But if /usr/local/bin/ld is found, I
> > > see
> > >
> > > % cd msun
> > > % make clean && make cleandepend
> > > % make
> > > ..
> > > ld: error: version script assignment of 'FBSD_1.0' to symbol 'fabs' \
> > >failed: symbol not defined
> > > cc: error: linker command failed with exit code 1 (use -v to see
> > > invocation)
> > > *** Error code 1
> > >
> > > Stop.
> > > make: stopped in /usr/src/lib/msun
> > >
> > > % grep fabs /usr/src/lib/msun/Symbol.map
> > >fabs;
> > >fabsf;
> > >fabsl;
> > >
> > > But, if one looks in msun/Makefile, one see
> > >
> > > # FreeBSD's C library supplies these functions:
> > > #COMMON_SRCS+= s_fabs.c s_frexp.c s_isnan.c s_ldexp.c s_modf.c
> > >
> > > so fabs is not built with libm.
> > >
> > > % nm --dynamic /lib/libc.so.7 | grep fabs
> > > 000ba600 T fabs
> > > % nm --dynamic /lib/libm.so.5 | grep fabs
> > > 0001fa90 T fabsf
> > > 000252e0 T fabsl
> > >
> > >
> > > Is this a known issue? Should fabs be removed from Symbol.map?
> >
> > Yes, fabs is excluded in msun's Makefile:
> >
> > # FreeBSD's C library supplies these functions:
> > #COMMON_SRCS+= s_fabs.c s_frexp.c s_isnan.c s_ldexp.c s_modf.c
>
> Thanks for the quick response. I knew this, but
>
> > so it should not have been in Symbol.map at all.
>
> it has been this way for a very long time.
>
> > The comment is also
> > incorrect, since s_frexp.c and s_isnan.c *are* actually in COMMON_SRCS,
> > see lines 79 and 80 of the Makefile. (They are indeed also in libc, so
> > which one is chosen is only known by the linker. :)
>
> I would it depends on the search order of the libraries. For
> static linking, it's the order on the commandline. For rtld,
> it's the order of the libraries in the cache.
>
> % nm --dynamic /lib/libc.so.7 | grep snan
> 000ace30 T __isnan@@FBSD_1.0
> 000ace60 T __isnanf@@FBSD_1.0
> 000ace30 W isnan@@FBSD_1.0
> 000ace60 W isnanf@@FBSD_1.0
> % nm --dynamic /lib/libm.so.5 | grep snan
> 000220a0 T __isnanf@@FBSD_1.2
> 000220d0 T __isnanl@@FBSD_1.0
> 000220a0 W isnanf@@FBSD_1.0
>
> Not quite. isnan is in libc but libm. isnanf seems to be
> in both, and isnanl is only in libm. Does FBSD_1.2 trump
> FBSD_1.0 for __isnanf?
No, the binary specifies which version of the symbol it wants, either
__isnanf@FBSD_1.2 or __isnanf@FBSD_1.0, and the dynamic linker binds to
the version.
Which version is recorded into the consumer binary, is up to the static
linker (ld), and there it is normally defined by the order of the libraries
specified on the command line.
>
> > It doesn't complain with lld >= 16 because of
> > https://cgit.freebsd.org/src/commit/?id=2ba84b4bcdd60, where it add
> > -Wl,--undefined-version to suppress such warnings. I added that rather
> > big hammer to be able to continue importing llvm 16, but I see now that
> > it may be better to attempt to fix all individual failures due to
> > missing symbols.
> >
> > The reason that it still goes wrong if you put /usr/local/bin in front
> > of your PATH (or if you set LD explicitly to /usr/local/bin/ld) is that
> > /usr/bin/cc will pick /usr/bin/ld over whatever it finds in the PATH or
> > in the LD variable, while bsd.linker.mk still uses PATH or LD to find
> > the linker type and version. E.g., it concludes that the linker type is
> > BFD and the version is 2.40, then does not add the
> > -Wl,--undefined-version to allow undefined symbols.
>
> Thanks for the details. This had me stumped.
>
> --
> Steve