Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2011-02-27 02:30:33 +0300
committerChristopher Faylor <me@cgf.cx>2011-02-27 02:30:33 +0300
commita16b0549d49af27bb6e71e97f2b5b7c219bba0ca (patch)
tree3f7700708456d5485f927753ac93895632f094dd
parente80f6dc8f004a687271c5172ea14d3497ec6c39b (diff)
* autoload.cc: Use LoadDLLfuncEx3 for all winmm functions. Accommodate changes
to LoadDLLprime. (LoadDLLprime): Take an extra argument indicating whether this dll needs special handling on fork. Place this information in the "handle" location. (LoadDLLfuncEx3): Eliminate "func" handling. Pass new no_resolve_on_fork argument to LoadDLLprime. (dll_load): New function. (std_dll_init): Accommodate changes to dll_info::handle. Use dll_load to load DLL in both cases where it is used.
-rw-r--r--winsup/cygwin/ChangeLog13
-rw-r--r--winsup/cygwin/autoload.cc90
2 files changed, 65 insertions, 38 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c2ea0aede..b9350f7c5 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,16 @@
+2011-02-26 Christopher Faylor <me+cygwin@cgf.cx>
+
+ * autoload.cc: Use LoadDLLfuncEx3 for all winmm functions. Accommodate
+ changes to LoadDLLprime.
+ (LoadDLLprime): Take an extra argument indicating whether this dll
+ needs special handling on fork. Place this information in the "handle"
+ location.
+ (LoadDLLfuncEx3): Eliminate "func" handling. Pass new
+ no_resolve_on_fork argument to LoadDLLprime.
+ (dll_load): New function.
+ (std_dll_init): Accommodate changes to dll_info::handle. Use dll_load
+ to load DLL in both cases where it is used.
+
2011-02-26 Corinna Vinschen <corinna@vinschen.de>
* autoload.cc: Make autoloaded ntdll function non-optional. Ditto for
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 2bf2f5ed7..d9732765b 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -60,13 +60,13 @@ bool NO_COPY wsock_started;
/* LoadDLLprime is used to prime the DLL info information, providing an
additional initialization routine to call prior to calling the first
function. */
-#define LoadDLLprime(dllname, init_also) __asm__ (" \n\
+#define LoadDLLprime(dllname, init_also, no_resolve_on_fork) __asm__ (" \n\
.ifndef " #dllname "_primed \n\
.section .data_cygwin_nocopy,\"w\" \n\
.align 4 \n\
."#dllname "_info: \n\
.long _std_dll_init \n\
- .long 0 \n\
+ .long " #no_resolve_on_fork " \n\
.long -1 \n\
.long " #init_also " \n\
.string16 \"" #dllname ".dll\" \n\
@@ -88,8 +88,8 @@ bool NO_COPY wsock_started;
LoadDLLfuncEx3(name, n, dllname, notimp, err, 0)
/* Main DLL setup stuff. */
-#define LoadDLLfuncEx3(name, n, dllname, notimp, err, fn) \
- LoadDLLprime (dllname, dll_func_load) \
+#define LoadDLLfuncEx3(name, n, dllname, notimp, err, no_resolve_on_fork) \
+ LoadDLLprime (dllname, dll_func_load, no_resolve_on_fork) \
__asm__ (" \n\
.section ." #dllname "_autoload_text,\"wx\" \n\
.global _" mangle (name, n) " \n\
@@ -102,9 +102,9 @@ _win32_" mangle (name, n) ": \n\
1:movl (2f),%eax \n\
call *(%eax) \n\
2:.long ." #dllname "_info \n\
- .long (" #n "+" #notimp ") | (((" #err ") & 0xff) <<16) | (((" #fn ") & 0xff) << 24) \n\
- .asciz \"" #name "\" \n\
- .text \n\
+ .long (" #n "+" #notimp ") | (((" #err ") & 0xff) <<16) \n\
+ .asciz \"" #name "\" \n\
+ .text \n\
");
/* DLL loader helper functions used during initialization. */
@@ -204,6 +204,21 @@ union retchain
long long ll;
};
+
+/* This function is a workaround for the problem reported here:
+ http://cygwin.com/ml/cygwin/2011-02/msg00552.html
+ and discussed here:
+ http://cygwin.com/ml/cygwin-developers/2011-02/threads.html#00007
+
+ To wit: winmm.dll calls FreeLibrary in its DllMain and that can result
+ in LoadLibraryExW returning an ERROR_INVALID_ADDRESS. */
+static bool
+dll_load (HANDLE& handle, WCHAR *name)
+{
+ HANDLE h = LoadLibraryExW (name, NULL, (in_forkee && handle) ? DONT_RESOLVE_DLL_REFERENCES : 0);
+ return h ? (handle = h) : 0;
+}
+
#define RETRY_COUNT 10
/* The standard DLL initialization routine. */
@@ -221,21 +236,22 @@ std_dll_init ()
yield ();
}
while (InterlockedIncrement (&dll->here));
- else if (!dll->handle)
+ else if ((uintptr_t) dll->handle <= 1)
{
fenv_t fpuenv;
fegetenv (&fpuenv);
WCHAR dll_path[MAX_PATH];
DWORD err = ERROR_SUCCESS;
+ int i;
/* http://www.microsoft.com/technet/security/advisory/2269637.mspx */
wcpcpy (wcpcpy (dll_path, windows_system_directory), dll->name);
/* MSDN seems to imply that LoadLibrary can fail mysteriously, so,
since there have been reports of this in the mailing list, retry
several times before giving up. */
- for (int i = 1; i <= RETRY_COUNT; i++)
+ for (i = 1; i <= RETRY_COUNT; i++)
{
/* If loading the library succeeds, just leave the loop. */
- if ((dll->handle = LoadLibraryW (dll_path)) != NULL)
+ if (!dll_load (dll->handle, dll_path))
break;
/* Otherwise check error code returned by LoadLibrary. If the
error code is neither NOACCESS nor DLL_INIT_FAILED, break out
@@ -246,15 +262,13 @@ std_dll_init ()
if (i < RETRY_COUNT)
yield ();
}
- if (!dll->handle)
+ if ((uintptr_t) dll->handle <= 1)
{
/* If LoadLibrary with full path returns one of the weird errors
reported on the Cygwin mailing list, retry with only the DLL
- name. Checking the error codes allows to restrict loading
- with just the DLL name to this specific problem. */
- if ((err == ERROR_NOACCESS || err == ERROR_DLL_INIT_FAILED)
- && (dll->handle = LoadLibraryW (dll->name)) != NULL)
- ;
+ name. Only do this when the above retry loop has been exhausted. */
+ if (i > RETRY_COUNT && dll_load (dll->handle, dll->name))
+ /* got it with the fallback */;
else if ((func->decoration & 1))
dll->handle = INVALID_HANDLE_VALUE;
else
@@ -330,7 +344,7 @@ wsock_init ()
return ret.ll;
}
-LoadDLLprime (ws2_32, _wsock_init)
+LoadDLLprime (ws2_32, _wsock_init, 0)
LoadDLLfuncEx2 (DnsQuery_A, 24, dnsapi, 1, 127) // ERROR_PROC_NOT_FOUND
LoadDLLfuncEx (DnsRecordListFree, 8, dnsapi, 1)
@@ -435,27 +449,27 @@ LoadDLLfunc (SetProcessWindowStation, 4, user32)
LoadDLLfunc (SetThreadDesktop, 4, user32)
LoadDLLfunc (ShowWindowAsync, 8, user32)
-LoadDLLfunc (timeBeginPeriod, 4, winmm)
-LoadDLLfunc (timeEndPeriod, 4, winmm)
-LoadDLLfunc (timeGetDevCaps, 8, winmm)
-LoadDLLfunc (timeGetTime, 0, winmm)
-LoadDLLfunc (waveInAddBuffer, 12, winmm)
-LoadDLLfunc (waveInClose, 4, winmm)
-LoadDLLfunc (waveInGetNumDevs, 0, winmm)
-LoadDLLfunc (waveInOpen, 24, winmm)
-LoadDLLfunc (waveInPrepareHeader, 12, winmm)
-LoadDLLfunc (waveInReset, 4, winmm)
-LoadDLLfunc (waveInStart, 4, winmm)
-LoadDLLfunc (waveInUnprepareHeader, 12, winmm)
-LoadDLLfunc (waveOutClose, 4, winmm)
-LoadDLLfunc (waveOutGetNumDevs, 0, winmm)
-LoadDLLfunc (waveOutGetVolume, 8, winmm)
-LoadDLLfunc (waveOutOpen, 24, winmm)
-LoadDLLfunc (waveOutPrepareHeader, 12, winmm)
-LoadDLLfunc (waveOutReset, 4, winmm)
-LoadDLLfunc (waveOutSetVolume, 8, winmm)
-LoadDLLfunc (waveOutUnprepareHeader, 12, winmm)
-LoadDLLfunc (waveOutWrite, 12, winmm)
+LoadDLLfuncEx3 (timeBeginPeriod, 4, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (timeEndPeriod, 4, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (timeGetDevCaps, 8, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (timeGetTime, 0, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveInAddBuffer, 12, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveInClose, 4, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveInGetNumDevs, 0, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveInOpen, 24, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveInPrepareHeader, 12, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveInReset, 4, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveInStart, 4, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveInUnprepareHeader, 12, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveOutClose, 4, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveOutGetNumDevs, 0, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveOutGetVolume, 8, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveOutOpen, 24, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveOutPrepareHeader, 12, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveOutReset, 4, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveOutSetVolume, 8, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveOutUnprepareHeader, 12, winmm, 0, 0, 1)
+LoadDLLfuncEx3 (waveOutWrite, 12, winmm, 0, 0, 1)
LoadDLLfunc (accept, 12, ws2_32)
LoadDLLfunc (bind, 12, ws2_32)