crt: test: Add t_noatexit_dll test which verifies that DLL which is not using atexit does not have atexit statically linked Signed-off-by: LIU Hao <lh_mouse@126.com>
diff --git a/mingw-w64-crt/testcases/Makefile.am b/mingw-w64-crt/testcases/Makefile.am index 88ec065..b4cb67e 100644 --- a/mingw-w64-crt/testcases/Makefile.am +++ b/mingw-w64-crt/testcases/Makefile.am
@@ -38,6 +38,11 @@ $(LINK) -shared -o $@ $^ t_nontls_dll.exe: libnontls.dll +# Used by t_noatexit_dll +libnoatexit.dll: libnoatexit.o + $(LINK) -shared -o $@ $^ +t_noatexit_dll.exe: libnoatexit.dll + # Used by t_global_ctors libglbctors.dll: libglbctors.o $(LINK) -shared -static -o $@ $^ @TARGET_LIBGCC_FILE_NAME@ @@ -128,6 +133,7 @@ t_mbrlen \ t_mbrtowc \ t_mbsrtowcs \ + t_noatexit_dll \ t_nontls_dll \ t_nontls_exe \ t_tls_dll \
diff --git a/mingw-w64-crt/testcases/libnoatexit.c b/mingw-w64-crt/testcases/libnoatexit.c new file mode 100644 index 0000000..322d955 --- /dev/null +++ b/mingw-w64-crt/testcases/libnoatexit.c
@@ -0,0 +1,9 @@ +/* This is simple DLL library which does not use atexit callback */ + +/* Tentative symbol __mingw_dll_atexit_table_func_ptr is mingw-w64 internal + * symbol only for DLL libraries. It is non-NULL if the DLL library is using atexit. + */ +int (__cdecl *const __mingw_dll_atexit_table_func_ptr)(int) __attribute__((common)); /* tentative */ + +__attribute__((dllexport)) +int is_atexit_included(void) { return !!__mingw_dll_atexit_table_func_ptr; }
diff --git a/mingw-w64-crt/testcases/t_noatexit_dll.c b/mingw-w64-crt/testcases/t_noatexit_dll.c new file mode 100644 index 0000000..e62ad5b --- /dev/null +++ b/mingw-w64-crt/testcases/t_noatexit_dll.c
@@ -0,0 +1,48 @@ +#include <stdio.h> + +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include <windows.h> + +/* mingw-w64 headers */ +#include "libtest.h" + +/* This test verifies that DLL library libnoatexit.dll which is not using atexit callbacks, does not have unwanted/unexpected atexit implementation. */ +int main(void) +{ + mingw_test_init(); + + /* gcc's crtbegin.o (libgcc/config/i386/cygming-crtbegin.c) injects atexit call into every output binary. + * So skip this test for all gcc builds (and exclude clang builds for which this test is passing). */ +#if defined(__GNUC__) && !defined(__clang__) + printf("test skipped for gcc builds\n"); + return 77; +#endif + + HMODULE lib = LoadLibraryA("libnoatexit.dll"); + if (!lib) { + DWORD error = GetLastError(); + printf("test failed\n"); + printf("Cannot load DLL library libnoatexit.dll: %lu\n", error); + return 1; + } + + int (*is_atexit_included)(void) = (int(*)(void))(void(*)(void))GetProcAddress(lib, "is_atexit_included"); + if (!is_atexit_included) { + DWORD error = GetLastError(); + printf("test failed\n"); + printf("Cannot resolve is_atexit_included symbol from DLL library libnoatexit.dll: %lu\n", error); + return 1; + } + + if (is_atexit_included()) { + printf("test failed\n"); + printf("DLL library libnoatexit.dll contains static linked mingw-w64 atexit implementation\n"); + return 1; + } else { + printf("test passed\n"); + printf("DLL library libnoatexit.dll does not contain static linked mingw-w64 atexit implementation\n"); + return 0; + } +}