* cygtls.h (_cygtls::el): New field.

(_cygtls::handle_exceptions): New function declaration.
(_cygtls::handle_threadlist_exception): Ditto.
(_cygtls::init_exception_handler): Ditto.
(_cygtls::init_threadlist_exceptions): Remove arg from declaration.
* cygtls.cc (_cygtls::call2): Don't initialize exceptions here.
(_cygtls::init_thread): Do it here instead and use member function.
(_cygtls::handle_threadlist_exception): Move into _cygtls class.
(_cygtls::init_exception_handler): Ditto.  Rely on existence of 'el' memmber in
_cygtls.
(_cygtls::init_threadlist_exceptions): Ditto.
* dcrt0.cc (dll_crt0_1): Remove exception_list definition and setting since it
now commonly resides in the tls.
* exceptions.cc (init_exception_handler): Move to cygtls.cc.
(init_exceptions): Ditto.
(rtl_unwind): New, safe wrapper function for RtlUnwind.
(_cygtls::handle_exceptions): Move to _cygtls.  Call rtl_unwind to unwind
frames and eliminate copying of structures.  Put address of failing instruction
in si_addr, not the address on the stack.  Return 0 to indicate that we've
handled this exception.
* external.cc (cygwin_internal): Make CW_INIT_EXCEPTIONS a no-op.
* sigproc.cc (wait_sig): Accommodate argument change to
_cygtls::init_threadlist_exceptions.
* tlsoffsets.h: Regenerate.
* include/exceptions.h (exception_list): Add more stuff to the exception list.
Apparently windows needs this?
(init_exceptions): Remove bogus declaration.
* include/cygwin/signal.h (SI_USER): Redefine as zero as per SUSv3.
* thread.cc (pthread_kill): Set si_pid and si_uid.
* timer.cc (timer_thread): Set si_code to SI_TIMER.
This commit is contained in:
Christopher Faylor 2005-12-03 04:23:35 +00:00
parent e7f6a31bb0
commit f153e6b280
13 changed files with 179 additions and 133 deletions

View File

@ -1,3 +1,39 @@
2005-12-02 Christopher Faylor <cgf@timesys.com>
* cygtls.h (_cygtls::el): New field.
(_cygtls::handle_exceptions): New function declaration.
(_cygtls::handle_threadlist_exception): Ditto.
(_cygtls::init_exception_handler): Ditto.
(_cygtls::init_threadlist_exceptions): Remove arg from declaration.
* cygtls.cc (_cygtls::call2): Don't initialize exceptions here.
(_cygtls::init_thread): Do it here instead and use member function.
(_cygtls::handle_threadlist_exception): Move into _cygtls class.
(_cygtls::init_exception_handler): Ditto. Rely on existence of 'el'
memmber in _cygtls.
(_cygtls::init_threadlist_exceptions): Ditto.
* dcrt0.cc (dll_crt0_1): Remove exception_list definition and setting
since it now commonly resides in the tls.
* exceptions.cc (init_exception_handler): Move to cygtls.cc.
(init_exceptions): Ditto.
(rtl_unwind): New, safe wrapper function for RtlUnwind.
(_cygtls::handle_exceptions): Move to _cygtls. Call rtl_unwind to
unwind frames and eliminate copying of structures. Put address of
failing instruction in si_addr, not the address on the stack. Return 0
to indicate that we've handled this exception.
* external.cc (cygwin_internal): Make CW_INIT_EXCEPTIONS a no-op.
* sigproc.cc (wait_sig): Accommodate argument change to
_cygtls::init_threadlist_exceptions.
* tlsoffsets.h: Regenerate.
* include/exceptions.h (exception_list): Add more stuff to the
exception list. Apparently windows needs this?
(init_exceptions): Remove bogus declaration.
* include/cygwin/signal.h (SI_USER): Redefine as zero as per SUSv3.
* thread.cc (pthread_kill): Set si_pid and si_uid.
* timer.cc (timer_thread): Set si_code to SI_KERNEL.
2005-12-01 Christopher Faylor <cgf@timesys.com> 2005-12-01 Christopher Faylor <cgf@timesys.com>
* dcrt0.cc (getstack): Try harder to modify memory. * dcrt0.cc (getstack): Try harder to modify memory.

View File

@ -88,10 +88,6 @@ _cygtls::call (DWORD (*func) (void *, void *), void *arg)
void void
_cygtls::call2 (DWORD (*func) (void *, void *), void *arg, void *buf) _cygtls::call2 (DWORD (*func) (void *, void *), void *arg, void *buf)
{ {
exception_list except_entry;
/* Initialize this thread's ability to respond to things like
SIGSEGV or SIGFPE. */
init_exceptions (&except_entry);
_my_tls.init_thread (buf, func); _my_tls.init_thread (buf, func);
DWORD res = func (arg, buf); DWORD res = func (arg, buf);
_my_tls.remove (INFINITE); _my_tls.remove (INFINITE);
@ -117,6 +113,9 @@ _cygtls::init_thread (void *x, DWORD (*func) (void *, void *))
} }
local_clib._current_locale = "C"; local_clib._current_locale = "C";
locals.process_logmask = LOG_UPTO (LOG_DEBUG); locals.process_logmask = LOG_UPTO (LOG_DEBUG);
/* Initialize this thread's ability to respond to things like
SIGSEGV or SIGFPE. */
init_exception_handler (handle_exceptions);
} }
locals.exitsock = INVALID_SOCKET; locals.exitsock = INVALID_SOCKET;
@ -240,8 +239,8 @@ _cygtls::set_siginfo (sigpacket *pack)
} }
extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD); extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
static int int
handle_threadlist_exception (EXCEPTION_RECORD *e, void *frame, CONTEXT *c, void *) _cygtls::handle_threadlist_exception (EXCEPTION_RECORD *e, void *frame, CONTEXT *c, void *)
{ {
if (e->ExceptionCode != STATUS_ACCESS_VIOLATION) if (e->ExceptionCode != STATUS_ACCESS_VIOLATION)
{ {
@ -269,9 +268,24 @@ handle_threadlist_exception (EXCEPTION_RECORD *e, void *frame, CONTEXT *c, void
return 0; return 0;
} }
/* Set up the exception handler for the current thread. The PowerPC & Mips
use compiler generated tables to set up the exception handlers for each
region of code, and the kernel walks the call list until it finds a region
of code that handles exceptions. The x86 on the other hand uses segment
register fs, offset 0 to point to the current exception handler. */
extern exception_list *_except_list asm ("%fs:0");
void void
_cygtls::init_threadlist_exceptions (exception_list *el) _cygtls::init_exception_handler (exception_handler *eh)
{ {
extern void init_exception_handler (exception_list *, exception_handler *); el.handler = eh;
init_exception_handler (el, handle_threadlist_exception); el.prev = _except_list;
_except_list = &el;
}
void
_cygtls::init_threadlist_exceptions ()
{
init_exception_handler (handle_threadlist_exception);
} }

View File

@ -17,6 +17,7 @@ details. */
#include <mntent.h> #include <mntent.h>
#undef _NOMNTENT_FUNCS #undef _NOMNTENT_FUNCS
#include <setjmp.h> #include <setjmp.h>
#include <exceptions.h>
#ifndef _WINSOCK_H #ifndef _WINSOCK_H
/* Stupid hack: Including winsock.h explicitly causes too many problems. */ /* Stupid hack: Including winsock.h explicitly causes too many problems. */
@ -182,6 +183,7 @@ struct _cygtls
}; };
struct _local_storage locals; struct _local_storage locals;
class cygthread *_ctinfo; class cygthread *_ctinfo;
exception_list el;
san andreas; san andreas;
waitq wq; waitq wq;
struct _cygtls *prev, *next; struct _cygtls *prev, *next;
@ -212,7 +214,13 @@ struct _cygtls
void __stdcall interrupt_setup (int sig, void *handler, void __stdcall interrupt_setup (int sig, void *handler,
struct sigaction& siga) struct sigaction& siga)
__attribute__((regparm(3))); __attribute__((regparm(3)));
void init_threadlist_exceptions (struct _exception_list *);
/* exception handling */
static int handle_exceptions (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
static int handle_threadlist_exception (EXCEPTION_RECORD *e, void *frame, CONTEXT *c, void *);
void init_exception_handler (int (*) (EXCEPTION_RECORD *, void *, CONTEXT *, void*));
void init_threadlist_exceptions ();
#ifdef _THREAD_H #ifdef _THREAD_H
operator HANDLE () const {return tid->win32_obj_id;} operator HANDLE () const {return tid->win32_obj_id;}
#endif #endif

View File

@ -730,11 +730,6 @@ dll_crt0_0 ()
static void static void
dll_crt0_1 (char *) dll_crt0_1 (char *)
{ {
/* According to onno@stack.urc.tue.nl, the exception handler record must
be on the stack. */
/* FIXME: Verify forked children get their exception handler set up ok. */
exception_list cygwin_except_entry;
check_sanity_and_sync (user_data); check_sanity_and_sync (user_data);
malloc_init (); malloc_init ();
#ifdef CGF #ifdef CGF
@ -744,9 +739,6 @@ dll_crt0_1 (char *)
small_printf ("cmalloc returns %p\n", cmalloc (HEAP_STR, n)); small_printf ("cmalloc returns %p\n", cmalloc (HEAP_STR, n));
#endif #endif
/* Initialize SIGSEGV handling, etc. */
init_exceptions (&cygwin_except_entry);
user_data->resourcelocks->Init (); user_data->resourcelocks->Init ();
user_data->threadinterface->Init (); user_data->threadinterface->Init ();
ProtectHandle (hMainProc); ProtectHandle (hMainProc);

View File

@ -36,7 +36,6 @@ details. */
char debugger_command[2 * CYG_MAX_PATH + 20]; char debugger_command[2 * CYG_MAX_PATH + 20];
extern "C" { extern "C" {
static int handle_exceptions (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
extern void sigdelayed (); extern void sigdelayed ();
}; };
@ -94,28 +93,6 @@ NO_COPY static struct
/* Initialization code. */ /* Initialization code. */
// Set up the exception handler for the current thread. The PowerPC & Mips
// use compiler generated tables to set up the exception handlers for each
// region of code, and the kernel walks the call list until it finds a region
// of code that handles exceptions. The x86 on the other hand uses segment
// register fs, offset 0 to point to the current exception handler.
extern exception_list *_except_list asm ("%fs:0");
void
init_exception_handler (exception_list *el, exception_handler *eh)
{
el->handler = eh;
el->prev = _except_list;
_except_list = el;
}
extern "C" void
init_exceptions (exception_list *el)
{
init_exception_handler (el, handle_exceptions);
}
BOOL WINAPI BOOL WINAPI
dummy_ctrl_c_handler (DWORD dwCtrlType) dummy_ctrl_c_handler (DWORD dwCtrlType)
{ {
@ -403,11 +380,31 @@ try_to_debug (bool waitloop)
return dbg; return dbg;
} }
extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
static void __stdcall rtl_unwind (void *, PEXCEPTION_RECORD) __attribute__ ((noinline, regparm (3)));
void __stdcall
rtl_unwind (void *frame, PEXCEPTION_RECORD e)
{
__asm__ ("\n\
pushl %%ebx \n\
pushl %%edi \n\
pushl %%esi \n\
pushl $0 \n\
pushl %1 \n\
pushl $1f \n\
pushl %0 \n\
call _RtlUnwind@16 \n\
1: \n\
popl %%esi \n\
popl %%edi \n\
popl %%ebx \n\
": : "r" (frame), "r" (e));
}
/* Main exception handler. */ /* Main exception handler. */
extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD); int
static int _cygtls::handle_exceptions (EXCEPTION_RECORD *e, void *frame, CONTEXT *in, void *)
handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
{ {
static bool NO_COPY debugging; static bool NO_COPY debugging;
static int NO_COPY recursed; static int NO_COPY recursed;
@ -421,16 +418,13 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
/* If we've already exited, don't do anything here. Returning 1 /* If we've already exited, don't do anything here. Returning 1
tells Windows to keep looking for an exception handler. */ tells Windows to keep looking for an exception handler. */
if (exit_already) if (exit_already || e->ExceptionFlags)
return 1; return 1;
EXCEPTION_RECORD e = *e0;
CONTEXT in = *in0;
siginfo_t si; siginfo_t si;
si.si_code = SI_KERNEL; si.si_code = SI_KERNEL;
/* Coerce win32 value to posix value. */ /* Coerce win32 value to posix value. */
switch (e.ExceptionCode) switch (e->ExceptionCode)
{ {
case STATUS_FLOAT_DENORMAL_OPERAND: case STATUS_FLOAT_DENORMAL_OPERAND:
case STATUS_FLOAT_DIVIDE_BY_ZERO: case STATUS_FLOAT_DIVIDE_BY_ZERO:
@ -514,8 +508,9 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
return 1; return 1;
} }
debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e.ExceptionCode, in.Eip, in.Esp); rtl_unwind (frame, e);
debug_printf ("In cygwin_except_handler sig %d at %p", si.si_signo, in.Eip); debug_printf ("In cygwin_except_handler exc %p at %p sp %p", e->ExceptionCode, in->Eip, in->Esp);
debug_printf ("In cygwin_except_handler sig %d at %p", si.si_signo, in->Eip);
if (global_sigs[si.si_signo].sa_mask & SIGTOMASK (si.si_signo)) if (global_sigs[si.si_signo].sa_mask & SIGTOMASK (si.si_signo))
syscall_printf ("signal %d, masked %p", si.si_signo, syscall_printf ("signal %d, masked %p", si.si_signo,
@ -524,9 +519,9 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
debug_printf ("In cygwin_except_handler calling %p", debug_printf ("In cygwin_except_handler calling %p",
global_sigs[si.si_signo].sa_handler); global_sigs[si.si_signo].sa_handler);
DWORD *ebp = (DWORD *)in.Esp; DWORD *ebp = (DWORD *) in->Esp;
for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--) for (DWORD *bpend = (DWORD *) __builtin_frame_address (0); ebp > bpend; ebp--)
if (*ebp == in.SegCs && ebp[-1] == in.Eip) if (*ebp == in->SegCs && ebp[-1] == in->Eip)
{ {
ebp -= 2; ebp -= 2;
break; break;
@ -534,7 +529,7 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
if (!me.fault_guarded () if (!me.fault_guarded ()
&& (!cygwin_finished_initializing && (!cygwin_finished_initializing
|| &_my_tls == _sig_tls || &me == _sig_tls
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_DFL
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_IGN
|| (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR)) || (void *) global_sigs[si.si_signo].sa_handler == (void *) SIG_ERR))
@ -542,7 +537,7 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
/* Print the exception to the console */ /* Print the exception to the console */
if (!myself->cygstarted) if (!myself->cygstarted)
for (int i = 0; status_info[i].name; i++) for (int i = 0; status_info[i].name; i++)
if (status_info[i].code == e.ExceptionCode) if (status_info[i].code == e->ExceptionCode)
{ {
system_printf ("Exception: %s", status_info[i].name); system_printf ("Exception: %s", status_info[i].name);
break; break;
@ -561,25 +556,22 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
} }
open_stackdumpfile (); open_stackdumpfile ();
exception (&e, &in); exception (e, in);
stackdump ((DWORD) ebp, 0, 1); stackdump ((DWORD) ebp, 0, 1);
} }
signal_exit (0x80 | si.si_signo); // Flag signal + core dump signal_exit (0x80 | si.si_signo); // Flag signal + core dump
} }
extern DWORD ret_here[];
RtlUnwind (frame, ret_here, e0, 0);
__asm__ volatile (".equ _ret_here,.");
if (me.fault_guarded ()) if (me.fault_guarded ())
me.return_from_fault (); me.return_from_fault ();
si.si_addr = ebp; si.si_addr = (void *) in->Eip;
si.si_errno = si.si_pid = si.si_uid = 0; si.si_errno = si.si_pid = si.si_uid = 0;
me.push ((__stack_t) ebp, true); me.push ((__stack_t) ebp, true);
sig_send (NULL, si, &me); // Signal myself sig_send (NULL, si, &me); // Signal myself
return 1; e->ExceptionFlags = 0;
return 0;
} }
/* Utilities to call a user supplied exception handler. */ /* Utilities to call a user supplied exception handler. */

View File

@ -184,7 +184,7 @@ cygwin_internal (cygwin_getinfo_types t, ...)
return (DWORD) fillout_pinfo (va_arg (arg, pid_t), 1); return (DWORD) fillout_pinfo (va_arg (arg, pid_t), 1);
case CW_INIT_EXCEPTIONS: case CW_INIT_EXCEPTIONS:
init_exceptions (va_arg (arg, exception_list *)); /* noop */ /* init_exceptions (va_arg (arg, exception_list *)); */
return 0; return 0;
case CW_GET_CYGDRIVE_INFO: case CW_GET_CYGDRIVE_INFO:

View File

@ -102,8 +102,8 @@ typedef struct
enum enum
{ {
SI_USER = 1, /* sent by kill, raise, pthread_kill */ SI_USER = 0, /* sent by kill, raise, pthread_kill */
SI_ASYNCIO, /* sent by AIO completion (currently SI_ASYNCIO = 2, /* sent by AIO completion (currently
unimplemented) */ unimplemented) */
SI_MESGQ, /* sent by real time mesq state change SI_MESGQ, /* sent by real time mesq state change
(currently unimplemented) */ (currently unimplemented) */

View File

@ -283,12 +283,14 @@ details. */
143: Export clock_getres, clock_setres 143: Export clock_getres, clock_setres
144: Export timelocal, timegm. 144: Export timelocal, timegm.
145: Add MAP_NORESERVE flag to mmap. 145: Add MAP_NORESERVE flag to mmap.
146: Change SI_USER definition. FIXME: Need to develop compatibility macro
for this?
*/ */
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */ /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0 #define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 145 #define CYGWIN_VERSION_API_MINOR 146
/* There is also a compatibity version number associated with the /* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible shared memory regions. It is incremented when incompatible

View File

@ -106,13 +106,9 @@ typedef struct _exception_list
{ {
struct _exception_list *prev; struct _exception_list *prev;
exception_handler *handler; exception_handler *handler;
unsigned long stuff[8];
/* We're apparently free to add more stuff here.
At present we don't need any. */
} exception_list; } exception_list;
void init_exceptions (exception_list *);
#ifdef __cplusplus #ifdef __cplusplus
}; };
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -1067,8 +1067,7 @@ wait_sig (VOID *)
sigproc_printf ("myself->dwProcessId %u", myself->dwProcessId); sigproc_printf ("myself->dwProcessId %u", myself->dwProcessId);
SetEvent (wait_sig_inited); SetEvent (wait_sig_inited);
exception_list el; _sig_tls->init_threadlist_exceptions ();
_sig_tls->init_threadlist_exceptions (&el);
debug_printf ("entering ReadFile loop, readsig %p, myself->sendsig %p", debug_printf ("entering ReadFile loop, readsig %p, myself->sendsig %p",
readsig, myself->sendsig); readsig, myself->sendsig);

View File

@ -2873,7 +2873,9 @@ pthread_kill (pthread_t thread, int sig)
siginfo_t si; siginfo_t si;
si.si_signo = sig; si.si_signo = sig;
si.si_code = SI_USER; si.si_code = SI_USER;
si.si_pid = si.si_uid = si.si_errno = 0; si.si_pid = myself->pid;
si.si_uid = myself->uid;
si.si_errno = 0;
thread->cygtls->set_threadkill (); thread->cygtls->set_threadkill ();
int rval = sig ? sig_send (NULL, si, thread->cygtls) : 0; int rval = sig ? sig_send (NULL, si, thread->cygtls) : 0;

View File

@ -168,6 +168,7 @@ timer_thread (VOID *x)
memset (&si, 0, sizeof (si)); memset (&si, 0, sizeof (si));
si.si_signo = tt->evp.sigev_signo; si.si_signo = tt->evp.sigev_signo;
si.si_sigval.sival_ptr = tt->evp.sigev_value.sival_ptr; si.si_sigval.sival_ptr = tt->evp.sigev_value.sival_ptr;
si.si_code = SI_TIMER;
debug_printf ("%p sending sig %d", x, tt->evp.sigev_signo); debug_printf ("%p sending sig %d", x, tt->evp.sigev_signo);
sig_send (myself_nowait, si); sig_send (myself_nowait, si);
break; break;

View File

@ -1,121 +1,125 @@
//;# autogenerated: Do not edit. //;# autogenerated: Do not edit.
//; $tls::sizeof__cygtls = 3988; //; $tls::sizeof__cygtls = 4028;
//; $tls::func = -3988; //; $tls::func = -4028;
//; $tls::pfunc = 0; //; $tls::pfunc = 0;
//; $tls::saved_errno = -3984; //; $tls::saved_errno = -4024;
//; $tls::psaved_errno = 4; //; $tls::psaved_errno = 4;
//; $tls::sa_flags = -3980; //; $tls::sa_flags = -4020;
//; $tls::psa_flags = 8; //; $tls::psa_flags = 8;
//; $tls::oldmask = -3976; //; $tls::oldmask = -4016;
//; $tls::poldmask = 12; //; $tls::poldmask = 12;
//; $tls::deltamask = -3972; //; $tls::deltamask = -4012;
//; $tls::pdeltamask = 16; //; $tls::pdeltamask = 16;
//; $tls::event = -3968; //; $tls::event = -4008;
//; $tls::pevent = 20; //; $tls::pevent = 20;
//; $tls::errno_addr = -3964; //; $tls::errno_addr = -4004;
//; $tls::perrno_addr = 24; //; $tls::perrno_addr = 24;
//; $tls::initialized = -3960; //; $tls::initialized = -4000;
//; $tls::pinitialized = 28; //; $tls::pinitialized = 28;
//; $tls::sigmask = -3956; //; $tls::sigmask = -3996;
//; $tls::psigmask = 32; //; $tls::psigmask = 32;
//; $tls::sigwait_mask = -3952; //; $tls::sigwait_mask = -3992;
//; $tls::psigwait_mask = 36; //; $tls::psigwait_mask = 36;
//; $tls::sigwait_info = -3948; //; $tls::sigwait_info = -3988;
//; $tls::psigwait_info = 40; //; $tls::psigwait_info = 40;
//; $tls::threadkill = -3944; //; $tls::threadkill = -3984;
//; $tls::pthreadkill = 44; //; $tls::pthreadkill = 44;
//; $tls::infodata = -3940; //; $tls::infodata = -3980;
//; $tls::pinfodata = 48; //; $tls::pinfodata = 48;
//; $tls::tid = -3792; //; $tls::tid = -3832;
//; $tls::ptid = 196; //; $tls::ptid = 196;
//; $tls::local_clib = -3788; //; $tls::local_clib = -3828;
//; $tls::plocal_clib = 200; //; $tls::plocal_clib = 200;
//; $tls::__dontuse = -3788; //; $tls::__dontuse = -3828;
//; $tls::p__dontuse = 200; //; $tls::p__dontuse = 200;
//; $tls::locals = -2724; //; $tls::locals = -2764;
//; $tls::plocals = 1264; //; $tls::plocals = 1264;
//; $tls::_ctinfo = -1092; //; $tls::_ctinfo = -1132;
//; $tls::p_ctinfo = 2896; //; $tls::p_ctinfo = 2896;
//; $tls::el = -1128;
//; $tls::pel = 2900;
//; $tls::andreas = -1088; //; $tls::andreas = -1088;
//; $tls::pandreas = 2900; //; $tls::pandreas = 2940;
//; $tls::wq = -1080; //; $tls::wq = -1080;
//; $tls::pwq = 2908; //; $tls::pwq = 2948;
//; $tls::prev = -1052; //; $tls::prev = -1052;
//; $tls::pprev = 2936; //; $tls::pprev = 2976;
//; $tls::next = -1048; //; $tls::next = -1048;
//; $tls::pnext = 2940; //; $tls::pnext = 2980;
//; $tls::stackptr = -1044; //; $tls::stackptr = -1044;
//; $tls::pstackptr = 2944; //; $tls::pstackptr = 2984;
//; $tls::sig = -1040; //; $tls::sig = -1040;
//; $tls::psig = 2948; //; $tls::psig = 2988;
//; $tls::incyg = -1036; //; $tls::incyg = -1036;
//; $tls::pincyg = 2952; //; $tls::pincyg = 2992;
//; $tls::spinning = -1032; //; $tls::spinning = -1032;
//; $tls::pspinning = 2956; //; $tls::pspinning = 2996;
//; $tls::stacklock = -1028; //; $tls::stacklock = -1028;
//; $tls::pstacklock = 2960; //; $tls::pstacklock = 3000;
//; $tls::stack = -1024; //; $tls::stack = -1024;
//; $tls::pstack = 2964; //; $tls::pstack = 3004;
//; $tls::padding = 0; //; $tls::padding = 0;
//; $tls::ppadding = 3988; //; $tls::ppadding = 4028;
//; __DATA__ //; __DATA__
#define tls_func (-3988) #define tls_func (-4028)
#define tls_pfunc (0) #define tls_pfunc (0)
#define tls_saved_errno (-3984) #define tls_saved_errno (-4024)
#define tls_psaved_errno (4) #define tls_psaved_errno (4)
#define tls_sa_flags (-3980) #define tls_sa_flags (-4020)
#define tls_psa_flags (8) #define tls_psa_flags (8)
#define tls_oldmask (-3976) #define tls_oldmask (-4016)
#define tls_poldmask (12) #define tls_poldmask (12)
#define tls_deltamask (-3972) #define tls_deltamask (-4012)
#define tls_pdeltamask (16) #define tls_pdeltamask (16)
#define tls_event (-3968) #define tls_event (-4008)
#define tls_pevent (20) #define tls_pevent (20)
#define tls_errno_addr (-3964) #define tls_errno_addr (-4004)
#define tls_perrno_addr (24) #define tls_perrno_addr (24)
#define tls_initialized (-3960) #define tls_initialized (-4000)
#define tls_pinitialized (28) #define tls_pinitialized (28)
#define tls_sigmask (-3956) #define tls_sigmask (-3996)
#define tls_psigmask (32) #define tls_psigmask (32)
#define tls_sigwait_mask (-3952) #define tls_sigwait_mask (-3992)
#define tls_psigwait_mask (36) #define tls_psigwait_mask (36)
#define tls_sigwait_info (-3948) #define tls_sigwait_info (-3988)
#define tls_psigwait_info (40) #define tls_psigwait_info (40)
#define tls_threadkill (-3944) #define tls_threadkill (-3984)
#define tls_pthreadkill (44) #define tls_pthreadkill (44)
#define tls_infodata (-3940) #define tls_infodata (-3980)
#define tls_pinfodata (48) #define tls_pinfodata (48)
#define tls_tid (-3792) #define tls_tid (-3832)
#define tls_ptid (196) #define tls_ptid (196)
#define tls_local_clib (-3788) #define tls_local_clib (-3828)
#define tls_plocal_clib (200) #define tls_plocal_clib (200)
#define tls___dontuse (-3788) #define tls___dontuse (-3828)
#define tls_p__dontuse (200) #define tls_p__dontuse (200)
#define tls_locals (-2724) #define tls_locals (-2764)
#define tls_plocals (1264) #define tls_plocals (1264)
#define tls__ctinfo (-1092) #define tls__ctinfo (-1132)
#define tls_p_ctinfo (2896) #define tls_p_ctinfo (2896)
#define tls_el (-1128)
#define tls_pel (2900)
#define tls_andreas (-1088) #define tls_andreas (-1088)
#define tls_pandreas (2900) #define tls_pandreas (2940)
#define tls_wq (-1080) #define tls_wq (-1080)
#define tls_pwq (2908) #define tls_pwq (2948)
#define tls_prev (-1052) #define tls_prev (-1052)
#define tls_pprev (2936) #define tls_pprev (2976)
#define tls_next (-1048) #define tls_next (-1048)
#define tls_pnext (2940) #define tls_pnext (2980)
#define tls_stackptr (-1044) #define tls_stackptr (-1044)
#define tls_pstackptr (2944) #define tls_pstackptr (2984)
#define tls_sig (-1040) #define tls_sig (-1040)
#define tls_psig (2948) #define tls_psig (2988)
#define tls_incyg (-1036) #define tls_incyg (-1036)
#define tls_pincyg (2952) #define tls_pincyg (2992)
#define tls_spinning (-1032) #define tls_spinning (-1032)
#define tls_pspinning (2956) #define tls_pspinning (2996)
#define tls_stacklock (-1028) #define tls_stacklock (-1028)
#define tls_pstacklock (2960) #define tls_pstacklock (3000)
#define tls_stack (-1024) #define tls_stack (-1024)
#define tls_pstack (2964) #define tls_pstack (3004)
#define tls_padding (0) #define tls_padding (0)
#define tls_ppadding (3988) #define tls_ppadding (4028)