* 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.
This commit is contained in:
parent
e80f6dc8f0
commit
a16b0549d4
@ -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>
|
2011-02-26 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* autoload.cc: Make autoloaded ntdll function non-optional. Ditto for
|
* autoload.cc: Make autoloaded ntdll function non-optional. Ditto for
|
||||||
|
@ -60,13 +60,13 @@ bool NO_COPY wsock_started;
|
|||||||
/* LoadDLLprime is used to prime the DLL info information, providing an
|
/* LoadDLLprime is used to prime the DLL info information, providing an
|
||||||
additional initialization routine to call prior to calling the first
|
additional initialization routine to call prior to calling the first
|
||||||
function. */
|
function. */
|
||||||
#define LoadDLLprime(dllname, init_also) __asm__ (" \n\
|
#define LoadDLLprime(dllname, init_also, no_resolve_on_fork) __asm__ (" \n\
|
||||||
.ifndef " #dllname "_primed \n\
|
.ifndef " #dllname "_primed \n\
|
||||||
.section .data_cygwin_nocopy,\"w\" \n\
|
.section .data_cygwin_nocopy,\"w\" \n\
|
||||||
.align 4 \n\
|
.align 4 \n\
|
||||||
."#dllname "_info: \n\
|
."#dllname "_info: \n\
|
||||||
.long _std_dll_init \n\
|
.long _std_dll_init \n\
|
||||||
.long 0 \n\
|
.long " #no_resolve_on_fork " \n\
|
||||||
.long -1 \n\
|
.long -1 \n\
|
||||||
.long " #init_also " \n\
|
.long " #init_also " \n\
|
||||||
.string16 \"" #dllname ".dll\" \n\
|
.string16 \"" #dllname ".dll\" \n\
|
||||||
@ -88,8 +88,8 @@ bool NO_COPY wsock_started;
|
|||||||
LoadDLLfuncEx3(name, n, dllname, notimp, err, 0)
|
LoadDLLfuncEx3(name, n, dllname, notimp, err, 0)
|
||||||
|
|
||||||
/* Main DLL setup stuff. */
|
/* Main DLL setup stuff. */
|
||||||
#define LoadDLLfuncEx3(name, n, dllname, notimp, err, fn) \
|
#define LoadDLLfuncEx3(name, n, dllname, notimp, err, no_resolve_on_fork) \
|
||||||
LoadDLLprime (dllname, dll_func_load) \
|
LoadDLLprime (dllname, dll_func_load, no_resolve_on_fork) \
|
||||||
__asm__ (" \n\
|
__asm__ (" \n\
|
||||||
.section ." #dllname "_autoload_text,\"wx\" \n\
|
.section ." #dllname "_autoload_text,\"wx\" \n\
|
||||||
.global _" mangle (name, n) " \n\
|
.global _" mangle (name, n) " \n\
|
||||||
@ -102,9 +102,9 @@ _win32_" mangle (name, n) ": \n\
|
|||||||
1:movl (2f),%eax \n\
|
1:movl (2f),%eax \n\
|
||||||
call *(%eax) \n\
|
call *(%eax) \n\
|
||||||
2:.long ." #dllname "_info \n\
|
2:.long ." #dllname "_info \n\
|
||||||
.long (" #n "+" #notimp ") | (((" #err ") & 0xff) <<16) | (((" #fn ") & 0xff) << 24) \n\
|
.long (" #n "+" #notimp ") | (((" #err ") & 0xff) <<16) \n\
|
||||||
.asciz \"" #name "\" \n\
|
.asciz \"" #name "\" \n\
|
||||||
.text \n\
|
.text \n\
|
||||||
");
|
");
|
||||||
|
|
||||||
/* DLL loader helper functions used during initialization. */
|
/* DLL loader helper functions used during initialization. */
|
||||||
@ -204,6 +204,21 @@ union retchain
|
|||||||
long long ll;
|
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
|
#define RETRY_COUNT 10
|
||||||
|
|
||||||
/* The standard DLL initialization routine. */
|
/* The standard DLL initialization routine. */
|
||||||
@ -221,21 +236,22 @@ std_dll_init ()
|
|||||||
yield ();
|
yield ();
|
||||||
}
|
}
|
||||||
while (InterlockedIncrement (&dll->here));
|
while (InterlockedIncrement (&dll->here));
|
||||||
else if (!dll->handle)
|
else if ((uintptr_t) dll->handle <= 1)
|
||||||
{
|
{
|
||||||
fenv_t fpuenv;
|
fenv_t fpuenv;
|
||||||
fegetenv (&fpuenv);
|
fegetenv (&fpuenv);
|
||||||
WCHAR dll_path[MAX_PATH];
|
WCHAR dll_path[MAX_PATH];
|
||||||
DWORD err = ERROR_SUCCESS;
|
DWORD err = ERROR_SUCCESS;
|
||||||
|
int i;
|
||||||
/* http://www.microsoft.com/technet/security/advisory/2269637.mspx */
|
/* http://www.microsoft.com/technet/security/advisory/2269637.mspx */
|
||||||
wcpcpy (wcpcpy (dll_path, windows_system_directory), dll->name);
|
wcpcpy (wcpcpy (dll_path, windows_system_directory), dll->name);
|
||||||
/* MSDN seems to imply that LoadLibrary can fail mysteriously, so,
|
/* MSDN seems to imply that LoadLibrary can fail mysteriously, so,
|
||||||
since there have been reports of this in the mailing list, retry
|
since there have been reports of this in the mailing list, retry
|
||||||
several times before giving up. */
|
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 loading the library succeeds, just leave the loop. */
|
||||||
if ((dll->handle = LoadLibraryW (dll_path)) != NULL)
|
if (!dll_load (dll->handle, dll_path))
|
||||||
break;
|
break;
|
||||||
/* Otherwise check error code returned by LoadLibrary. If the
|
/* Otherwise check error code returned by LoadLibrary. If the
|
||||||
error code is neither NOACCESS nor DLL_INIT_FAILED, break out
|
error code is neither NOACCESS nor DLL_INIT_FAILED, break out
|
||||||
@ -246,15 +262,13 @@ std_dll_init ()
|
|||||||
if (i < RETRY_COUNT)
|
if (i < RETRY_COUNT)
|
||||||
yield ();
|
yield ();
|
||||||
}
|
}
|
||||||
if (!dll->handle)
|
if ((uintptr_t) dll->handle <= 1)
|
||||||
{
|
{
|
||||||
/* If LoadLibrary with full path returns one of the weird errors
|
/* If LoadLibrary with full path returns one of the weird errors
|
||||||
reported on the Cygwin mailing list, retry with only the DLL
|
reported on the Cygwin mailing list, retry with only the DLL
|
||||||
name. Checking the error codes allows to restrict loading
|
name. Only do this when the above retry loop has been exhausted. */
|
||||||
with just the DLL name to this specific problem. */
|
if (i > RETRY_COUNT && dll_load (dll->handle, dll->name))
|
||||||
if ((err == ERROR_NOACCESS || err == ERROR_DLL_INIT_FAILED)
|
/* got it with the fallback */;
|
||||||
&& (dll->handle = LoadLibraryW (dll->name)) != NULL)
|
|
||||||
;
|
|
||||||
else if ((func->decoration & 1))
|
else if ((func->decoration & 1))
|
||||||
dll->handle = INVALID_HANDLE_VALUE;
|
dll->handle = INVALID_HANDLE_VALUE;
|
||||||
else
|
else
|
||||||
@ -330,7 +344,7 @@ wsock_init ()
|
|||||||
return ret.ll;
|
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
|
LoadDLLfuncEx2 (DnsQuery_A, 24, dnsapi, 1, 127) // ERROR_PROC_NOT_FOUND
|
||||||
LoadDLLfuncEx (DnsRecordListFree, 8, dnsapi, 1)
|
LoadDLLfuncEx (DnsRecordListFree, 8, dnsapi, 1)
|
||||||
@ -435,27 +449,27 @@ LoadDLLfunc (SetProcessWindowStation, 4, user32)
|
|||||||
LoadDLLfunc (SetThreadDesktop, 4, user32)
|
LoadDLLfunc (SetThreadDesktop, 4, user32)
|
||||||
LoadDLLfunc (ShowWindowAsync, 8, user32)
|
LoadDLLfunc (ShowWindowAsync, 8, user32)
|
||||||
|
|
||||||
LoadDLLfunc (timeBeginPeriod, 4, winmm)
|
LoadDLLfuncEx3 (timeBeginPeriod, 4, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (timeEndPeriod, 4, winmm)
|
LoadDLLfuncEx3 (timeEndPeriod, 4, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (timeGetDevCaps, 8, winmm)
|
LoadDLLfuncEx3 (timeGetDevCaps, 8, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (timeGetTime, 0, winmm)
|
LoadDLLfuncEx3 (timeGetTime, 0, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveInAddBuffer, 12, winmm)
|
LoadDLLfuncEx3 (waveInAddBuffer, 12, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveInClose, 4, winmm)
|
LoadDLLfuncEx3 (waveInClose, 4, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveInGetNumDevs, 0, winmm)
|
LoadDLLfuncEx3 (waveInGetNumDevs, 0, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveInOpen, 24, winmm)
|
LoadDLLfuncEx3 (waveInOpen, 24, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveInPrepareHeader, 12, winmm)
|
LoadDLLfuncEx3 (waveInPrepareHeader, 12, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveInReset, 4, winmm)
|
LoadDLLfuncEx3 (waveInReset, 4, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveInStart, 4, winmm)
|
LoadDLLfuncEx3 (waveInStart, 4, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveInUnprepareHeader, 12, winmm)
|
LoadDLLfuncEx3 (waveInUnprepareHeader, 12, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveOutClose, 4, winmm)
|
LoadDLLfuncEx3 (waveOutClose, 4, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveOutGetNumDevs, 0, winmm)
|
LoadDLLfuncEx3 (waveOutGetNumDevs, 0, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveOutGetVolume, 8, winmm)
|
LoadDLLfuncEx3 (waveOutGetVolume, 8, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveOutOpen, 24, winmm)
|
LoadDLLfuncEx3 (waveOutOpen, 24, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveOutPrepareHeader, 12, winmm)
|
LoadDLLfuncEx3 (waveOutPrepareHeader, 12, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveOutReset, 4, winmm)
|
LoadDLLfuncEx3 (waveOutReset, 4, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveOutSetVolume, 8, winmm)
|
LoadDLLfuncEx3 (waveOutSetVolume, 8, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveOutUnprepareHeader, 12, winmm)
|
LoadDLLfuncEx3 (waveOutUnprepareHeader, 12, winmm, 0, 0, 1)
|
||||||
LoadDLLfunc (waveOutWrite, 12, winmm)
|
LoadDLLfuncEx3 (waveOutWrite, 12, winmm, 0, 0, 1)
|
||||||
|
|
||||||
LoadDLLfunc (accept, 12, ws2_32)
|
LoadDLLfunc (accept, 12, ws2_32)
|
||||||
LoadDLLfunc (bind, 12, ws2_32)
|
LoadDLLfunc (bind, 12, ws2_32)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user