From 3daf2dc4f18b2fbd62a3aed3276f6a7ab7f058dc Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Fri, 7 Nov 2014 08:33:22 +0000 Subject: [PATCH] * dcrt0.cc (cygwin__cxa_atexit): Fetch correct DSO handle value by searching dll list. Explain why. --- winsup/cygwin/ChangeLog | 5 +++++ winsup/cygwin/dcrt0.cc | 14 ++++++++------ 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 7f001ced5..fa5ca1947 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +2014-11-07 Corinna Vinschen + + * dcrt0.cc (cygwin__cxa_atexit): Fetch correct DSO handle value + by searching dll list. Explain why. + 2014-11-06 Corinna Vinschen * dcrt0.cc (cygwin_atexit): Change preceeding comment to reflect diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 19fb46d2c..738860d0e 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -1239,15 +1239,17 @@ do_exit (int status) calls to __cxa_atexit using the *address* of __dso_handle as DSO handle. So what we do here is this: A call to __cxa_atexit from the application - actually calls cygwin__cxa_atexit. From the dso_handle value we fetch the - ImageBase address, which is then used as the actual DSO handle value in - calls to __cxa_atexit and __cxa_finalize. */ + actually calls cygwin__cxa_atexit. From dso_handle (which is either + &__dso_handle, or __dso_handle == ImageBase or NULL) we fetch the dll + structure of the DLL. Then use dll::handle == ImageBase as the actual DSO + handle value in calls to __cxa_atexit and __cxa_finalize. + Thus, __cxa_atexit becomes entirely independent of the incoming value of + dso_handle, as long as it's *some* pointer into the DSO's address space. */ extern "C" int cygwin__cxa_atexit (void (*fn)(void *), void *obj, void *dso_handle) { - if (dso_handle) - dso_handle = *(void **) dso_handle; - return __cxa_atexit (fn, obj, dso_handle); + dll *d = dso_handle ? dlls.find (dso_handle) : NULL; + return __cxa_atexit (fn, obj, d ? d->handle : NULL); } /* This function is only called for applications built with Cygwin versions