blob: 42f2e5f231a43794022c58b67dd67c4fd0064a72 [file] [log] [blame]
Pali Rohárbe232592022-01-11 13:56:21 +01001/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6#include <windows.h>
Pali Rohárbe232592022-01-11 13:56:21 +01007#include <stdarg.h>
8#include <stdio.h>
9#include <string.h>
10
11/* mingw-w64 always provides _vscprintf() implementation, so use it */
12static int __cdecl emu_scprintf(const char * __restrict__ format, ...)
13{
14 va_list arglist;
15 int ret;
16
17 va_start(arglist, format);
18 ret = _vscprintf(format, arglist);
19 va_end(arglist);
20 return ret;
21}
22
Pali Rohára40df962022-03-06 02:32:15 +010023#ifndef __LIBMSVCRT_OS__
24
Pali Rohárc7f7d302024-04-07 18:24:20 +020025int __attribute__ ((alias ("emu_scprintf"))) __cdecl _scprintf (const char * __restrict__, ...);
26int (__cdecl *__MINGW_IMP_SYMBOL(_scprintf))(const char * __restrict__, ...) = _scprintf;
Pali Rohára40df962022-03-06 02:32:15 +010027
28#else
29
30#include <msvcrt.h>
31
Pali Rohárbe232592022-01-11 13:56:21 +010032static int __cdecl init_scprintf(const char * __restrict__ format, ...);
33
34int (__cdecl *__MINGW_IMP_SYMBOL(_scprintf))(const char * __restrict__, ...) = init_scprintf;
35
36__attribute__((used))
37static void resolve_scprintf(void)
38{
39 HMODULE msvcrt = __mingw_get_msvcrt_handle();
40 int (__cdecl *func)(const char * __restrict__, ...) = NULL;
41
42 if (msvcrt)
43 func = (int (__cdecl *)(const char * __restrict__, ...))GetProcAddress(msvcrt, "_scprintf");
44
45 if (!func)
46 func = emu_scprintf;
47
48 __MINGW_IMP_SYMBOL(_scprintf) = func;
49}
50
51/* gcc does not provide an easy way to call another variadic function with reusing current arguments
52 * this source file is used only on i386, so do this function redirect via inline i386 assembly */
53#define ASM_SYM(sym) __MINGW64_STRINGIFY(__MINGW_USYMBOL(sym))
54asm (
55".def\t" ASM_SYM(init_scprintf) ";\t.scl\t3;\t.type\t32;\t.endef\n"
56ASM_SYM(init_scprintf) ":\n\t"
57 "pushal\n\t"
58 "call\t" ASM_SYM(resolve_scprintf) "\n\t"
59 "popal\n\t"
60 /* fallthrough */
61".globl\t" ASM_SYM(_scprintf) "\n\t"
62".def\t" ASM_SYM(_scprintf) ";\t.scl\t2;\t.type\t32;\t.endef\n"
63ASM_SYM(_scprintf) ":\n\t"
64 "jmp\t*" ASM_SYM(__MINGW_IMP_SYMBOL(_scprintf))
65);
Pali Rohára40df962022-03-06 02:32:15 +010066
67#endif