diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 5ff53ed53..7d4a6d30b 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,8 @@ +2013-10-27 Corinna Vinschen + + * exception.h: Fold in content of include/exceptions.h. + * include/exceptions.h: Remove. + 2013-10-26 Corinna Vinschen * devices.in (dev_storage): Map /dev/dsp to \Device\Null. diff --git a/winsup/cygwin/exception.h b/winsup/cygwin/exception.h index 8981c241b..9c64f3883 100644 --- a/winsup/cygwin/exception.h +++ b/winsup/cygwin/exception.h @@ -1,6 +1,7 @@ /* exception.h - Copyright 2010, 2011, 2012, 2013 Red Hat, Inc. + Copyright 1996, 1997, 1998, 2000, 2001, 2005, 2010, 2011, 1012, 2013 + Red Hat, Inc. This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for @@ -8,11 +9,102 @@ details. */ #pragma once -#include - #ifndef __x86_64__ +/* Documentation on the innards of 32 bit Windows exception handling (i.e. + from the perspective of a compiler implementor) apparently doesn't exist. + However, the following came from Onno Hovers + +The first pointer to the chain of handlers is in the thread environment block +at FS:[0]. This chain has the following format: + +typedef struct __EXCEPTION_FRAME +{ + struct __EXCEPTION_FRAME *Prev; /-* pointer to the previous frame *-/ + PEXCEPTION_HANDLER Handler; /-* handler function *-/ +} + +You register an exception handler in your compiler with this simple ASM +sequence: + PUSH _MyExceptionHandler + PUSH FS:[0] + MOV FS:[0],ESP +An exception frame MUST be on the stack! The frame may have more fields and +both Visual C++ and Borland C++ use more fields for themselves. + +When an exception occurs the system calls all handlers starting with the +handler at FS:0, and then the previous etc. until one handler returns +ExceptionContinueExecution, which is 0. If a handler does not want to handle +the exception it should just return ExceptionContinueSearch, which is 1. + +The handler has the following parameters: +ehandler ( + PEXCEPTION_RECORD erecord, + PEXCEPTION_FRAME myframe, + PCONTEXT context, /-* context before and after *-/ + PVOID dispatch) /-* something *-/ + +When a handler wants to handle the exception, it has some alternatives: + +-one is to do do something about the exception condition, like emulating +an invalid instruction, mapping memory where there was a page fault, etc. +If the handler wants to have the context of the thread that causes the +exception changed, it should make that change in the context passed to the +handler. + +-the second alternative is to call all exception handlers again, indicating +that you want them to clean up. This way all the __finally blocks get +executed. After doing that you change the context passed to the handler so +the code starts executing in the except block. For this purpose you could +call RtlUnwind. This (undocumented) function calls all exception handlers +up to but not including the exception frame passed to it. If NULL is passed +as exception frame RtlUnwind calls all exception handlers and then exits the +process. The parameters to RtlUnwind are: + +RtlUnwind ( + PEXCEPTION_FRAME endframe, + PVOID unusedEip, + PEXCEPTION_RECORD erecord, + DWORD returnEax) + +You should set unusedEip to the address where RtlUnwind should return like +this: + PUSH 0 + PUSH OFFSET ReturnUnwind + PUSH 0 + PUSH 0 + CALL RtlUnwind +ReturnUnwind: + ..... + +If no EXCEPTION_RECORD is passed, RtlUnwind makes a default exception +record. In any case, the ExceptionFlags part of this record has the +EH_UNWINDING (=2), flag set. (and EH_EXIT_UNWIND (=4), when NULL is passed as the end +frame.). + +The handler for a exception as well as a for unwinds may be executed in the +thread causing the exception, but may also be executed in another (special +exception) thread. So it is not wise to make any assumptions about that! + +As an alternative you may consider the SetUnhandledExceptionFilter API +to install your own exception filter. This one is documented. +*/ + +/* The January 1994 MSJ has an article entitled "Clearer, More Comprehensive + Error Processing with Win32 Structured Exception Handling". It goes into + a teensy bit of detail of the innards of exception handling (i.e. what we + have to do). */ + +typedef int (exception_handler) (EXCEPTION_RECORD *, struct _exception_list *, + CONTEXT *, void *); + +typedef struct _exception_list +{ + struct _exception_list *prev; + exception_handler *handler; +} exception_list; + extern exception_list *_except_list asm ("%fs:0"); -#endif +#endif /* !__x86_64 */ class exception { @@ -23,7 +115,7 @@ class exception exception_list el; exception_list *save; static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *); -#endif +#endif /* __x86_64__ */ public: exception () __attribute__ ((always_inline)) { @@ -43,11 +135,11 @@ public: el.handler = handle; el.prev = _except_list; _except_list = ⪙ -#endif +#endif /* __x86_64__ */ }; #ifndef __x86_64__ ~exception () __attribute__ ((always_inline)) { _except_list = save; } -#endif +#endif /* !__x86_64__ */ }; class cygwin_exception diff --git a/winsup/cygwin/include/exceptions.h b/winsup/cygwin/include/exceptions.h deleted file mode 100644 index 82f064285..000000000 --- a/winsup/cygwin/include/exceptions.h +++ /dev/null @@ -1,119 +0,0 @@ -/* exceptions.h - - Copyright 1996, 1997, 1998, 2000, 2001, 2005, 2013 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. */ - -#ifndef _EXCEPTIONS_H -#define _EXCEPTIONS_H - -#ifndef __x86_64__ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Documentation on the innards of exception handling (i.e. from the - perspective of a compiler implementor) apparently doesn't exist. Sigh. - However, the following came from Onno Hovers - -The first pointer to the chain of handlers is in the thread environment block -at FS:[0]. This chain has the following format: - -typedef struct __EXCEPTION_FRAME -{ - struct __EXCEPTION_FRAME *Prev; /-* pointer to the previous frame *-/ - PEXCEPTION_HANDLER Handler; /-* handler function *-/ -} - -You register an exception handler in your compiler with this simple ASM -sequence: - PUSH _MyExceptionHandler - PUSH FS:[0] - MOV FS:[0],ESP -An exception frame MUST be on the stack! The frame may have more fields and -both Visual C++ and Borland C++ use more fields for themselves. - -When an exception occurs the system calls all handlers starting with the -handler at FS:0, and then the previous etc. until one handler returns -ExceptionContinueExecution, which is 0. If a handler does not want to handle -the exception it should just return ExceptionContinueSearch, which is 1. - -The handler has the following parameters: -ehandler ( - PEXCEPTION_RECORD erecord, - PEXCEPTION_FRAME myframe, - PCONTEXT context, /-* context before and after *-/ - PVOID dispatch) /-* something *-/ - -When a handler wants to handle the exception, it has some alternatives: - --one is to do do something about the exception condition, like emulating -an invalid instruction, mapping memory where there was a page fault, etc. -If the handler wants to have the context of the thread that causes the -exception changed, it should make that change in the context passed to the -handler. - --the second alternative is to call all exception handlers again, indicating -that you want them to clean up. This way all the __finally blocks get -executed. After doing that you change the context passed to the handler so -the code starts executing in the except block. For this purpose you could -call RtlUnwind. This (undocumented) function calls all exception handlers -up to but not including the exception frame passed to it. If NULL is passed -as exception frame RtlUnwind calls all exception handlers and then exits the -process. The parameters to RtlUnwind are: - -RtlUnwind ( - PEXCEPTION_FRAME endframe, - PVOID unusedEip, - PEXCEPTION_RECORD erecord, - DWORD returnEax) - -You should set unusedEip to the address where RtlUnwind should return like -this: - PUSH 0 - PUSH OFFSET ReturnUnwind - PUSH 0 - PUSH 0 - CALL RtlUnwind -ReturnUnwind: - ..... - -If no EXCEPTION_RECORD is passed, RtlUnwind makes a default exception -record. In any case, the ExceptionFlags part of this record has the -EH_UNWINDING (=2), flag set. (and EH_EXIT_UNWIND (=4), when NULL is passed as the end -frame.). - -The handler for a exception as well as a for unwinds may be executed in the -thread causing the exception, but may also be executed in another (special -exception) thread. So it is not wise to make any assumptions about that! - -As an alternative you may consider the SetUnhandledExceptionFilter API -to install your own exception filter. This one is documented. -*/ - -/* The January 1994 MSJ has an article entitled "Clearer, More Comprehensive - Error Processing with Win32 Structured Exception Handling". It goes into - a teensy bit of detail of the innards of exception handling (i.e. what we - have to do). */ - -typedef int (exception_handler) (EXCEPTION_RECORD *, struct _exception_list *, - CONTEXT *, void *); - -typedef struct _exception_list -{ - struct _exception_list *prev; - exception_handler *handler; -} exception_list; - -#ifdef __cplusplus -}; -#endif /* __cplusplus */ - -#endif /* __x86_64__ */ - -#endif /* _EXCEPTIONS_H */ diff --git a/winsup/cygwin/release/1.7.26 b/winsup/cygwin/release/1.7.26 index b350703d0..e4aeecd89 100644 --- a/winsup/cygwin/release/1.7.26 +++ b/winsup/cygwin/release/1.7.26 @@ -11,6 +11,9 @@ What changed: Right now this excludes console windows on pre Windows 8, as well as almost all virtual files under /proc. +- The header /usr/include/exceptions.h, containing implementation details for + 32 bit Windows' exception handling only, has been removed. + Bug fixes: ----------