Permalink
Browse files

win32: fixed vfprintf not being found for vitals.

Since the Universal CRT was introduced, vfprintf may no longer be
included in the runtime dll, but may be defined as an inline function
that calls __stdio_common_vfprintf instead.

Since the vitals.c code was searching for the vfprintf function, aborting
if not found, it was crashing under windows versions shipping UCRT. We now
search for __stdio_common_vfprintf as a fallback.
  • Loading branch information...
Snaipe committed Jul 29, 2017
1 parent e018311 commit 81461b33e6e7c217fd9d62329dd3ab0e219b1436
Showing with 30 additions and 1 deletion.
  1. +2 −0 CMakeLists.txt
  2. +1 −0 src/config.h.in
  3. +27 −1 src/vitals.c
@@ -132,6 +132,8 @@ endfunction ()

list(APPEND CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE)

check_symbol_exists(__stdio_common_vfprintf stdio.h HAVE___STDIO_COMMON_VFPRINTF)

if (MMK_EXE_FMT_ELF)
check_symbol_exists(_r_debug link.h HAVE__R_DEBUG)
check_symbol_exists(_DYNAMIC link.h HAVE__DYNAMIC)
@@ -21,5 +21,6 @@
#cmakedefine HAVE_MMAP @HAVE_MMAP@
#cmakedefine HAVE_MMAP_MAP_ANONYMOUS @HAVE_MMAP_MAP_ANONYMOUS@
#cmakedefine HAVE_MMAP_MAP_ANON @HAVE_MMAP_MAP_ANON@
#cmakedefine HAVE___STDIO_COMMON_VFPRINTF @HAVE___STDIO_COMMON_VFPRINTF@

#endif /* !CONFIG_H_IN_ */
@@ -141,6 +141,17 @@ mmk_noreturn void mmk_panic(const char *str, ...)
mmk_unreachable();
}

#ifdef HAVE___STDIO_COMMON_VFPRINTF
static int (__cdecl *mmk___stdio_common_vfprintf_)(
unsigned __int64, FILE *, char const *, _locale_t, va_list);

static int win32_vfprintf_fallback(FILE *f, const char *fmt, va_list vl)
{
return mmk___stdio_common_vfprintf_(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS,
f, fmt, NULL, vl);
}
#endif

# define INIT_VITAL_FUNC(Id) do { \
mmk_ ## Id ## _ = (void *) plt_get_real_fn(ctx, #Id); \
if (!mmk_ ## Id ## _) \
@@ -153,11 +164,26 @@ void mmk_init_vital_functions(plt_ctx ctx)
mmk_vfprintf_ = (void *) plt_get_real_fn(ctx, "vfprintf");
mmk_abort_ = (void *) plt_get_real_fn(ctx, "abort");

#ifdef HAVE___STDIO_COMMON_VFPRINTF
/* Windows doesn't always dynlink to msvcstr.dll (when the universal CRT
is used), so we don't have the definition for vfprintf since ucrt
may define it as an inline function that calls
__stdio_common_vfprintf. */
if (!mmk_vfprintf_) {
mmk___stdio_common_vfprintf_ = (void *)
plt_get_real_fn(ctx, "__stdio_common_vfprintf");
if (mmk___stdio_common_vfprintf_)
mmk_vfprintf_ = win32_vfprintf_fallback;
}
#endif

/* Don't use mmk_panic yet, since it depends on both mmk_abort and
mmk_vfprintf. */
if (!mmk_abort_ || !mmk_vfprintf_) {
fprintf(stderr, "mimick: Initialization error: could not find "
"definitions for vital functions 'abort' and/or 'vfprintf'.\n");
"definitions for vital function(s): %s %s\n",
mmk_abort_ ? "" : "'abort'",
mmk_vfprintf_ ? "" : "'vfprintf'");
abort();
}

0 comments on commit 81461b3

Please sign in to comment.