On Mon, 19 Sep 2016, Ed Schouten wrote:

2016-09-19 14:34 GMT+02:00 Bruce Evans <b...@freebsd.org>:
+#if (LDBL_MANT_DIG == 53)
+__weak_reference(fmod, fmodl);
+#endif


I've noticed that libm uses __weak_reference() all over the place, but
I guess that in this specific case there is no reason to use them,
right? Wouldn't it make more sense to use strong references here, so
that they are consistent with other architectures?

I just copied what das did here.

Weak symbols are less portable in theory but more portable in practice:
- the ifdefs depend on compiler support for __strong_reference() but
  not for __weak_reference
- there was apparently no compiler support for __strong_reference() in
  icc, and it is still not defined if __INTEL_COMPILER (so the hundreds
  of other __INTEL_COMPILER ifdefs are nonsense, since __strong_reference()
  is now used all over the place)
- __weak_reference() was implemented in FreeBSD in 1994 but
  __strong_reference() was not implemented until 2000 -- it is barely in
  FreeBSD-4
- however, it is __strong_reference() that requires less toolchain support.
  I think just asm() with ".globl" and ".equ" or ".set" would work for
  it.  __weak_reference() needs the less portable ".weak" instead of
  ".globl".  The compiler __alias__ attribute used to define
  __strong_reference() just generates these directives on x86, except
  clang spells ".equ" worse as "=" (it even rewrites ".equ" in the asm
  to "=") and also generates ".type", and gcc-4.2.1 generates ".set"
  instead of ".equ" (it doesn't rewrite the asm).
- at least, with ELF.  Old versions of FreeBSD including FreeBSD-3 have
  even uglier ifdefs for this involving AOUT.  Apparently, a magic ".stab"
  was needed instead of ".weak".  A magic ".stab" was also used for
  aliasing.  Perhaps ".equ" was not powerful enough, and IIRC it indeed
  isn't in my aout implementation (IIRC it is not exported).  In direct
  asm, it is not needed for mere aliases for functions since you can
  just duplicate labels as needed.

The strong reference is also technically more correct in theory but less
useful in practice.  With non-broken (static) linkers, it gives an error
if the user tries to replace the library function by his own function.
An error is technically correct.  But the user should be allowed to do
this.  Libraries should have only one API per object file, to allow the
user to replace one function at a time (and to not bloat the linked
executable with unused functions).  libm mostly does this.  However, for
these aliases, it puts the alias in the same file as the main function
for convenience.  With strong aliases, this would prevent the user from
replacing the alias without also replacing the main function.

Compiler support for aliases gives mere aliases.  It doesn't generate
extra code like the kernel ALTENTRY() macros to disambiguate the aliases
for -pg.  Compilers should optionally also generate such code (or
duplicate the function for small functions) for -g and -finstrument-
functions (so that you can put a breakpoint in fmodl() without hitting
in when you only call fmod() ...).  ALTENTRY() and END() are perhaps
not careful enough with ".type" and ".size" directives for the not-quite-
alias.  Compilers don't generate ".size" for the alias.

Bruce
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to