* dcrt0.cc (cygwin_atexit): Change preceeding comment to reflect

API version numbers.
	* external.cc (cygwin_internal): disable setting cxx_malloc on 64 bit.
	Add CW_FIXED_ATEXIT case.
	* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
	* include/sys/cygwin.h (cygwin_getinfo_types): Add CW_FIXED_ATEXIT.
	* lib/atexit.c (atexit): Test running Cygwin version by checking
	return value of cygwin_internal (CW_FIXED_ATEXIT).
This commit is contained in:
Corinna Vinschen 2014-11-06 15:32:21 +00:00
parent 97e2f27aa1
commit dfc361dad4
6 changed files with 46 additions and 11 deletions

View File

@ -1,3 +1,14 @@
2014-11-06 Corinna Vinschen <corinna@vinschen.de>
* dcrt0.cc (cygwin_atexit): Change preceeding comment to reflect
API version numbers.
* external.cc (cygwin_internal): disable setting cxx_malloc on 64 bit.
Add CW_FIXED_ATEXIT case.
* include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump.
* include/sys/cygwin.h (cygwin_getinfo_types): Add CW_FIXED_ATEXIT.
* lib/atexit.c (atexit): Test running Cygwin version by checking
return value of cygwin_internal (CW_FIXED_ATEXIT).
2014-11-05 Corinna Vinschen <corinna@vinschen.de>
* lib/atexit.c (atexit): Check for being linked into the executable.

View File

@ -1251,12 +1251,12 @@ cygwin__cxa_atexit (void (*fn)(void *), void *obj, void *dso_handle)
}
/* This function is only called for applications built with Cygwin versions
up to 1.7.32. Starting with 1.7.33, atexit is a statically linked function
inside of libcygwin.a. The reason is that the old method to fetch the
caller return address is unreliable given GCCs ability to perform tail call
elimination. For the details, see the below comment.
The atexit replacement is defined in libcygwin.a to allow reliable access
to the correct DSO handle. */
up to API 0.279. Starting with API 0.280 (Cygwin 1.7.33/1.8.6-2), atexit
is a statically linked function inside of libcygwin.a. The reason is that
the old method to fetch the caller return address is unreliable given GCCs
ability to perform tail call elimination. For the details, see the below
comment. The atexit replacement is defined in libcygwin.a to allow reliable
access to the correct DSO handle. */
extern "C" int
cygwin_atexit (void (*fn) (void))
{

View File

@ -243,11 +243,13 @@ cygwin_internal (cygwin_getinfo_types t, ...)
break;
case CW_USER_DATA:
#ifndef __x86_64__
/* This is a kludge to work around a version of _cygwin_common_crt0
which overwrote the cxx_malloc field with the local DLL copy.
Hilarity ensues if the DLL is not loaded like while the process
is forking. */
__cygwin_user_data.cxx_malloc = &default_cygwin_cxx_malloc;
#endif
res = (uintptr_t) &__cygwin_user_data;
break;
@ -673,6 +675,10 @@ cygwin_internal (cygwin_getinfo_types t, ...)
}
break;
case CW_FIXED_ATEXIT:
res = 0;
break;
default:
set_errno (ENOSYS);
}

View File

@ -455,12 +455,13 @@ details. */
277: Add setsockopt(SO_PEERCRED).
278: Add quotactl.
279: Export stime.
280: Static atexit in libcygwin.a, CW_FIXED_ATEXIT.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 279
#define CYGWIN_VERSION_API_MINOR 280
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible

View File

@ -150,7 +150,8 @@ typedef enum
CW_GETNSSSEP,
CW_GETPWSID,
CW_GETGRSID,
CW_CYGNAME_FROM_WINNAME
CW_CYGNAME_FROM_WINNAME,
CW_FIXED_ATEXIT
} cygwin_getinfo_types;
#define CW_LOCK_PINFO CW_LOCK_PINFO
@ -208,6 +209,7 @@ typedef enum
#define CW_GETPWSID CW_GETPWSID
#define CW_GETGRSID CW_GETGRSID
#define CW_CYGNAME_FROM_WINNAME CW_CYGNAME_FROM_WINNAME
#define CW_FIXED_ATEXIT CW_FIXED_ATEXIT
/* Token type for CW_SET_EXTERNAL_TOKEN */
enum

View File

@ -9,11 +9,13 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include <stddef.h>
#include <sys/cygwin.h>
#include <windows.h>
/* Statically linked replacement for the former cygwin_atexit. We need
the function here to be able to access the correct __dso_handle of the
caller's DSO. */
int
atexit (void (*fn) (void))
{
@ -21,6 +23,7 @@ atexit (void (*fn) (void))
extern void *__dso_handle;
extern void *__ImageBase;
void *fixed_dso_handle = &__dso_handle;
/* Check for being called from inside the executable. If so, use NULL
as __dso_handle. This allows to link executables with GCC versions
not providing __dso_handle in crtbegin{S}.o. In this case our own
@ -28,7 +31,19 @@ atexit (void (*fn) (void))
__dso_handle always points to &__ImageBase, while the __dso_handle
for executables provided by crtbegin.o usually points to NULL.
That's what we remodel here. */
return __cxa_atexit ((void (*)(void*))fn, NULL,
&__ImageBase == (void **) GetModuleHandleW (NULL)
? NULL : &__dso_handle);
if (&__ImageBase == (void **) GetModuleHandleW (NULL))
fixed_dso_handle = NULL;
/* With recent Cygwin versions starting with API version 0.280 we call
__cxa_atexit (which is actually the cygwin__cxa_atexit wrapper in
dcrt0.cc) with the address of __dso_handle since that's how g++ generates
calls to __cxa_atexit as well. However, when running an application
built with this atexit under an older Cygwin version, the __cxa_atexit
entry point is the one from newlib, which expects the *value* of
__dso_handle. So, check for the Cygwin version we're running under.
Older version prior to 0.280 don't know CW_FIXED_ATEXIT and return -1.
0.280 and later return 0. */
else if (cygwin_internal (CW_FIXED_ATEXIT) != 0)
fixed_dso_handle = __dso_handle;
return __cxa_atexit ((void (*)(void*))fn, NULL, fixed_dso_handle);
}