--- mingw-w64-crt/include/msvcrt_or_emu_glue.h | 112 +++++++++++++++++++++ mingw-w64-headers/crt/_mingw_mac.h | 15 +-- 2 files changed, 121 insertions(+), 6 deletions(-) create mode 100644 mingw-w64-crt/include/msvcrt_or_emu_glue.h
diff --git a/mingw-w64-crt/include/msvcrt_or_emu_glue.h b/mingw-w64-crt/include/msvcrt_or_emu_glue.h new file mode 100644 index 000000000000..ac5834b577b0 --- /dev/null +++ b/mingw-w64-crt/include/msvcrt_or_emu_glue.h @@ -0,0 +1,112 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <_mingw_mac.h> + +/* + * Example usage of this include file: + * + * #define RETT int + * #define FUNC func1 + * #define ARGS int arg1, int arg2 + * #define CALL arg1, arg2 + * #include "msvcrt_or_emu_glue.h" + * + * This example defines function named "func1" with signature: + * int __cdecl func1(int arg1, int arg2) { ... } + * + * This function "func1" would either call emulation function named "emu_func1" + * which always has to be declarated (it should be defined as static in the + * same source file) or would call function named "func1" from "msvcrt.dll" + * library if exists. +*/ + +#if !defined(RETT) || !defined(FUNC) || !defined(ARGS) || !defined(CALL) +#error "Missing definitions for msvcrt_or_emu_glue.h" +#endif + +#if defined(FORCEEMU) || !defined(__LIBMSVCRT_OS__) + +/* + * If not compiling for os-system version of msvcrt.dll or FORCEEMU was + * specified then always use emulated version. + */ + +#ifdef NORETURN +__MINGW_ATTRIB_NORETURN +#endif +RETT __attribute__((alias(__MINGW64_STRINGIFY(__MINGW64_PASTE(emu_,FUNC))))) __cdecl FUNC(ARGS); +#ifdef NORETURN +__MINGW_ATTRIB_NORETURN +#endif +RETT (__cdecl *__MINGW_IMP_SYMBOL(FUNC))(ARGS) = FUNC; + +#else + +/* + * If compiling for os-system version of msvcrt.dll and FORCEEMU was not + * specified then try to use function from msvcrt.dll and fallback to + * emulated version only if function does not exist in msvcrt.dll. + */ + +#include <windows.h> +#include <msvcrt.h> + +#ifdef NORETURN +__MINGW_ATTRIB_NORETURN +#endif +static RETT __cdecl __MINGW64_PASTE(init_,FUNC)(ARGS); + +#ifdef NORETURN +__MINGW_ATTRIB_NORETURN +#endif +RETT (__cdecl *volatile __MINGW_IMP_SYMBOL(FUNC))(ARGS) = __MINGW64_PASTE(init_,FUNC); + +#ifdef NORETURN +__MINGW_ATTRIB_NORETURN +#endif +static RETT __cdecl __MINGW64_PASTE(init_,FUNC)(ARGS) +{ + HMODULE msvcrt = __mingw_get_msvcrt_handle(); +#ifdef NORETURN + __MINGW_ATTRIB_NORETURN +#endif + RETT (__cdecl *func)(ARGS) = NULL; + + if (msvcrt) + func = (typeof(func))(void (__cdecl *)(void))GetProcAddress(msvcrt, __MINGW64_STRINGIFY(FUNC)); + + if (!func) + func = __MINGW64_PASTE(emu_,FUNC); + + (void)InterlockedExchangePointer((PVOID volatile *)&__MINGW_IMP_SYMBOL(FUNC), func); + +#ifndef NORETURN + return +#endif + func(CALL); +} + +#ifdef NORETURN +__MINGW_ATTRIB_NORETURN +#endif +RETT __cdecl FUNC(ARGS) +{ +#ifndef NORETURN + return +#endif + __MINGW_IMP_SYMBOL(FUNC)(CALL); +} + +#endif + +/* Now undefine the definitions, so the file can be included more times. */ +#undef FORCEEMU +#undef NORETURN +#undef RETT +#undef FUNC +#undef ARGS +#undef CALL diff --git a/mingw-w64-headers/crt/_mingw_mac.h b/mingw-w64-headers/crt/_mingw_mac.h index 3fe61328edfb..7ceabe7474f8 100644 --- a/mingw-w64-headers/crt/_mingw_mac.h +++ b/mingw-w64-headers/crt/_mingw_mac.h @@ -7,6 +7,9 @@ #ifndef _INC_CRTDEFS_MACRO #define _INC_CRTDEFS_MACRO +#define __PASTE(x, y) x ## y +#define __MINGW64_PASTE(x, y) __PASTE(x, y) + #define __STRINGIFY(x) #x #define __MINGW64_STRINGIFY(x) \ __STRINGIFY(x) @@ -123,14 +126,14 @@ #endif /* ifndef _X86_ */ #if __MINGW_USE_UNDERSCORE_PREFIX == 0 -# define __MINGW_IMP_SYMBOL(sym) __imp_##sym -# define __MINGW_IMP_LSYMBOL(sym) __imp_##sym +# define __MINGW_IMP_SYMBOL(sym) __MINGW64_PASTE(__imp_,sym) +# define __MINGW_IMP_LSYMBOL(sym) __MINGW64_PASTE(__imp_,sym) # define __MINGW_USYMBOL(sym) sym -# define __MINGW_LSYMBOL(sym) _##sym +# define __MINGW_LSYMBOL(sym) __MINGW64_PASTE(_,sym) #else /* ! if __MINGW_USE_UNDERSCORE_PREFIX == 0 */ -# define __MINGW_IMP_SYMBOL(sym) _imp__##sym -# define __MINGW_IMP_LSYMBOL(sym) __imp__##sym -# define __MINGW_USYMBOL(sym) _##sym +# define __MINGW_IMP_SYMBOL(sym) __MINGW64_PASTE(_imp__,sym) +# define __MINGW_IMP_LSYMBOL(sym) __MINGW64_PASTE(__imp__,sym) +# define __MINGW_USYMBOL(sym) __MINGW64_PASTE(_,sym) # define __MINGW_LSYMBOL(sym) sym #endif /* if __MINGW_USE_UNDERSCORE_PREFIX == 0 */ -- 2.20.1 _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public