This is necessary to accommodate ARM64EC, under which CONTEXT refers to the
X86_64 context structure but the regular ARM64 context structure is still
exposed as ARM64_NT_CONTEXT.
Based on patch by Billy Laws.
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
This structure is the same across every architecture that uses it, so
avoid needlessly duplicating its definition.
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
They were accidentally removed in commit e0b9e84fd8f9 ("crt: Fix
__getmainargs() and __wgetmainargs() ABI for msvcrt40.dll and msvcrt.dll")
when these functions were implemented as wrappers around the real
functions.
_imp_ symbols for __getmainargs() and __wgetmainargs() functions are needed
for applications which provides own declaration of these functions with
__declspec(dllimport).
Fixes linking error "undefined reference to `_imp____wgetmainargs'" as was
reported in bug report for mpeg123 application:
https://github.com/mingw-w64/mingw-w64/issues/73
ARM64EC defines x86_64 identification macros, but its actual intrinsics are aarch64-based. Since this
differs from what x86_64 code expects, MSVC additionally provides softintrin.h (and softintrin.lib),
which act as wrappers to offer x86_64 variants of the intrinsics.
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
This change is based on Wine's winnt.h implementation. Using a register variable for NtCurrentTeb
allows the compiler to optimize the access more effectively.
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
These macros depends on ANSI / UNICODE build type and therefore for example
_fgettc_nolock has different definition based on _UNICODE macro.
Currently there are duplicate and different definitions:
#define _fgettc_nolock _fgetwc_nolock
#define _fgettc_nolock _fgetc_nolock
Which are causing compile warnings:
include/tchar.h:784: warning: "_fgettc_nolock" redefined
#define _fgettc_nolock _fgetc_nolock
include/tchar.h:772: note: this is the location of the previous definition
#define _fgettc_nolock _fgetwc_nolock
This change fixes commit 2f9a13461d265592b33cc9ff0e425ecb0df9499c
("include/crt: Ensure declarations of `_*_nolock` match MSVCRT version").
Signed-off-by: Martin Storsjö <martin@martin.st>
In commit 797b4a6b5191 ("headers: Expose the wchar ctype _l functions for
msvcrt.dll for Vista") was added following pattern:
#if __MSVCRT_VERSION__ >= 0x800 || (__MSVCRT_VERSION__ == 0x700 && _WIN32_WINNT >= 0x0600)
/* These are available since msvcr80.dll, and in msvcrt.dll since Vista. */
_CRTIMP int __cdecl _iswalpha_l(wint_t _C,_locale_t _Locale);
...
#endif
This preprocessor condition is not fully correct as it matches also the
case when compiling for msvcr70.dll library on Windows Vista+ target
systems. msvcr70.dll library does not provide these ctype _l functions on
Windows Vista or new systems. So it should not be enabled.
The problem is that currently __MSVCRT_VERSION__ == 0x700 condition means
compiling for msvcrt.dll OR for msvcr70.dll. And currently it is not
possible to distinguish between these two targets.
Fix this problem by changing the __MSVCRT_VERSION__ value when compiling
for msvcrt.dll and set __MSVCRT_VERSION__ to 0x600.
This is logical step because msvcrt.dll provides ABI / DLL library name of
the Visual C++ 6.0 version and msvcr70.dll provides ABI / DLL library name
of the Visual Studio 2002 (AKA VC++ 7.0).
msvcrt.dll preinstalled as part of the Windows system provides more
functions than the original Visual C++ 6.0, but still it is compatible with
the original version. So setting __MSVCRT_VERSION__ to 0x600 for msvcrt.dll
build is relatively sane option.
I was considering to use 0x6FF value for this case, but this would make it
more complicated for applications if they need to know if they are being
compiled for msvcrt.dll library ABI. They would need to check if the macro
__MSVCRT_VERSION__ is set to 0x600 (targetting the original VC++ msvcrt.dll
library) or to value 0x6FFF (targettting the system msvcrt.dll library).
This looks to be additional complication as it would be needed to track all
possible values for __MSVCRT_VERSION__. So using just one value 0x600 for
both cases should be enough because for system version specific version is
always needed to check also _WIN32_WINNT value.
So __MSVCRT_VERSION__=0x600 would mean compiling for msvcrt.dll ABI
and __MSVCRT_VERSION__=0x700 would mean compiling for msvcr70.dll ABI.
This change fixes guards around wchar ctype _l functions and also the
default value of __MSVCRT_VERSION__ when targeting msvcrt-os filled by the
mingw-w64-headers/configure.ac.
Signed-off-by: Martin Storsjö <martin@martin.st>
In Visual Studio when including crtdbg.h file with both _DEBUG and
_CRTDBG_MAP_ALLOC macros set, all standard memory allocation functions are
redefined and forwarded to their *_dbg siblings. This allows to track
memory allocation in program compiled and linked with debug version of CRT
DLL library.
Add same support also into mingw-w64. This allows to use memory leak
functionality provided by msvcrtd.dll when compiling with gcc's
-mcrtdll=msvcrtd and -D_DEBUG and -D_CRTDBG_MAP_ALLOC switches.
Note that those redefined functions needs macro guards in other header
files to prevent expadning redefined macros when declaring non-debug
functions. For example when declaring void *__cdecl malloc(size_t _Size);
in malloc.h header file, it needs to be ensured that malloc macro from
crtdbg.h #define malloc(s) _malloc_dbg(s,_NORMAL_BLOCK,__FILE__,__LINE__)
does not expad for standard malloc declaration. Same guard technique via
pragma push_macro, undef and pragma pop_macro is used by Visual Studio.
Signed-off-by: Martin Storsjö <martin@martin.st>
msvc compiler for msvcrt and ucrt debug builds declare debug CRT function
when _DEBUG macro is defined. All those functions and macros are defined in
crtdbg.h include file. Do same in mingw-w64 headers.
This allows applications to be compiled with gcc's -mcrtdll=msvcrtd and
-D_DEBUG switches and to use debug functions.
Signed-off-by: Martin Storsjö <martin@martin.st>
ARM64EC targets are identified by the __arm64ec__, _M_ARM64EC, and _ARM64EC_ macros.
ARM64EC code functions as an __x86_64__ compiler while utilizing the AArch64 instruction set.
Consequently, it defines the __x86_64__, _M_AMD64, and _AMD64_ macros, but not
__aarch64__, _M_ARM64, or _ARM64_.
Signed-off-by: Jacek Caban <jacek@codeweavers.com>
In mingw-w64-headers/configure.ac is missing case for the msvcr40d. It is
missing because all CRT debug libraries in all versions except for VC++4.0,
have just appended letter "d" after the release name.
VC++ 4.0 CRT debug library is exception, the release library is called
msvcrt40 and debug library is called msvcr40d (without T in the middle).
So the current wildcard for msvcrt40* does not catch it. Fix it.
Signed-off-by: Martin Storsjö <martin@martin.st>
In mingw-w64-headers/configure.ac is missing case for the crtdll. Usage of
crtdll as CRT library is treated with zero value in __MSVCRT_VERSION__ and
setting additional __CRTDLL__ macro. Setting of __CRTDLL__ is needed also
to mimic compatibility with gcc, which can be configure to target
crtdll.dll by default in which case it predefines __CRTDLL__ macro.
Signed-off-by: Martin Storsjö <martin@martin.st>
Use _initterm_e() for executing functions in __xi_a[] ... __xi_z[] array.
This function properly stops execution on error and returns error value.
Same logic is doing Visual C++ startup code.
This fixes error handling of function callbacks defined in that array.
Signed-off-by: Martin Storsjö <martin@martin.st>
Function _initterm_e() is available since msvcr80.dll. Add emulation of
this function into all pre-msvcr80 import libraries for compatibility.
Signed-off-by: Martin Storsjö <martin@martin.st>
Function _(w)setargv() provided by the application itself (not by the CRT
DLL runtime library) can fail, which is indicated by the return value.
Check for this failure and call _amsg_exit(_RT_SPACEARG) on error. Same
behavior has Visual C++ startup code.
Signed-off-by: Martin Storsjö <martin@martin.st>
Functions __getmainargs() and __wgetmainargs() in system msvcrt.dll library
since Windows XP and in Visual C++ libraries since msvcr70.dll return
negative value on error and expect that caller handle it and terminate
process. Visual C++ 2002+ startup code calls _amsg_exit(_RT_SPACEARG) on
failure. Do same in mingw-w64 startup code.
Note that mingw-w64 contains compatibility layer around __getmainargs() and
__wgetmainargs() functions for msvcrt.dll and older VC++ DLL libraries in
mingw-w64 import libraries to ensure that these functions returns 0 on
success. This allows to have uniform mingw-w64 crtexe.c startup code, which
can always expects that __getmainargs() and __wgetmainargs() returns the
correct value.
Variable argret is used only in the pre_cpp_init() function, so declare it
on the function stack instead of having it static for the whole file.
With this change, compiled applications linked with msvcrt.dll or new
library correctly reports runtime failure on allocations errors from
__getmainargs() and __wgetmainargs() calls.
Signed-off-by: Martin Storsjö <martin@martin.st>
Visual C++ CRT DLL libraries older than VC70 / msvcr70.dll have different
ABI of __getmainargs() and __wgetmainargs() functions. Their return value
is void, instead of int. This includes VC++ libs crtdll.dll, msvcrt10.dll,
msvcrt20.dll, msvcrt40.dll, msvcr40d.dll, msvcrt.dll and msvcrtd.dll.
Same applies for OS system msvcrt.dll library for older systems than
Windows XP.
System version of msvcrt.dll library since Windows XP has same ABI of
__getmainargs() and __wgetmainargs() functions as Visal C++ msvcr70.dll
library.
MinGW-w64 already provides declaration of __getmainargs() and
__wgetmainargs() with int return value. So it is expected that these
functions in MinGW-w64 perspective returns int and let caller to handle
errors.
Import libraries for crtdll.dll, msvcrt10.dll and msvcrt20.dll have already
wrappers around __getmainargs() and __wgetmainargs() which handle this kind
of ABI incompatibility.
Add a new wrappers around __getmainargs() and __wgetmainargs() also for
msvcrt40.dll, msvcr40d.dll and msvcrtd.dll import libraries to correctly
return integer value 0.
For msvcrt.dll library is situation quite complicated as its ABI is not
stable and was changed in Windows XP version. But the problem is only with
i386 version as all AMD64 and ARM systems were released after Windows XP.
As int return value on i386 is stored in the eax register we can call this
function from C even with wrong return value in declaration and ignoring it
return value. This function does not touch argc/argv/envp arguments on
error, so we can use this fact to detect failure independently of return
value ABI. With this trick is it possible to achieve i386 implementation of
MinGW-w64 wrappers around __getmainargs() and __wgetmainargs() which would
work with both Visual C++ ABI and also with Window XP ABI.
Signed-off-by: Martin Storsjö <martin@martin.st>
PE format allows to have variable length of Data Directories in PE Optional
Header. The exact number of Data Directories is stored in NumberOfRvaAndSizes
field. Size of the optional header depends on the number of Data Directories.
Constants IMAGE_SIZEOF_NT_OPTIONAL32_HEADER and IMAGE_SIZEOF_NT_OPTIONAL64_HEADER
are for PE images with all 16 Data Directories. And so cannot be used for
checking validity of SizeOfOptionalHeader.
Older PE linkers were generating PE binaries with less number of Data
Directories than 16 if trailing entries were empty. And gendef cannot
recognize such PE binaries.
Relax check for PE SizeOfOptionalHeader field. Allow any number of Data
Directories in PE Optional Header, including zero.
At the same time add checks for NumberOfRvaAndSizes member before
dereferencing DataDirectory[] array, which ensures that the entry is present.
Signed-off-by: Martin Storsjö <martin@martin.st>
According to docs, the order is unspecified; running them in
reverse order would be more logical.
When libstdc++ is built, it can either provide its own implementation
of __cxa_thread_atexit or use one from the host environment.
When libstdc++ is cross compiled, the configure script doesn't do any
linking tests and doesn't detect the mingw-w64-crt implementation of
__cxa_thread_atexit, and always provides its own implementation
instead.
When the libstdc++/libsupc++ implementation of __cxa_thread_atexit is
used in conjunction with emulated TLS, both emutls and libsupc++
register destructors to be executed via pthread_key_create; one for
freeing the per-thread memory allocated for the TLS objects, and
one for executing the destructors. They are registered in a sequential
order; first emutls registers the destructor for freeing the memory,
followed by libsupc++ registers a destructor for running the TLS
object destructors.
Therefore, running the pthread key destructors in reverse order makes
sure that the TLS object destructors are called (via libsupc++) before
their memory is deallocated (via emutls).
This pattern also matches how destructors normally are executed - in
opposite order compared with how they were constructors.
Signed-off-by: Martin Storsjö <martin@martin.st>
This initialization isn't needed, static variables are guaranteed
to be zero initialized anyway. This syntax of using an empty brace
list is only supported since C23 (even though compilers may accept
it in older language modes too).
This removes one unnecessary change from
997473bddf5b6b256599f7031064eda9a916c9d6.
Signed-off-by: Martin Storsjö <martin@martin.st>
Variable startinfo is used only by __(w)getmainargs() call passed by the
pointer in pre_cpp_init() function. The __(w)getmainargs() function does
not use or store the pointer value, so the variable does not have to be
static. Declare this variable just on the pre_cpp_init() function stack.
The _startupinfo struct is an input-only struct with one member
(int newmode).
Signed-off-by: Martin Storsjö <martin@martin.st>
i386 DLL builds have same issue as EXE builds, entry point (DllMain or
DllEntryPoint) can use SSE and therefore stack should be aligned to
16-bytes. Use attribute force_align_arg_pointer for __DllMainCRTStartup,
like it is already for __tmainCRTStartup. Also mark it as static.
This code was copied from crtexe.c __tmainCRTStartup() function.
Signed-off-by: Martin Storsjö <martin@martin.st>
For EXE builds __mingw_init_ehandler() function is called after the
_pei386_runtime_relocator() from the __tmainCRTStartup() (and not from the
WinMainCRTStartup() function).
Do same for DLL builds and call __mingw_init_ehandler() from
__DllMainCRTStartup() instead of DllMainCRTStartup(), for consistency.
Note that __mingw_init_ehandler is only called in x86_64 builds
without SEH, i.e. in practice x86_64 builds configured to use
DWARF rather than SEH, which is quite rare these days.
Signed-off-by: Martin Storsjö <martin@martin.st>