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>2005-12-03 07:23:35 +0300
committerChristopher Faylor <me@cgf.cx>2005-12-03 07:23:35 +0300
commitf153e6b2804f06315d748bd1c8cad9f76798db09 (patch)
tree0ca55fa4e5dbf0332d9a3d587104236d51b1fb59 /winsup/cygwin/exceptions.cc
parente7f6a31bb07e96eed5ffb7b8d137051292532930 (diff)
* 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.
Diffstat (limited to 'winsup/cygwin/exceptions.cc')
-rw-r--r--winsup/cygwin/exceptions.cc80
1 files changed, 36 insertions, 44 deletions
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index bc0ea739a..9851183fc 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -36,7 +36,6 @@ details. */
char debugger_command[2 * CYG_MAX_PATH + 20];
extern "C" {
-static int handle_exceptions (EXCEPTION_RECORD *, void *, CONTEXT *, void *);
extern void sigdelayed ();
};
@@ -94,28 +93,6 @@ NO_COPY static struct
/* 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
dummy_ctrl_c_handler (DWORD dwCtrlType)
{
@@ -403,11 +380,31 @@ try_to_debug (bool waitloop)
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. */
-extern "C" DWORD __stdcall RtlUnwind (void *, void *, void *, DWORD);
-static int
-handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
+int
+_cygtls::handle_exceptions (EXCEPTION_RECORD *e, void *frame, CONTEXT *in, void *)
{
static bool NO_COPY debugging;
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
tells Windows to keep looking for an exception handler. */
- if (exit_already)
+ if (exit_already || e->ExceptionFlags)
return 1;
- EXCEPTION_RECORD e = *e0;
- CONTEXT in = *in0;
-
siginfo_t si;
si.si_code = SI_KERNEL;
/* Coerce win32 value to posix value. */
- switch (e.ExceptionCode)
+ switch (e->ExceptionCode)
{
case STATUS_FLOAT_DENORMAL_OPERAND:
case STATUS_FLOAT_DIVIDE_BY_ZERO:
@@ -514,8 +508,9 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
return 1;
}
- 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);
+ rtl_unwind (frame, e);
+ 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))
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",
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--)
- if (*ebp == in.SegCs && ebp[-1] == in.Eip)
+ if (*ebp == in->SegCs && ebp[-1] == in->Eip)
{
ebp -= 2;
break;
@@ -534,7 +529,7 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
if (!me.fault_guarded ()
&& (!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_IGN
|| (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 */
if (!myself->cygstarted)
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);
break;
@@ -561,25 +556,22 @@ handle_exceptions (EXCEPTION_RECORD *e0, void *frame, CONTEXT *in0, void *)
}
open_stackdumpfile ();
- exception (&e, &in);
+ exception (e, in);
stackdump ((DWORD) ebp, 0, 1);
}
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 ())
me.return_from_fault ();
- si.si_addr = ebp;
+ si.si_addr = (void *) in->Eip;
si.si_errno = si.si_pid = si.si_uid = 0;
me.push ((__stack_t) ebp, true);
sig_send (NULL, si, &me); // Signal myself
- return 1;
+ e->ExceptionFlags = 0;
+ return 0;
}
/* Utilities to call a user supplied exception handler. */