Possibly ambiguous redefinition of _fpreset()?

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Possibly ambiguous redefinition of _fpreset()?

Keith Marshall-3
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Guys,

A recent bug report:
https://sourceforge.net/p/mingw/bugs/2326/

prompted me to revisit an idea I've been toying with for a while -- as
it grows bigger, there may be mileage in offering a dynamic linking
option for libmingwex.a.  However, when I try to create a DLL, I see:

  $ mingw32-gcc -shared -o libmingwex-0.dll -Wl,--whole-archive \
    libmingwex.a -Wl,--no-whole-archive -L.
  ./libmsvcrt.a(dgrcbs00324.o):(.text+0x0): multiple definition
   of `_fpreset'
  ./libmingw32.a(CRT_fp10.o):.../mingwrt/CRT_fp10.c:14: first
   defined here
  collect2: error: ld returned 1 exit status

The problem here is Danny Smith's stratagem for overriding the default
behaviour of MSVCRT.DLL's _fpreset() function, by shoving an alternative
function of the same name, but with somewhat different behaviour, (which
he implements in CRT_fp10.c), into libmingw32.a, whence it should be
statically linked ahead of -lmsvcrt; he then also provided a further
free-standing implementation, CRT_fp8.c, which attempts to redirect the
call back to the (*_imp__fpreset)() entry point in MSVCRT.DLL.

Am I over-thinking this?  Or is this as fragile as it appears?  Was
Danny off his game, when he wrote this stuff?  I guess it can't be too
serious a problem, since no issues have been reported in the 15 years
or so since Danny wrote it, but I can see the following possibilities:

1) User creates his own DLL, into which CRT_fp10.o is linked, and its
   _fpreset() symbol is re-exported; that now provides its own copy of
   (*_imp__fpreset)(), which neutralizes Danny's stratagem for calling
   the MSVCRT.DLL implementation.

2) User creates his own DLL, within which _fpreset() is called; user
   then links this DLL to his main program, which he also links with
   CRT_fp8.o; calls to _fpreset() in his DLL will still be resolved
   to whichever of CRT_fp10.o or CRT_fp8.o was linked into the DLL
   itself, ignoring the intent of linking the main program with
   CRT_fp8.o

Given that _fpreset() is strictly a Microsoft concept, conforming to no
known standard, I'd prefer to do away with this ambiguity, and leave it
to MSVCRT.DLL to resolve all references -- users who value standards,
and portability, should be using ISO-C99's fesetenv() function anyway.
Consequently, I've extensively revised Danny's implementation; would
anyone care to review the attached patch, before I commit it?

Of course, if the modified fesetenv() function continues to be linked
statically, from libmingwex.a, the potential for (non-deterministic)
behavioural ambiguity remains, spanning user created DLLs; that could
be mitigated by furnishing libmingwex-0.dll as an alternative to a
statically linked libmingwex.a, so that only a single fesetenv() need
exist within the process address space.

One final related issue: Danny's implementations of both CRT_fp10.c
and CRT_fp8.c defined fpreset(), (without leading underscore), as an
alias for each of his _fpreset() replacement implementations.  Given
the complete lack of any defining standard, that seems kind of pointless
to me.  Right now I've marked this as deprecated, but have retained a
__LIBIMPL__ stub for it, (reimplemented in terms of fesetenv()), but
it's messy, and I'd just as soon see it disappear altogether.

Any thoughts?
- --
Regards,
Keith.

Public key available from keys.gnupg.net
Key fingerprint: C19E C018 1547 DE50 E1D4 8F53 C0AD 36C6 347E 5A3F
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.20 (GNU/Linux)

iQIcBAEBAgAGBQJYm5v3AAoJEMCtNsY0flo/kMoP/0hMLVflTgbCBHDGxGSUByND
rLZzeA/lD+X2mlB4yNGGVI+VUGFEAbkt20oQYVT9vJiBAHB3+qAUoq3s1/+MJ1gw
9uUQMUKr5yrLTmi1nyR1gAR/zPnpzLwVoMVvVP46oV0skjf8+Ais11/kbHVyTSPy
B4e3WzJWka1f1WSKab+BU1iIzCksCf3OxwANWefHCNxvDBJlR30Hu9cDjbBkf4J5
0Cy4p99OuXQERzlcPplXQG79rrdeHGcH2q5insw8pDNG64Tm7Bbo9Th3JKblyuN+
BiOHHH0b3wPJ/tzJUJt84KBzeAvpv9+7ywzX8bu4Y7wnSneof9sBB/XpG9r8kwG1
+FJRPlHJ9KtMy5wFYka7/GWwmzyMf8vtUxz6awaf46IkPomQZvlLcAMOruvdUu+u
y7hkg4FnAgtGyfIxdQ20LTZjCZ3R5AkNrrpxaHpxU9OHe9TdFk79AL07Sbn+MCh7
iVVdZx+R79rxzbuX1nMJ/YKIYmsZnY1FAJMnmj+5bDzRrgkHf5zAPLYyPnLDJGIy
HHh7PDSrX0TewATDwtCYXB1xOlMKTIPsHjLdHXYla1uXq6syaj9UGn5N0NPh7qsr
RFGQ/thrhkEqWto5MzSEEu0YSlOkLMh6fzZGhLQu7Fy+LpOkZJXtiAHJFoJJrPKK
IwNh8PQbSoDJVLkR5AdT
=M8C7
-----END PGP SIGNATURE-----

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-dvlpr mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mingw-dvlpr

fenv.patch (54K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Possibly ambiguous redefinition of _fpreset()?

Earnie Boyd
On 2/8/2017 5:30 PM, Keith Marshall wrote:
> Guys,
>
> A recent bug report:
> https://sourceforge.net/p/mingw/bugs/2326/
>
> prompted me to revisit an idea I've been toying with for a while -- as
> it grows bigger, there may be mileage in offering a dynamic linking
> option for libmingwex.a.  However, when I try to create a DLL, I see:
>

I toyed with this idea in the distant past but

>   $ mingw32-gcc -shared -o libmingwex-0.dll -Wl,--whole-archive \
>     libmingwex.a -Wl,--no-whole-archive -L.
>   ./libmsvcrt.a(dgrcbs00324.o):(.text+0x0): multiple definition
>    of `_fpreset'
>   ./libmingw32.a(CRT_fp10.o):.../mingwrt/CRT_fp10.c:14: first
>    defined here
>   collect2: error: ld returned 1 exit status
>

I didn't have the time to resolve this.

> The problem here is Danny Smith's stratagem for overriding the default
> behaviour of MSVCRT.DLL's _fpreset() function, by shoving an alternative
> function of the same name, but with somewhat different behaviour, (which
> he implements in CRT_fp10.c), into libmingw32.a, whence it should be
> statically linked ahead of -lmsvcrt; he then also provided a further
> free-standing implementation, CRT_fp8.c, which attempts to redirect the
> call back to the (*_imp__fpreset)() entry point in MSVCRT.DLL.
>
> Am I over-thinking this?  Or is this as fragile as it appears?  Was
> Danny off his game, when he wrote this stuff?  I guess it can't be too
> serious a problem, since no issues have been reported in the 15 years
> or so since Danny wrote it, but I can see the following possibilities:
>
> 1) User creates his own DLL, into which CRT_fp10.o is linked, and its
>    _fpreset() symbol is re-exported; that now provides its own copy of
>    (*_imp__fpreset)(), which neutralizes Danny's stratagem for calling
>    the MSVCRT.DLL implementation.
>
> 2) User creates his own DLL, within which _fpreset() is called; user
>    then links this DLL to his main program, which he also links with
>    CRT_fp8.o; calls to _fpreset() in his DLL will still be resolved
>    to whichever of CRT_fp10.o or CRT_fp8.o was linked into the DLL
>    itself, ignoring the intent of linking the main program with
>    CRT_fp8.o
>
> Given that _fpreset() is strictly a Microsoft concept, conforming to no
> known standard, I'd prefer to do away with this ambiguity, and leave it
> to MSVCRT.DLL to resolve all references -- users who value standards,
> and portability, should be using ISO-C99's fesetenv() function anyway.
> Consequently, I've extensively revised Danny's implementation; would
> anyone care to review the attached patch, before I commit it?
>
> Of course, if the modified fesetenv() function continues to be linked
> statically, from libmingwex.a, the potential for (non-deterministic)
> behavioural ambiguity remains, spanning user created DLLs; that could
> be mitigated by furnishing libmingwex-0.dll as an alternative to a
> statically linked libmingwex.a, so that only a single fesetenv() need
> exist within the process address space.
>
> One final related issue: Danny's implementations of both CRT_fp10.c
> and CRT_fp8.c defined fpreset(), (without leading underscore), as an
> alias for each of his _fpreset() replacement implementations.  Given
> the complete lack of any defining standard, that seems kind of pointless
> to me.  Right now I've marked this as deprecated, but have retained a
> __LIBIMPL__ stub for it, (reimplemented in terms of fesetenv()), but
> it's messy, and I'd just as soon see it disappear altogether.
>
> Any thoughts?

Maybe put out a test and call for testers.  Eli at least would probably
give it a try.  Looking at the MSDN recent documentation I would guess
that even MS is going to get rid of it so I would at least test with it
gone.

<quote>
This function is deprecated when compiling with /clr (Common Language
Runtime Compilation) or /clr:pure because the common language runtime
only supports the default floating-point precision.
</quote>

--
Earnie

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-dvlpr mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mingw-dvlpr
Reply | Threaded
Open this post in threaded view
|

Re: Possibly ambiguous redefinition of _fpreset()?

Keith Marshall-3
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 11/02/17 21:57, Earnie wrote:
> Maybe put out a test and call for testers.  Eli at least would probably
> give it a try.

Good idea.  I'd like to get this integrated sooner, rather than later,
and then get a 5.0 release out the door.  It would be good to get some
beta testing in, before final release.

> Looking at the MSDN recent documentation I would guess that
> even MS is going to get rid of it so I would at least test with
> it [_fpreset()] gone.

Except that it wouldn't be gone; it would simply always resolve to
the implementation provided in MSVCRT.DLL.  In any case, fesetenv()
depends on it, currently, when selecting the FE_PC53_ENV option.

> <quote>
> This function is deprecated when compiling with /clr (Common Language
> Runtime Compilation) or /clr:pure because the common language runtime
> only supports the default floating-point precision.
> </quote>

That's incompatible with us continuing to support GCC's extended
precision (10-byte) long doubles; Microsoft's default is to support
only 8-byte format for both double and (indistinguishably) their
(non-)implementation of long double.  Besides, unless I'm missing
something, I don't think we support, (or even have any interest in
supporting), CLR; (isn't it primarily .Net technology?)

- --
Regards,
Keith.

Public key available from keys.gnupg.net
Key fingerprint: C19E C018 1547 DE50 E1D4 8F53 C0AD 36C6 347E 5A3F
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.20 (GNU/Linux)

iQIcBAEBAgAGBQJYn5UtAAoJEMCtNsY0flo/WCwP/1Yz5YCq7oWtE9eeRJbY4OWm
7UOQC0PX5sikgDGeOoeygTGUM7YGXWIDz2MHR3iS0iHQl2Z6uZQb5JZRppUuuYUD
oMFJcWW92Txxdl/2r/5r1IXfSDsZ8BiyFbXySN3H7f/5wHJtNr4rLLhOlghI4AY+
hYUTmhtIeje5LbBusKqaTeMTRp5LO5nsOtrHINzqZZqNGGs4ghVc/+UDKWUsZL48
jlDhi+agMunag4zqrpuJoUxX30duqHt/CWXX91pr2c8LnwCFLfzAy1kUByEm572c
dx2aMTuoou5ocEeN+qVUI93h8Ca4t3iZHF22lYF3MnTnbglxyrOqBaEsRu8Wahs5
lNf/p4cHDV+s1hNrGgEYXqhzSb6uG48/wNJCAJhjrzLG+7dNwIBBJjH7Z1jtdthu
CMVVE2hvHUtMbwskjU1Mb5TDdqRO84vUqBmjuSiofUc1Nk2BkcWHqApVxaj0aaO+
RvGaxRwz6U6Qw78FvoLteXA1PAX/Pqoqg/8k+ZkkgNU8Oxc8se/oCUc+0xD5BF+R
p7Ad1v+Vu95gn4YZyAnRetVUyd4rex6Q7BwSEFWGUF28iqnxfru95D5PEJQfjvtK
0qj8n0KPEw1PIMDxU3Q4YcBPPYocSwgwB63UccjDyOmQMsR1qdC9TQvohc9QPu0+
sFK0akA4y5wdUaEnSV6y
=0jfM
-----END PGP SIGNATURE-----

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
MinGW-dvlpr mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/mingw-dvlpr