summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristopher Faylor <cgf@redhat.com>2004-01-12 05:15:18 +0000
committerChristopher Faylor <cgf@redhat.com>2004-01-12 05:15:18 +0000
commitb11056fbcf1136f3a15eb54f97a439f91d5420af (patch)
tree9fff2cb5189a0474ffefa1a08ce55b41eb3d218a
parent46f9078b6f5ef23c2fcebc7318aed97b3f60482c (diff)
downloadgdb-b11056fbcf1136f3a15eb54f97a439f91d5420af.tar.gz
* Makefile.in (DLL_IMPORTS): Link advapi32 to ensure proper DLL initialization.
* autoload.cc (RegCloseKey): Arbitrarily choose this function as a "seed" to pull the advapi32 link library in. So, comment out the autoloading. * cygtls.cc (_threadinfo::init_thread): Just clear CYGTLS_PADSIZE. (_threadinfo::remove): Add debugging. (_threadinfo::find_tls): Ditto. * cygtls.h (_threadinfo::padding): Make zero length (for now?). * dcrt0.cc (dll_crt0_0): Move more initialization here from dll_crt0_1. (dll_crt0_1): See above. * dtable.h (dtable::lock): Remove commented out critical section locking. * dtable.h (dtable::init_lock): Remove commented out critical section locking. * dtable.h (dtable::unlock): Remove commented out critical section locking. * exceptions.cc (interruptible): bool'ize. * init.cc (threadfunc_fe): Revert to storing threadfunc at stack bottom. (munge_threadfunc): Ditto. Avoid adding overhead to calibration_thread. (prime_threads): Don't initialize tls stuff. (dll_entry): Make minor change to initialization order. * tlsoffsets.h: Regenerate. * sigproc.cc (wait_sig): Add sanity check for end of process thread exit. * select.h: Make minor formatting change.
-rw-r--r--winsup/cygwin/ChangeLog33
-rw-r--r--winsup/cygwin/Makefile.in2
-rw-r--r--winsup/cygwin/autoload.cc536
-rw-r--r--winsup/cygwin/cygheap.cc1
-rw-r--r--winsup/cygwin/cygthread.cc3
-rw-r--r--winsup/cygwin/cygtls.cc4
-rw-r--r--winsup/cygwin/cygtls.h4
-rw-r--r--winsup/cygwin/dcrt0.cc28
-rw-r--r--winsup/cygwin/dtable.h6
-rw-r--r--winsup/cygwin/exceptions.cc10
-rw-r--r--winsup/cygwin/init.cc22
-rw-r--r--winsup/cygwin/select.h55
-rw-r--r--winsup/cygwin/sigproc.cc2
-rw-r--r--winsup/cygwin/tlsoffsets.h84
14 files changed, 710 insertions, 80 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 88606d16d38..2e91790190b 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,36 @@
+2004-01-12 Christopher Faylor <cgf@redhat.com>
+
+ * Makefile.in (DLL_IMPORTS): Link advapi32 to ensure proper DLL
+ initialization.
+ * autoload.cc (RegCloseKey): Arbitrarily choose this function as a
+ "seed" to pull the advapi32 link library in. So, comment out the
+ autoloading.
+ * cygtls.cc (_threadinfo::init_thread): Just clear CYGTLS_PADSIZE.
+ (_threadinfo::remove): Add debugging.
+ (_threadinfo::find_tls): Ditto.
+ * cygtls.h (_threadinfo::padding): Make zero length (for now?).
+ * dcrt0.cc (dll_crt0_0): Move more initialization here from dll_crt0_1.
+ (dll_crt0_1): See above.
+ * dtable.h (dtable::lock): Remove commented out critical section
+ locking.
+ * dtable.h (dtable::init_lock): Remove commented out critical section
+ locking.
+ * dtable.h (dtable::unlock): Remove commented out critical section
+ locking.
+ * exceptions.cc (interruptible): bool'ize.
+ * init.cc (threadfunc_fe): Revert to storing threadfunc at stack
+ bottom.
+ (munge_threadfunc): Ditto. Avoid adding overhead to
+ calibration_thread.
+ (prime_threads): Don't initialize tls stuff.
+ (dll_entry): Make minor change to initialization order.
+ * tlsoffsets.h: Regenerate.
+
+ * sigproc.cc (wait_sig): Add sanity check for end of process thread
+ exit.
+
+ * select.h: Make minor formatting change.
+
2004-01-10 Christopher Faylor <cgf@redhat.com>
* Makefile.in: Add still more -fomit-frame-pointer functions.
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index c3336bcf72c..cf15b320d28 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -113,7 +113,7 @@ EXTRA_OFILES=$(bupdir1)/libiberty/random.o $(bupdir1)/libiberty/strsignal.o
MALLOC_OFILES=@MALLOC_OFILES@
-DLL_IMPORTS:=$(w32api_lib)/libkernel32.a
+DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libadvapi32.a
MT_SAFE_OBJECTS:=
# Please maintain this list in sorted order, with maximum files per 80 col line
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
new file mode 100644
index 00000000000..6d0177fd292
--- /dev/null
+++ b/winsup/cygwin/autoload.cc
@@ -0,0 +1,536 @@
+/* autoload.cc: all dynamic load stuff.
+
+ Copyright 2000, 2001, 2002, 2003 Red Hat, Inc.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+#include "winsup.h"
+#define USE_SYS_TYPES_FD_SET
+#include <winsock2.h>
+
+/* Macro for defining "auto-load" functions.
+ * Note that this is self-modifying code *gasp*.
+ * The first invocation of a routine will trigger the loading of
+ * the DLL. This will then be followed by the discovery of
+ * the procedure's entry point, which is placed into the location
+ * pointed to by the stack pointer. This code then changes
+ * the "call" operand which invoked it to a "jmp" which will
+ * transfer directly to the DLL function on the next invocation.
+ *
+ * Subsequent calls to routines whose transfer address has not been
+ * determined will skip the "load the dll" step, starting at the
+ * "discovery of the entry point" step.
+ *
+ * So, immediately following the the call to one of the above routines
+ * we have:
+ * DLL info (4 bytes) Pointer to a block of information concerning
+ * the DLL (see below).
+ * DLL args (4 bytes) The number of arguments pushed on the stack by
+ * the call. If this is an odd value then this
+ * is a flag that non-existence of this function
+ * is not a fatal error
+ * func name (n bytes) asciz string containing the name of the function
+ * to be loaded.
+ *
+ * The DLL info block consists of the following
+ * load_state (4 bytes) Pointer to a word containing the routine used
+ * to eventually invoke the function. Initially
+ * points to an init function which loads the
+ * DLL, gets the process's load address,
+ * changes the contents here to point to the
+ * function address, and changes the call *(%eax)
+ * to a jmp func. If the initialization has been
+ * done, only the load part is done.
+ * DLL handle (4 bytes) The handle to use when loading the DLL.
+ * DLL locker (4 bytes) Word to use to avoid multi-thread access during
+ * initialization.
+ * extra init (4 bytes) Extra initialization function.
+ * DLL name (n bytes) asciz string containing the name of the DLL.
+ */
+
+/* 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\
+ .section ." #dllname "_info,\"w\" \n\
+ .linkonce \n\
+ .long _std_dll_init \n\
+ .long 0 \n\
+ .long -1 \n\
+ .long " #init_also " \n\
+ .asciz \"" #dllname "\" \n\
+ .text \n\
+");
+
+/* Create a "decorated" name */
+#define mangle(name, n) #name "@" #n
+
+/* Standard DLL load macro. Invokes a fatal warning if the function isn't
+ found. */
+#define LoadDLLfunc(name, n, dllname) LoadDLLfuncEx (name, n, dllname, 0)
+#define LoadDLLfuncEx(name, n, dllname, notimp) LoadDLLfuncEx2(name, n, dllname, notimp, 0)
+
+/* Main DLL setup stuff. */
+#define LoadDLLfuncEx2(name, n, dllname, notimp, err) \
+ LoadDLLprime (dllname, dll_func_load) \
+ __asm__ (" \n\
+ .section ." #dllname "_text,\"wx\" \n\
+ .global _" mangle (name, n) " \n\
+ .global _win32_" mangle (name, n) " \n\
+ .align 8 \n\
+_" mangle (name, n) ": \n\
+_win32_" mangle (name, n) ": \n\
+ .byte 0xe9 \n\
+ .long -4 + 1f - . \n\
+1:movl (2f),%eax \n\
+ call *(%eax) \n\
+2:.long ." #dllname "_info \n\
+ .long (" #n "+" #notimp ") | " #err "<<16 \n\
+ .asciz \"" #name "\" \n\
+ .text \n\
+");
+
+/* DLL loader helper functions used during initialization. */
+
+/* The function which finds the address, given the name and overwrites
+ the call so that future invocations go straight to the function in
+ the DLL. */
+extern "C" void dll_func_load () __asm__ ("dll_func_load");
+
+/* Called by the primary initialization function "init_std_dll" to
+ setup the stack and eliminate future calls to init_std_dll for other
+ functions from this DLL. */
+extern "C" void dll_chain () __asm__ ("dll_chain");
+
+/* called by the secondary initialization function to call dll_func_load. */
+extern "C" void dll_chain1 () __asm__ ("dll_chain1");
+
+extern "C" {
+
+/* FIXME: This is not thread-safe? */
+__asm__ (" \n\
+msg1: \n\
+ .ascii \"couldn't dynamically determine load address for '%s' (handle %p), %E\\0\"\n\
+ \n\
+ .align 32 \n\
+noload: \n\
+ popl %edx # Get the address of the information block\n\
+ movl 4(%edx),%eax # Should we 'ignore' the lack \n\
+ test $1,%eax # of this function? \n\
+ jz 1f # Nope. \n\
+ decl %eax # Yes. This is the # of bytes + 1 \n\
+ popl %edx # Caller's caller \n\
+ addl %eax,%esp # Pop off bytes \n\
+ andl $0xffff0000,%eax# upper word \n\
+ subl %eax,%esp # adjust for possible return value \n\
+ pushl %eax # Save for later \n\
+ movl $127,%eax # ERROR_PROC_NOT_FOUND \n\
+ pushl %eax # First argument \n\
+ call _SetLastError@4 # Set it \n\
+ popl %eax # Get back argument \n\
+ shrl $16,%eax # return value in high order word \n\
+ jmp *%edx # Return \n\
+1: \n\
+ movl (%edx),%eax # Handle value \n\
+ pushl 4(%eax) \n\
+ leal 8(%edx),%eax # Location of name of function \n\
+ push %eax \n\
+ push $msg1 # The message \n\
+ call ___api_fatal # Print message. Never returns \n\
+ \n\
+ .globl dll_func_load \n\
+dll_func_load: \n\
+ movl (%esp),%eax # 'Return address' contains load info \n\
+ addl $8,%eax # Address of name of function to load \n\
+ pushl %eax # Second argument \n\
+ movl -8(%eax),%eax # Where handle lives \n\
+ movl 4(%eax),%eax # Address of Handle to DLL \n\
+ pushl %eax # Handle to DLL \n\
+ call _GetProcAddress@8# Load it \n\
+ test %eax,%eax # Success? \n\
+ jne gotit # Yes \n\
+ jmp noload # Issue an error or return \n\
+gotit: \n\
+ popl %edx # Pointer to 'return address' \n\
+ subl %edx,%eax # Make it relative \n\
+ addl $7,%eax # Tweak \n\
+ subl $12,%edx # Point to jmp \n\
+ movl %eax,1(%edx) # Move relative address after jump \n\
+ jmp *%edx # Jump to actual function \n\
+ \n\
+ .global dll_chain \n\
+dll_chain: \n\
+ pushl %eax # Restore 'return address' \n\
+ movl (%eax),%eax # Get address of DLL info block \n\
+ movl $dll_func_load,(%eax) # Just load func now \n\
+ jmp *%edx # Jump to next init function \n\
+ \n\
+dll_chain1: \n\
+ pushl %eax # Restore 'return address' \n\
+ jmp *%edx # Jump to next init function \n\
+");
+
+/* C representations of the two info blocks described above.
+ FIXME: These structures confuse gdb for some reason. GDB can print
+ the whole structure but has problems with the name field? */
+struct dll_info
+{
+ DWORD load_state;
+ HANDLE handle;
+ LONG here;
+ void (*init) ();
+ char name[];
+};
+
+struct func_info
+{
+ struct dll_info *dll;
+ LONG decoration;
+ char name[];
+};
+
+/* Mechanism for setting up info for passing to dll_chain routines. */
+union retchain
+{
+ struct {long high; long low;};
+ long long ll;
+};
+
+/* The standard DLL initialization routine. */
+__attribute__ ((used, noinline)) static long long
+std_dll_init ()
+{
+ HANDLE h;
+ struct func_info *func = (struct func_info *) __builtin_return_address (0);
+ struct dll_info *dll = func->dll;
+ retchain ret;
+
+ if (InterlockedIncrement (&dll->here))
+ do
+ {
+ InterlockedDecrement (&dll->here);
+ low_priority_sleep (0);
+ }
+ while (InterlockedIncrement (&dll->here));
+ else if (!dll->handle)
+ {
+ if ((h = LoadLibrary (dll->name)) != NULL)
+ dll->handle = h;
+ else if (!(func->decoration & 1))
+ api_fatal ("could not load %s, %E", dll->name);
+ else
+ dll->handle = INVALID_HANDLE_VALUE;
+ }
+
+ InterlockedDecrement (&dll->here);
+
+ /* Kludge alert. Redirects the return address to dll_chain. */
+ __asm__ __volatile__ (" \n\
+ movl $dll_chain,4(%ebp) \n\
+ ");
+
+ /* Set "arguments for dll_chain. */
+ ret.low = (long) dll->init;
+ ret.high = (long) func;
+ return ret.ll;
+}
+
+/* Initialization function for winsock stuff. */
+bool NO_COPY wsock_started = 0;
+__attribute__ ((used, noinline, regparm(1))) static long long
+wsock_init ()
+{
+ static LONG NO_COPY here = -1L;
+ struct func_info *func = (struct func_info *) __builtin_return_address (0);
+ struct dll_info *dll = func->dll;
+
+ __asm__ (" \n\
+ .section .ws2_32_info \n\
+ .equ _ws2_32_handle,.ws2_32_info + 4 \n\
+ .global _ws2_32_handle \n\
+ .section .wsock32_info \n\
+ .equ _wsock32_handle,.wsock32_info + 4 \n\
+ .global _wsock32_handle \n\
+ .text \n\
+ ");
+
+ while (InterlockedIncrement (&here))
+ {
+ InterlockedDecrement (&here);
+ low_priority_sleep (0);
+ }
+
+ if (!wsock_started && (winsock_active || winsock2_active))
+ {
+ /* Don't use autoload to load WSAStartup to eliminate recursion. */
+ int (*wsastartup) (int, WSADATA *);
+
+ wsastartup = (int (*)(int, WSADATA *))
+ GetProcAddress ((HMODULE) (dll->handle), "WSAStartup");
+ if (wsastartup)
+ {
+ int res = wsastartup ((2<<8) | 2, &wsadata);
+
+ debug_printf ("res %d", res);
+ debug_printf ("wVersion %d", wsadata.wVersion);
+ debug_printf ("wHighVersion %d", wsadata.wHighVersion);
+ debug_printf ("szDescription %s", wsadata.szDescription);
+ debug_printf ("szSystemStatus %s", wsadata.szSystemStatus);
+ debug_printf ("iMaxSockets %d", wsadata.iMaxSockets);
+ debug_printf ("iMaxUdpDg %d", wsadata.iMaxUdpDg);
+ debug_printf ("lpVendorInfo %d", wsadata.lpVendorInfo);
+
+ wsock_started = 1;
+ }
+ }
+
+ InterlockedDecrement (&here);
+
+ /* Kludge alert. Redirects the return address to dll_chain1. */
+ __asm__ __volatile__ (" \n\
+ movl $dll_chain1,4(%ebp) \n\
+ ");
+
+ volatile retchain ret;
+ /* Set "arguments for dll_chain1. */
+ ret.low = (long) dll_func_load;
+ ret.high = (long) func;
+ return ret.ll;
+}
+
+LoadDLLprime (wsock32, _wsock_init)
+LoadDLLprime (ws2_32, _wsock_init)
+
+LoadDLLfunc (AccessCheck, 32, advapi32)
+LoadDLLfunc (AddAccessAllowedAce, 16, advapi32)
+LoadDLLfunc (AddAccessDeniedAce, 16, advapi32)
+LoadDLLfunc (AddAce, 20, advapi32)
+LoadDLLfunc (AdjustTokenPrivileges, 24, advapi32)
+LoadDLLfuncEx (AllocateLocallyUniqueId, 4, advapi32, 1)
+LoadDLLfunc (CopySid, 12, advapi32)
+LoadDLLfunc (CreateProcessAsUserA, 44, advapi32)
+LoadDLLfuncEx (CryptAcquireContextA, 20, advapi32, 1)
+LoadDLLfuncEx (CryptGenRandom, 12, advapi32, 1)
+LoadDLLfuncEx (CryptReleaseContext, 8, advapi32, 1)
+LoadDLLfunc (DeregisterEventSource, 4, advapi32)
+LoadDLLfunc (DuplicateToken, 12, advapi32)
+LoadDLLfuncEx (DuplicateTokenEx, 24, advapi32, 1)
+LoadDLLfunc (EqualSid, 8, advapi32)
+LoadDLLfunc (FindFirstFreeAce, 8, advapi32)
+LoadDLLfunc (GetAce, 12, advapi32)
+LoadDLLfunc (GetFileSecurityA, 20, advapi32)
+LoadDLLfunc (GetKernelObjectSecurity, 20, advapi32)
+LoadDLLfunc (GetLengthSid, 4, advapi32)
+LoadDLLfunc (GetSecurityDescriptorDacl, 16, advapi32)
+LoadDLLfunc (GetSecurityDescriptorGroup, 12, advapi32)
+LoadDLLfunc (GetSecurityDescriptorOwner, 12, advapi32)
+LoadDLLfunc (GetSecurityInfo, 32, advapi32)
+LoadDLLfunc (GetSidIdentifierAuthority, 4, advapi32)
+LoadDLLfunc (GetSidSubAuthority, 8, advapi32)
+LoadDLLfunc (GetSidSubAuthorityCount, 4, advapi32)
+LoadDLLfunc (GetTokenInformation, 20, advapi32)
+LoadDLLfunc (GetUserNameA, 8, advapi32)
+LoadDLLfunc (ImpersonateLoggedOnUser, 4, advapi32)
+LoadDLLfunc (ImpersonateNamedPipeClient, 4, advapi32)
+LoadDLLfunc (InitializeAcl, 12, advapi32)
+LoadDLLfunc (InitializeSecurityDescriptor, 8, advapi32)
+LoadDLLfunc (InitializeSid, 12, advapi32)
+LoadDLLfunc (IsValidSid, 4, advapi32)
+LoadDLLfunc (LogonUserA, 24, advapi32)
+LoadDLLfunc (LookupAccountNameA, 28, advapi32)
+LoadDLLfunc (LookupAccountNameW, 28, advapi32)
+LoadDLLfunc (LookupAccountSidA, 28, advapi32)
+LoadDLLfunc (LookupPrivilegeValueA, 12, advapi32)
+LoadDLLfunc (LsaClose, 4, advapi32)
+LoadDLLfunc (LsaEnumerateAccountRights, 16, advapi32)
+LoadDLLfunc (LsaFreeMemory, 4, advapi32)
+LoadDLLfunc (LsaNtStatusToWinError, 4, advapi32)
+LoadDLLfunc (LsaOpenPolicy, 16, advapi32)
+LoadDLLfunc (LsaQueryInformationPolicy, 12, advapi32)
+LoadDLLfunc (MakeSelfRelativeSD, 12, advapi32)
+LoadDLLfunc (OpenProcessToken, 12, advapi32)
+LoadDLLfunc (OpenThreadToken, 16, advapi32)
+// LoadDLLfunc (RegCloseKey, 4, advapi32)
+LoadDLLfunc (RegCreateKeyExA, 36, advapi32)
+LoadDLLfunc (RegDeleteKeyA, 8, advapi32)
+LoadDLLfunc (RegDeleteValueA, 8, advapi32)
+LoadDLLfunc (RegLoadKeyA, 12, advapi32)
+LoadDLLfunc (RegEnumKeyExA, 32, advapi32)
+LoadDLLfunc (RegEnumValueA, 32, advapi32)
+LoadDLLfunc (RegOpenKeyExA, 20, advapi32)
+LoadDLLfunc (RegQueryInfoKeyA, 48, advapi32)
+LoadDLLfunc (RegQueryValueExA, 24, advapi32)
+LoadDLLfunc (RegSetValueExA, 24, advapi32)
+LoadDLLfunc (RegisterEventSourceA, 8, advapi32)
+LoadDLLfunc (ReportEventA, 36, advapi32)
+LoadDLLfunc (RevertToSelf, 0, advapi32)
+LoadDLLfunc (SetKernelObjectSecurity, 12, advapi32)
+LoadDLLfunc (SetSecurityDescriptorControl, 12, advapi32)
+LoadDLLfunc (SetSecurityDescriptorDacl, 16, advapi32)
+LoadDLLfunc (SetSecurityDescriptorGroup, 12, advapi32)
+LoadDLLfunc (SetSecurityDescriptorOwner, 12, advapi32)
+LoadDLLfunc (SetTokenInformation, 16, advapi32)
+LoadDLLfunc (RegGetKeySecurity, 16, advapi32)
+
+LoadDLLfunc (NetApiBufferFree, 4, netapi32)
+LoadDLLfuncEx (NetGetDCName, 12, netapi32, 1)
+LoadDLLfunc (NetLocalGroupEnum, 28, netapi32)
+LoadDLLfunc (NetLocalGroupGetMembers, 32, netapi32)
+LoadDLLfunc (NetUserGetGroups, 28, netapi32)
+LoadDLLfunc (NetUserGetInfo, 16, netapi32)
+LoadDLLfunc (NetWkstaUserGetInfo, 12, netapi32)
+
+LoadDLLfuncEx (NtCreateToken, 52, ntdll, 1)
+LoadDLLfuncEx (NtMapViewOfSection, 40, ntdll, 1)
+LoadDLLfuncEx (NtOpenFile, 24, ntdll, 1)
+LoadDLLfuncEx (NtOpenSection, 12, ntdll, 1)
+LoadDLLfuncEx (NtQueryInformationFile, 20, ntdll, 1)
+LoadDLLfuncEx (NtQueryInformationProcess, 20, ntdll, 1)
+LoadDLLfuncEx2 (NtQueryObject, 20, ntdll, 1, 1)
+LoadDLLfuncEx (NtQuerySystemInformation, 16, ntdll, 1)
+LoadDLLfuncEx (NtQueryVirtualMemory, 24, ntdll, 1)
+LoadDLLfuncEx (NtUnmapViewOfSection, 8, ntdll, 1)
+LoadDLLfuncEx (RtlInitUnicodeString, 8, ntdll, 1)
+LoadDLLfuncEx (RtlNtStatusToDosError, 4, ntdll, 1)
+
+LoadDLLfuncEx (GetProcessMemoryInfo, 12, psapi, 1)
+
+LoadDLLfuncEx (LsaDeregisterLogonProcess, 4, secur32, 1)
+LoadDLLfuncEx (LsaFreeReturnBuffer, 4, secur32, 1)
+LoadDLLfuncEx (LsaLogonUser, 56, secur32, 1)
+LoadDLLfuncEx (LsaLookupAuthenticationPackage, 12, secur32, 1)
+LoadDLLfuncEx (LsaRegisterLogonProcess, 12, secur32, 1)
+
+LoadDLLfunc (CharToOemA, 8, user32)
+LoadDLLfunc (CharToOemBuffA, 12, user32)
+LoadDLLfunc (CloseClipboard, 0, user32)
+LoadDLLfunc (CreateWindowExA, 48, user32)
+LoadDLLfunc (CreateWindowStationA, 16, user32)
+LoadDLLfunc (DefWindowProcA, 16, user32)
+LoadDLLfunc (DispatchMessageA, 4, user32)
+LoadDLLfunc (EmptyClipboard, 0, user32)
+LoadDLLfunc (FindWindowA, 8, user32)
+LoadDLLfunc (GetClipboardData, 4, user32)
+LoadDLLfunc (GetForegroundWindow, 0, user32)
+LoadDLLfunc (GetKeyboardLayout, 4, user32)
+LoadDLLfunc (GetMessageA, 16, user32)
+LoadDLLfunc (GetPriorityClipboardFormat, 8, user32)
+LoadDLLfunc (GetProcessWindowStation, 0, user32)
+LoadDLLfunc (GetThreadDesktop, 4, user32)
+LoadDLLfunc (GetWindowThreadProcessId, 8, user32)
+LoadDLLfunc (GetUserObjectInformationA, 20, user32)
+LoadDLLfunc (KillTimer, 8, user32)
+LoadDLLfunc (MessageBeep, 4, user32)
+LoadDLLfunc (MessageBoxA, 16, user32)
+LoadDLLfunc (MsgWaitForMultipleObjects, 20, user32)
+LoadDLLfunc (OemToCharBuffA, 12, user32)
+LoadDLLfunc (OpenClipboard, 4, user32)
+LoadDLLfunc (PeekMessageA, 20, user32)
+LoadDLLfunc (PostMessageA, 16, user32)
+LoadDLLfunc (PostQuitMessage, 4, user32)
+LoadDLLfunc (RegisterClassA, 4, user32)
+LoadDLLfunc (RegisterClipboardFormatA, 4, user32)
+LoadDLLfunc (SendMessageA, 16, user32)
+LoadDLLfunc (SetClipboardData, 8, user32)
+LoadDLLfunc (SetProcessWindowStation, 4, user32)
+LoadDLLfunc (SetTimer, 16, user32)
+LoadDLLfunc (SetUserObjectSecurity, 12, user32)
+
+LoadDLLfuncEx (load_wsock32, 0, wsock32, 1) // non-existent function forces wsock32 load
+LoadDLLfunc (WSAAsyncSelect, 16, wsock32)
+LoadDLLfunc (WSACleanup, 0, wsock32)
+LoadDLLfunc (WSAGetLastError, 0, wsock32)
+LoadDLLfunc (WSASetLastError, 4, wsock32)
+// LoadDLLfunc (WSAStartup, 8, wsock32)
+LoadDLLfunc (__WSAFDIsSet, 8, wsock32)
+LoadDLLfunc (accept, 12, wsock32)
+LoadDLLfunc (bind, 12, wsock32)
+LoadDLLfunc (closesocket, 4, wsock32)
+LoadDLLfunc (connect, 12, wsock32)
+LoadDLLfunc (gethostbyaddr, 12, wsock32)
+LoadDLLfunc (gethostbyname, 4, wsock32)
+LoadDLLfuncEx2 (gethostname, 8, wsock32, 1, 1)
+LoadDLLfunc (getpeername, 12, wsock32)
+LoadDLLfunc (getprotobyname, 4, wsock32)
+LoadDLLfunc (getprotobynumber, 4, wsock32)
+LoadDLLfunc (getservbyname, 8, wsock32)
+LoadDLLfunc (getservbyport, 8, wsock32)
+LoadDLLfunc (getsockname, 12, wsock32)
+LoadDLLfunc (getsockopt, 20, wsock32)
+LoadDLLfunc (inet_addr, 4, wsock32)
+LoadDLLfunc (inet_network, 4, wsock32)
+LoadDLLfunc (inet_ntoa, 4, wsock32)
+LoadDLLfunc (ioctlsocket, 12, wsock32)
+LoadDLLfunc (listen, 8, wsock32)
+LoadDLLfunc (rcmd, 24, wsock32)
+LoadDLLfunc (recv, 16, wsock32)
+LoadDLLfunc (recvfrom, 24, wsock32)
+LoadDLLfunc (rexec, 24, wsock32)
+LoadDLLfunc (rresvport, 4, wsock32)
+LoadDLLfunc (select, 20, wsock32)
+LoadDLLfunc (send, 16, wsock32)
+LoadDLLfunc (sendto, 24, wsock32)
+LoadDLLfunc (setsockopt, 20, wsock32)
+LoadDLLfunc (shutdown, 8, wsock32)
+LoadDLLfunc (socket, 12, wsock32)
+
+LoadDLLfuncEx (WSACloseEvent, 4, ws2_32, 1)
+LoadDLLfuncEx (WSACreateEvent, 0, ws2_32, 1)
+LoadDLLfuncEx (WSADuplicateSocketA, 12, ws2_32, 1)
+LoadDLLfuncEx (WSAGetOverlappedResult, 20, ws2_32, 1)
+LoadDLLfuncEx (WSARecv, 28, ws2_32, 1)
+LoadDLLfuncEx (WSARecvFrom, 36, ws2_32, 1)
+LoadDLLfuncEx (WSASend, 28, ws2_32, 1)
+LoadDLLfuncEx (WSASendTo, 36, ws2_32, 1)
+LoadDLLfuncEx (WSASetEvent, 4, ws2_32, 1)
+LoadDLLfuncEx (WSASocketA, 24, ws2_32, 1)
+LoadDLLfuncEx (WSAWaitForMultipleEvents, 20, ws2_32, 1)
+LoadDLLfuncEx (WSAEventSelect, 12, ws2_32, 1)
+LoadDLLfuncEx (WSAEnumNetworkEvents, 12, ws2_32, 1)
+
+LoadDLLfuncEx (GetIfTable, 12, iphlpapi, 1)
+LoadDLLfuncEx (GetIfEntry, 4, iphlpapi, 1)
+LoadDLLfuncEx (GetIpAddrTable, 12, iphlpapi, 1)
+LoadDLLfuncEx (GetNetworkParams, 8, iphlpapi, 1)
+
+LoadDLLfunc (CoInitialize, 4, ole32)
+LoadDLLfunc (CoUninitialize, 0, ole32)
+LoadDLLfunc (CoCreateInstance, 20, ole32)
+
+LoadDLLfuncEx (CancelIo, 4, kernel32, 1)
+LoadDLLfuncEx (CreateHardLinkA, 12, kernel32, 1)
+LoadDLLfuncEx (CreateToolhelp32Snapshot, 8, kernel32, 1)
+LoadDLLfuncEx2 (GetCompressedFileSizeA, 8, kernel32, 1, 0xffffffff)
+LoadDLLfuncEx (GetConsoleWindow, 0, kernel32, 1)
+LoadDLLfuncEx (GetDiskFreeSpaceEx, 16, kernel32, 1)
+LoadDLLfuncEx (GetSystemTimes, 12, kernel32, 1)
+LoadDLLfuncEx2 (IsDebuggerPresent, 0, kernel32, 1, 1)
+LoadDLLfunc (IsProcessorFeaturePresent, 4, kernel32);
+LoadDLLfuncEx (Process32First, 8, kernel32, 1)
+LoadDLLfuncEx (Process32Next, 8, kernel32, 1)
+LoadDLLfuncEx (RegisterServiceProcess, 8, kernel32, 1)
+LoadDLLfuncEx (SignalObjectAndWait, 16, kernel32, 1)
+LoadDLLfuncEx (SwitchToThread, 0, kernel32, 1)
+LoadDLLfunc (TryEnterCriticalSection, 4, kernel32)
+
+LoadDLLfuncEx (waveOutGetNumDevs, 0, winmm, 1)
+LoadDLLfuncEx (waveOutOpen, 24, winmm, 1)
+LoadDLLfuncEx (waveOutReset, 4, winmm, 1)
+LoadDLLfuncEx (waveOutClose, 4, winmm, 1)
+LoadDLLfuncEx (waveOutGetVolume, 8, winmm, 1)
+LoadDLLfuncEx (waveOutSetVolume, 8, winmm, 1)
+LoadDLLfuncEx (waveOutUnprepareHeader, 12, winmm, 1)
+LoadDLLfuncEx (waveOutPrepareHeader, 12, winmm, 1)
+LoadDLLfuncEx (waveOutWrite, 12, winmm, 1)
+LoadDLLfuncEx (timeGetDevCaps, 8, winmm, 1)
+LoadDLLfuncEx (timeGetTime, 0, winmm, 1)
+LoadDLLfuncEx (timeBeginPeriod, 4, winmm, 1)
+LoadDLLfuncEx (timeEndPeriod, 4, winmm, 1)
+
+LoadDLLfuncEx (UuidCreate, 4, rpcrt4, 1)
+LoadDLLfuncEx (UuidCreateSequential, 4, rpcrt4, 1)
+}
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index b6dbe265109..0171f99f687 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -216,6 +216,7 @@ cygheap_init ()
cygheap->fdtab.init ();
if (!cygheap->sigs)
sigalloc ();
+
if (!cygheap->shared_prefix)
cygheap->shared_prefix = cstrdup (
wincap.has_terminal_services ()
diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc
index eb761ea56ff..e830196635d 100644
--- a/winsup/cygwin/cygthread.cc
+++ b/winsup/cygwin/cygthread.cc
@@ -40,7 +40,7 @@ cygthread::stub (VOID *arg)
CloseHandle (info->ev);
CloseHandle (info->thread_sync);
}
- info->ev = info->thread_sync = info->stack_ptr = NULL;
+ info->ev = info->thread_sync = info->stack_ptr = NULL;
}
else
{
@@ -51,6 +51,7 @@ cygthread::stub (VOID *arg)
info->thread_sync = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
}
}
+
while (1)
{
if (!info->__name)
diff --git a/winsup/cygwin/cygtls.cc b/winsup/cygwin/cygtls.cc
index 7fe9af5c2da..4514ba15dc8 100644
--- a/winsup/cygwin/cygtls.cc
+++ b/winsup/cygwin/cygtls.cc
@@ -98,7 +98,7 @@ _threadinfo::init_thread (void *x, DWORD (*func) (void *, void *))
{
if (x)
{
- memset (this, 0, ((char *) padding - (char *) this));
+ memset (this, 0, CYGTLS_PADSIZE);
stackptr = stack;
if (_GLOBAL_REENT)
{
@@ -134,6 +134,7 @@ _threadinfo::init_thread (void *x, DWORD (*func) (void *, void *))
void
_threadinfo::remove (DWORD wait)
{
+ debug_printf ("wait %p\n", wait);
sentry here (wait);
if (here.acquired ())
{
@@ -174,6 +175,7 @@ static size_t NO_COPY threadlist_ix = BAD_IX;
_threadinfo *
_threadinfo::find_tls (int sig)
{
+ debug_printf ("sig %d\n", sig);
sentry here (INFINITE);
__asm__ volatile (".equ _threadlist_exception_return,.");
_threadinfo *res = NULL;
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 5dcbbe3657a..f3fadfb4ea4 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -110,7 +110,7 @@ struct _threadinfo
__stack_t *stackptr;
int sig;
__stack_t stack[TLS_STACK_SIZE];
- unsigned padding[256];
+ unsigned padding[0];
/*gentls_offsets*/
static CRITICAL_SECTION protect_linked_list;
@@ -142,5 +142,5 @@ extern _threadinfo *_main_tls;
#define __getreent() (&_my_tls.local_clib)
-#define CYGTLS_PADSIZE (sizeof (_threadinfo))
+enum {CYGTLS_PADSIZE = (((char *) _main_tls->padding) - ((char *) _main_tls))};
#endif /*_CYGTLS_H*/
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index e512f353c86..57a26aca2e0 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -577,7 +577,6 @@ dll_crt0_0 ()
char zeros[sizeof (child_proc_info->zero)] = {0};
static NO_COPY STARTUPINFO si;
- int mypid = 0;
_my_tls.stackptr = NULL;
@@ -591,8 +590,12 @@ dll_crt0_0 ()
DuplicateHandle (hMainProc, GetCurrentThread (), hMainProc,
&hMainThread, 0, false, DUPLICATE_SAME_ACCESS);
+ (void) SetErrorMode (SEM_FAILCRITICALERRORS);
+
GetStartupInfo (&si);
child_proc_info = (child_info *) si.lpReserved2;
+
+ int mypid = 0;
if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info
|| memcmp (child_proc_info->zero, zeros,
sizeof (child_proc_info->zero)) != 0)
@@ -641,6 +644,7 @@ dll_crt0_0 ()
device::init ();
winpids::init ();
do_global_ctors (&__CTOR_LIST__, 1);
+ cygthread::init ();
if (!child_proc_info)
memory_init ();
@@ -696,6 +700,13 @@ dll_crt0_0 ()
}
_threadinfo::init ();
+
+ /* Initialize events */
+ events_init ();
+
+ /* Init global well known SID objects */
+ cygsid::init ();
+ cygheap->cwd.init ();
}
/* Take over from libc's crt0.o and start the application. Note the
@@ -710,11 +721,12 @@ dll_crt0_1 (char *)
/* FIXME: Verify forked children get their exception handler set up ok. */
exception_list cygwin_except_entry;
- /* Initialize SIGSEGV handling, etc. */
- init_exceptions (&cygwin_except_entry);
check_sanity_and_sync (user_data);
malloc_init ();
+ /* Initialize SIGSEGV handling, etc. */
+ init_exceptions (&cygwin_except_entry);
+
/* Nasty static stuff needed by newlib -- point to a local copy of
the reent stuff.
Note: this MUST be done here (before the forkee code) as the
@@ -725,7 +737,6 @@ dll_crt0_1 (char *)
user_data->threadinterface->Init ();
ProtectHandle (hMainProc);
ProtectHandle (hMainThread);
- cygthread::init ();
/* Initialize pthread mainthread when not forked and it is safe to call new,
otherwise it is reinitalized in fixup_after_fork */
@@ -745,12 +756,6 @@ dll_crt0_1 (char *)
cygheap->fdtab.vfork_child_fixup ();
- (void) SetErrorMode (SEM_FAILCRITICALERRORS);
-
- /* Initialize events. */
- events_init ();
-
- cygheap->cwd.init ();
main_vfork = vfork_storage.create ();
cygbench ("pre-forkee");
@@ -779,9 +784,6 @@ dll_crt0_1 (char *)
}
#endif
- /* Init global well known SID objects */
- cygsid::init ();
-
/* Initialize our process table entry. */
pinfo_init (envp, envc);
diff --git a/winsup/cygwin/dtable.h b/winsup/cygwin/dtable.h
index 19de60e6377..2f10c2afaf4 100644
--- a/winsup/cygwin/dtable.h
+++ b/winsup/cygwin/dtable.h
@@ -28,9 +28,9 @@ class dtable
static const int initial_archetype_size = 8;
int first_fd_for_open;
int cnt_need_fixup_before;
- void lock () {/*EnterCriticalSection (&lock_cs); */spf ("%u locked, tid %u\n", GetCurrentProcessId (), GetCurrentThreadId ());}
- void unlock () {/*LeaveCriticalSection (&lock_cs);*/ spf ("%u ulocked, tid %u\n", GetCurrentProcessId (), GetCurrentThreadId ());}
- void init_lock () {/*InitializeCriticalSection (&lock_cs); */spf ("%u initialized, tid %u\n", GetCurrentProcessId (), GetCurrentThreadId ());}
+ void lock () {EnterCriticalSection (&lock_cs); spf ("%u locked, tid %u\n", GetCurrentProcessId (), GetCurrentThreadId ());}
+ void unlock () {LeaveCriticalSection (&lock_cs); spf ("%u ulocked, tid %u\n", GetCurrentProcessId (), GetCurrentThreadId ());}
+ void init_lock () {InitializeCriticalSection (&lock_cs); spf ("%u initialized, tid %u\n", GetCurrentProcessId (), GetCurrentThreadId ());}
public:
size_t size;
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index dab839f6ab9..e30d8fd261e 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -316,8 +316,6 @@ cygwin_stackdump ()
#define TIME_TO_WAIT_FOR_DEBUGGER 10000
-int keep_looping = 1;
-
extern "C" int
try_to_debug (bool waitloop)
{
@@ -617,7 +615,7 @@ sig_handle_tty_stop (int sig)
}
}
-int
+bool
interruptible (DWORD pc)
{
int res;
@@ -635,11 +633,11 @@ interruptible (DWORD pc)
GetThreadContext. These resolve to a strange allocation base.
These should *never* be treated as interruptible. */
if (!h || m.State != MEM_COMMIT)
- res = 0;
+ res = false;
else if (h == user_data->hmodule)
- res = 1;
+ res = true;
else if (!GetModuleFileName (h, checkdir, windows_system_directory_length + 2))
- res = 0;
+ res = false;
else
res = !strncasematch (windows_system_directory, checkdir,
windows_system_directory_length);
diff --git a/winsup/cygwin/init.cc b/winsup/cygwin/init.cc
index 5ca52949a0f..6b3de8fa817 100644
--- a/winsup/cygwin/init.cc
+++ b/winsup/cygwin/init.cc
@@ -22,15 +22,15 @@ DWORD tls_func;
HANDLE sync_startup;
-#define OLDFUNC_OFFSET -3
+#define OLDFUNC_OFFSET -1
static void WINAPI
threadfunc_fe (VOID *arg)
{
- void *threadfunc = (void *) TlsGetValue (tls_func);
- TlsFree (tls_func);
- // _threadinfo::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[OLDFUNC_OFFSET]));
- _threadinfo::call ((DWORD (*) (void *, void *)) (threadfunc), arg);
+ _threadinfo::call ((DWORD (*) (void *, void *)) (((char **) _tlsbase)[OLDFUNC_OFFSET]), arg);
+ // void *threadfunc = (void *) TlsGetValue (tls_func);
+ // TlsFree (tls_func);
+ // _threadinfo::call ((DWORD (*) (void *, void *)) (threadfunc), arg);
}
static DWORD WINAPI
@@ -61,20 +61,20 @@ munge_threadfunc (HANDLE cygwin_hmodule)
foundit:
char *threadfunc = ebp[threadfunc_ix];
- if (0 & (((DWORD) threadfunc & 0x80000000) == 0x80000000 || threadfunc == (char *) calibration_thread))
- /*nothing*/;
+ if (threadfunc == (char *) calibration_thread)
+ /* no need for the overhead */;
else
{
ebp[threadfunc_ix] = (char *) threadfunc_fe;
- // ((char **) _tlsbase)[OLDFUNC_OFFSET] = threadfunc;
- TlsSetValue (tls_func, (void *) threadfunc);
+ ((char **) _tlsbase)[OLDFUNC_OFFSET] = threadfunc;
+ // TlsSetValue (tls_func, (void *) threadfunc);
}
}
void
prime_threads ()
{
- tls_func = TlsAlloc ();
+ // tls_func = TlsAlloc ();
if (!threadfunc_ix)
{
DWORD id;
@@ -93,8 +93,8 @@ dll_entry (HANDLE h, DWORD reason, void *static_load)
case DLL_PROCESS_ATTACH:
dynamically_loaded = (static_load == NULL);
// __cygwin_user_data.impure_ptr = &_my_tls.local_clib;
- prime_threads ();
dll_crt0_0 ();
+ prime_threads ();
// small_printf ("%u, %p, %p\n", cygwin_pid (GetCurrentProcessId ()), _tlstop, _tlsbase);
break;
case DLL_PROCESS_DETACH:
diff --git a/winsup/cygwin/select.h b/winsup/cygwin/select.h
new file mode 100644
index 00000000000..d38e19ceec7
--- /dev/null
+++ b/winsup/cygwin/select.h
@@ -0,0 +1,55 @@
+/* select.h
+
+ Copyright 1998, 1999, 2000, 2001, 2004 Red Hat, Inc.
+
+This file is part of Cygwin.
+
+This software is a copyrighted work licensed under the terms of the
+Cygwin license. Please consult the file "CYGWIN_LICENSE" for
+details. */
+
+/* Winsock select() types and macros */
+
+/*
+ * Use this struct to interface to
+ * the system provided select.
+ */
+typedef struct winsock_fd_set
+{
+ unsigned int fd_count;
+ HANDLE fd_array[1024]; /* Dynamically allocated. */
+} winsock_fd_set;
+
+/*
+ * Define the Win32 winsock definitions to have a prefix WINSOCK_
+ * so we can be explicit when we are using them.
+ */
+#define WINSOCK_FD_ISSET(fd, set) __WSAFDIsSet ((SOCKET)fd, (fd_set *)set)
+#define WINSOCK_FD_SET(fd, set) do { \
+ (set)->fd_array[(set)->fd_count++]=fd;\
+} while(0)
+#define WINSOCK_FD_ZERO(set) ((set)->fd_count = 0)
+#define WINSOCK_FD_CLR(fd, set) do { \
+ u_int __i; \
+ for (__i = 0; __i < (set)->fd_count ; __i++) { \
+ if ((set)->fd_array[__i] == fd) { \
+ while (__i < (set)->fd_count-1) { \
+ (set)->fd_array[__i] = \
+ (set)->fd_array[__i+1]; \
+ __i++; \
+ } \
+ (set)->fd_count--; \
+ break; \
+ } \
+ } \
+} while(0)
+
+extern "C" int PASCAL __WSAFDIsSet(SOCKET, fd_set*);
+extern "C" int PASCAL win32_select(int, fd_set*, fd_set*, fd_set*, const struct timeval*);
+
+/*
+ * call to winsock's select() -
+ * type coercion need to appease confused prototypes
+ */
+#define WINSOCK_SELECT(nfd, rd, wr, ex, timeo) \
+ win32_select (nfd, (fd_set *) rd, (fd_set *) wr, (fd_set *) ex, timeo)
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 79912b981df..e143a823963 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1115,6 +1115,8 @@ wait_sig (VOID *self)
sigpacket pack;
if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
break;
+ if (myself->sendsig == INVALID_HANDLE_VALUE)
+ break;
if (nb != sizeof (pack))
{
diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h
index c61bad990a0..6aeea68d5fc 100644
--- a/winsup/cygwin/tlsoffsets.h
+++ b/winsup/cygwin/tlsoffsets.h
@@ -1,46 +1,46 @@
//;# autogenerated: Do not edit.
-//; $tls::func = -5100;
-//; $tls::saved_errno = -5096;
-//; $tls::sa_flags = -5092;
-//; $tls::oldmask = -5088;
-//; $tls::newmask = -5084;
-//; $tls::event = -5080;
-//; $tls::errno_addr = -5076;
-//; $tls::initialized = -5072;
-//; $tls::sigmask = -5068;
-//; $tls::sigwait_mask = -5064;
-//; $tls::sigwait_info = -5060;
-//; $tls::infodata = -5056;
-//; $tls::tid = -4532;
-//; $tls::local_clib = -4528;
-//; $tls::locals = -3600;
-//; $tls::prev = -2064;
-//; $tls::next = -2060;
-//; $tls::stackptr = -2056;
-//; $tls::sig = -2052;
-//; $tls::stack = -2048;
-//; $tls::padding = -1024;
+//; $tls::func = -4076;
+//; $tls::saved_errno = -4072;
+//; $tls::sa_flags = -4068;
+//; $tls::oldmask = -4064;
+//; $tls::newmask = -4060;
+//; $tls::event = -4056;
+//; $tls::errno_addr = -4052;
+//; $tls::initialized = -4048;
+//; $tls::sigmask = -4044;
+//; $tls::sigwait_mask = -4040;
+//; $tls::sigwait_info = -4036;
+//; $tls::infodata = -4032;
+//; $tls::tid = -3508;
+//; $tls::local_clib = -3504;
+//; $tls::locals = -2576;
+//; $tls::prev = -1040;
+//; $tls::next = -1036;
+//; $tls::stackptr = -1032;
+//; $tls::sig = -1028;
+//; $tls::stack = -1024;
+//; $tls::padding = 0;
//; __DATA__
-#define tls_func (-5100)
-#define tls_saved_errno (-5096)
-#define tls_sa_flags (-5092)
-#define tls_oldmask (-5088)
-#define tls_newmask (-5084)
-#define tls_event (-5080)
-#define tls_errno_addr (-5076)
-#define tls_initialized (-5072)
-#define tls_sigmask (-5068)
-#define tls_sigwait_mask (-5064)
-#define tls_sigwait_info (-5060)
-#define tls_infodata (-5056)
-#define tls_tid (-4532)
-#define tls_local_clib (-4528)
-#define tls_locals (-3600)
-#define tls_prev (-2064)
-#define tls_next (-2060)
-#define tls_stackptr (-2056)
-#define tls_sig (-2052)
-#define tls_stack (-2048)
-#define tls_padding (-1024)
+#define tls_func (-4076)
+#define tls_saved_errno (-4072)
+#define tls_sa_flags (-4068)
+#define tls_oldmask (-4064)
+#define tls_newmask (-4060)
+#define tls_event (-4056)
+#define tls_errno_addr (-4052)
+#define tls_initialized (-4048)
+#define tls_sigmask (-4044)
+#define tls_sigwait_mask (-4040)
+#define tls_sigwait_info (-4036)
+#define tls_infodata (-4032)
+#define tls_tid (-3508)
+#define tls_local_clib (-3504)
+#define tls_locals (-2576)
+#define tls_prev (-1040)
+#define tls_next (-1036)
+#define tls_stackptr (-1032)
+#define tls_sig (-1028)
+#define tls_stack (-1024)
+#define tls_padding (0)