headers: Use asm() to redirect symbols towards extern __mingw vararg functions
This avoids having to rely on inline functions for capturing
the variable arguments into a va_list and passing it to the
other v- prefixed function.
For the inline functions, in C++ we used plain C++ inline, while
we use static inline in C. (We need to use non-static inline in
C++ mode, for C++ module builds, where such stdio functions are
reexported by the C++ module.)
Using non-static inline functions can cause conflicts, if some
object files are built with __USE_MINGW_ANSI_STDIO enabled, and
others with it disabled. In such a case, both object files would
define a global comdat symbol e.g. "wprintf", and the linker would
pick either definition and use for all callers.
By redirecting the symbols with asm(), via __MINGW_ASM_CALL, there's
no conflict.
This also fixes https://github.com/mstorsjo/llvm-mingw/issues/438:
The fact that the inlines are non-static in C++ mode also can
cause other problems. The inline functions redirect towards the
__mingw_*printf functions, which do the formatting, and finally
call __ms_fwprintf to do the outputting. With short import libraries,
the import library redirect from __ms_fwprintf towards the imported
function fwprintf, is handled with a weak alias. But as we already
had a nonstatic function "fwprintf" (the inline function), this gets
linked and used instead of actually importing the "fwprintf" function
from msvcrt.dll.
By not using an inline function for the toplevel redirect, it doesn't
interfere with the import library __ms_fwprintf alias.
This doesn't seem to have been an issue for regular fprintf, as those
inline functions aren't wrapped in extern "C" {}, which causes the
inline function to get mangled differently, avoiding that problem.
Signed-off-by: Martin Storsjö <martin@martin.st>
2 files changed