* exception.h: Fold in content of include/exceptions.h.
* include/exceptions.h: Remove.
This commit is contained in:
		| @@ -1,3 +1,8 @@ | |||||||
|  | 2013-10-27  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* exception.h: Fold in content of include/exceptions.h. | ||||||
|  | 	* include/exceptions.h: Remove. | ||||||
|  |  | ||||||
| 2013-10-26  Corinna Vinschen  <corinna@vinschen.de> | 2013-10-26  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* devices.in (dev_storage): Map /dev/dsp to \Device\Null. | 	* devices.in (dev_storage): Map /dev/dsp to \Device\Null. | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| /* exception.h | /* 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 | This software is a copyrighted work licensed under the terms of the | ||||||
| Cygwin license.  Please consult the file "CYGWIN_LICENSE" for | Cygwin license.  Please consult the file "CYGWIN_LICENSE" for | ||||||
| @@ -8,11 +9,102 @@ details. */ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <exceptions.h> |  | ||||||
|  |  | ||||||
| #ifndef __x86_64__ | #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 <onno@stack.urc.tue.nl> | ||||||
|  |  | ||||||
|  | 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"); | extern exception_list *_except_list asm ("%fs:0"); | ||||||
| #endif | #endif /* !__x86_64 */ | ||||||
|  |  | ||||||
| class exception | class exception | ||||||
| { | { | ||||||
| @@ -23,7 +115,7 @@ class exception | |||||||
|   exception_list el; |   exception_list el; | ||||||
|   exception_list *save; |   exception_list *save; | ||||||
|   static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *); |   static int handle (EXCEPTION_RECORD *, exception_list *, CONTEXT *, void *); | ||||||
| #endif | #endif /* __x86_64__ */ | ||||||
| public: | public: | ||||||
|   exception () __attribute__ ((always_inline)) |   exception () __attribute__ ((always_inline)) | ||||||
|   { |   { | ||||||
| @@ -43,11 +135,11 @@ public: | |||||||
|     el.handler = handle; |     el.handler = handle; | ||||||
|     el.prev = _except_list; |     el.prev = _except_list; | ||||||
|     _except_list = ⪙ |     _except_list = ⪙ | ||||||
| #endif | #endif /* __x86_64__ */ | ||||||
|   }; |   }; | ||||||
| #ifndef __x86_64__ | #ifndef __x86_64__ | ||||||
|   ~exception () __attribute__ ((always_inline)) { _except_list = save; } |   ~exception () __attribute__ ((always_inline)) { _except_list = save; } | ||||||
| #endif | #endif /* !__x86_64__ */ | ||||||
| }; | }; | ||||||
|  |  | ||||||
| class cygwin_exception | class cygwin_exception | ||||||
|   | |||||||
| @@ -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 <onno@stack.urc.tue.nl> |  | ||||||
|  |  | ||||||
| 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 */ |  | ||||||
| @@ -11,6 +11,9 @@ What changed: | |||||||
|   Right now this excludes console windows on pre Windows 8, as well as almost |   Right now this excludes console windows on pre Windows 8, as well as almost | ||||||
|   all virtual files under /proc. |   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: | Bug fixes: | ||||||
| ---------- | ---------- | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user