summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2014-11-06 15:32:21 +0000
committerCorinna Vinschen <corinna@vinschen.de>2014-11-06 15:32:21 +0000
commitdfc361dad46347fea1089fff9ecd4dd3235703d3 (patch)
treeea145a53caebb8ab37f6b61520a1a008012f2af9
parent97e2f27aa1c50d7ecb37314f912f7510d3ede879 (diff)
downloadcygnal-dfc361dad46347fea1089fff9ecd4dd3235703d3.tar.gz
cygnal-dfc361dad46347fea1089fff9ecd4dd3235703d3.tar.bz2
cygnal-dfc361dad46347fea1089fff9ecd4dd3235703d3.zip
* 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).
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/dcrt0.cc12
-rw-r--r--winsup/cygwin/external.cc6
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rw-r--r--winsup/cygwin/include/sys/cygwin.h4
-rw-r--r--winsup/cygwin/lib/atexit.c21
6 files changed, 46 insertions, 11 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 8b1098e5c..7f001ced5 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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.
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 673f87a15..19fb46d2c 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -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))
{
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index edc9d5d29..fce161192 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -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);
}
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 813220e61..e1ac2cee9 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -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
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index 39639b877..7f40475e8 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -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
diff --git a/winsup/cygwin/lib/atexit.c b/winsup/cygwin/lib/atexit.c
index af82d1de7..a2dec6267 100644
--- a/winsup/cygwin/lib/atexit.c
+++ b/winsup/cygwin/lib/atexit.c
@@ -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);
}