| SEH exceptions for GCC |
| Écrit par Vincent Richomme | |
| 16-01-2009 | |
|
Nom: mingw-seh This project aimed at implementing "table-based" SEH exception handling inside GCC(4.1.2) compiler. In a first step we will focus on the simplest plateform (ARM) to implement it. To understand how it works on arm platforms you can have a detailed article here .To give a general idea seh exceptions rely on two important keywords __try and __except as shown below : int _tmain(int argc, _TCHAR* argv[]) { __try { INS_TRY; } __except(INS_FILTER) { INS_EXCEPT; } INS_AFTER_EXCEPT; } Please note that __except( ) can hold either an expression like this : __try { } __except( puts("in filter"), EXCEPTION_EXECUTE_HANDLER ) { } or directly a filter function : int filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) { puts("in filter."); if (code == EXCEPTION_ACCESS_VIOLATION) { puts("caught AV as expected."); return EXCEPTION_EXECUTE_HANDLER; } else { puts("didn't catch AV, unexpected."); return EXCEPTION_CONTINUE_SEARCH; }; } __try { } __except( filter(GetExceptionCode(), GetExceptionInformation()) ) { } Basically SEH implementation will consist in a few steps : 1) Parse __try __except or __try __finally keywords 2) Mark block holding code for __try and __except 3) if except filter is an expression, put its statements into an anonymous function 4) Generate labels corresponding to __try, __except and filter begin and end to be able to generate SCOPETABLE. Step1 : Add support for parsing __try __except We first need to add enum for our new keywords __try , __except and __finally Index: gcc/gcc/c-common.h =================================================================== --- gcc/gcc/c-common.h (revision 183) +++ gcc/gcc/c-common.h (working copy) @@ -72,6 +72,7 @@ RID_ASM, RID_TYPEOF, RID_ALIGNOF, RID_ATTRIBUTE, RID_VA_ARG, RID_EXTENSION, RID_IMAGPART, RID_REALPART, RID_LABEL, RID_CHOOSE_EXPR, RID_TYPES_COMPATIBLE_P, + RID_SEH_TRY, RID_SEH_EXCEPT, RID_SEH_FINALLY, /* Too many ways of getting the name of a function as a string */ RID_FUNCTION_NAME, RID_PRETTY_FUNCTION_NAME, RID_C99_FUNCTION_NAME, and then the intersting part for us seems to be done in gcc/gcc/c-parser.c in function c_parser_statement_after_labels where we could add RID_SEH_TRY case : /* Parse a statement, other than a labeled statement. */ static void c_parser_statement_after_labels (c_parser *parser) { ... case RID_SEH_TRY: c_parser_seh_try_catch_statement (parser); break; case RID_ASM: stmt = c_parser_asm_statement (parser); break; ... } /* Parse a SEH exception statement. seh-statement: __try statement __except (expression) statement __try statement __finally statement */ static void c_parser_seh_try_catch_statement (c_parser *parser) { // fprintf(stderr, "c_parser_seh_try_catch_statement()\n"); location_t loc; tree stmt; gcc_assert (c_parser_next_token_is_keyword (parser, RID_SEH_TRY)); c_parser_consume_token (parser); loc = c_parser_peek_token (parser)->location; ... } |
| < Précédent | Suivant > |
|---|

