On Tue, 20 Oct 2015, Martin Storsjo wrote:
> Since MSVC 2015/Windows 10, the C runtime has now been split into two
> parts, ucrtbase, which is the generic C runtime which is now considered
> a system component, and vcruntimeX which is specific to the compiler
> version.
>
> This DLL is built using only a small subset of the msvcrt source
> files. In particular, the DLL should not use most of the global
> CRT state as a normal msvcrt carries - the only TLS state handled
> is for exceptions.
>
> The functions in main.c are simplified versions of the corresponding
> ones from msvcrt. Additionally, two stub functions (relating to telemetry)
> are added; they are required for a plain empty exe built with MSVC 2015
> with dynamic C runtime to start up with the builtin vcruntime140.dll.
>
> Some functions that are available in the full msvcrt, that vcruntime140.dll
> should export, are not included since they haven't been split off to be
> buildable without the full internals of msvcrt yet. Those functions are:
> _CxxThrowException
> __AdjustPointer
> __RTCastToVoid
> __RTDynamicCast
> __RTtypeid
> _chkesp
> _get_unexpected
>
> Signed-off-by: Martin Storsjo <martin(a)martin.st>
> ---
> Changed since last version: Moved main-vcruntime.c to the vcruntime140
> directory; skipped the separate memory.c and included all of it in the
> vcruntime main.c instead. Removed a leftover commented out statement.
>
> In this build configuration, some functions use simpler error handling
> - instead of calling _amsg_exit, it calls ExitProcess directly.
> (_amsg_exit checks the error mode, which is state that lives within
> ucrtbase.dll; vcruntime140.dll shouldn't have a separate copy of that
> state, and there's no function in ucrtbase.dll that would allow quering it.)
> ---
> configure.ac | 1 +
> dlls/msvcrt/except.c | 4 +
> dlls/msvcrt/except_i386.c | 4 +
> dlls/vcruntime140/Makefile.in | 12 ++
> dlls/vcruntime140/main.c | 224 ++++++++++++++++++++++++++++++++++++
> dlls/vcruntime140/vcruntime140.spec | 87 ++++++++++++++
> 6 files changed, 332 insertions(+)
> create mode 100644 dlls/vcruntime140/Makefile.in
> create mode 100644 dlls/vcruntime140/main.c
> create mode 100644 dlls/vcruntime140/vcruntime140.spec
Piotr asked whether this would make sense as a DLL that only forwards
calls down to ucrtbase, instead of a standalone DLL that duplicates the
implementation.
For i386, this DLL has got 81 exported functions, and all of those except
a few do exist in ucrtbase.dll. The ones that are unique to
vcruntime140.dll are the following:
__C_specific_handler_noexcept
__std_terminate
__telemetry_main_invoke_trigger
__telemetry_main_return_trigger
__uncaught_exceptions
__vcrt_GetModuleFileNameW
__vcrt_GetModuleHandleW
__vcrt_InitializeCriticalSectionEx
__vcrt_LoadLibraryExW
Out of these, the telemetry ones actually are called implicitly even in a
plain hello world executable built with MSVC 2015 (but having them as
empty stubs seems to work fine so far), the other ones I haven't had
reason to look into yet.
The real vcruntime140.dll actually also do some calls to ucrtbase.dll
(linked via the api-ms-win-crt-* stub dlls), but not all the real
functions - it only links to the following ones:
terminate
abort
strcpy_s
malloc
_free_base
free
_malloc_base
_calloc_base
__stdio_common_vsprintf_s
atol
(Additionally it links to a few symbols from kernel32.dll and one from
advapi32.dll.)
Given this, I still think this DLL makes sense as a standalone DLL instead
of just a stub forwarding to ucrtbase, since that's what the original one
does as well. At worst some of the functions may need to have subtly
different behaviour in different versions (which I guess is the main
reason for the DLL existing in the first place).
// Martin