From: <dan...@us...> - 2007-08-05 10:20:49
|
Revision: 1040 http://cegcc.svn.sourceforge.net/cegcc/?rev=1040&view=rev Author: dannybackx Date: 2007-08-05 03:20:47 -0700 (Sun, 05 Aug 2007) Log Message: ----------- This is the support for the __exception_handler__ attribute. Code as originally posted on the list has been changed as Pedro suggested. 2007-08-05 Danny Backx <dan...@us...> * c-common.c (handle_exception_handler_attribute) : Add new handler to support the __exception_handler__ attribute. * config/arm/arm.c (arm_exception_handler) : Add function to query the structures built by the compiler for the exception handler for the function that we're currently generating code for. * config/arm/wince-pe.h (ASM_DECLARE_FUNCTION_NAME) : Add macro to generate function header including an exception handler spec and an entry in the .pdata segment, call the one in pe.h to reuse the existing code. * config/arm/wince-pe.h (ASM_DECLARE_FUNCTION_SIZE) : Add macro to generate function trailer (one additional local label) so we can do a size calculation. * config/arm/pe.h (ASM_DECLARE_FUNCTION_NAME) : Rename to ARM_PE_DECLARE_FUNCTION_NAME so it can be called from ASM_DECLARE_FUNCTION_NAME in config/arm/wince-pe.h . Code reuse instead of code duplication. Modified Paths: -------------- trunk/cegcc/src/gcc/gcc/ChangeLog.ce trunk/cegcc/src/gcc/gcc/c-common.c trunk/cegcc/src/gcc/gcc/config/arm/arm.c trunk/cegcc/src/gcc/gcc/config/arm/pe.h trunk/cegcc/src/gcc/gcc/config/arm/wince-pe.h Modified: trunk/cegcc/src/gcc/gcc/ChangeLog.ce =================================================================== --- trunk/cegcc/src/gcc/gcc/ChangeLog.ce 2007-08-01 00:04:32 UTC (rev 1039) +++ trunk/cegcc/src/gcc/gcc/ChangeLog.ce 2007-08-05 10:20:47 UTC (rev 1040) @@ -197,3 +197,23 @@ * config/arm/t-wince-cegcc: Make it empty, we now inherit the generic t-wince-pe. * ChangeLog.ce: New file. + +2007-08-05 Danny Backx <dan...@us...> + + * c-common.c (handle_exception_handler_attribute) : Add new handler to + support the __exception_handler__ attribute. + * config/arm/arm.c (arm_exception_handler) : Add function to query the + structures built by the compiler for the exception handler for the + function that we're currently generating code for. + * config/arm/wince-pe.h (ASM_DECLARE_FUNCTION_NAME) : Add macro to + generate function header including an exception handler spec and an + entry in the .pdata segment, call the one in pe.h to reuse the + existing code. + * config/arm/wince-pe.h (ASM_DECLARE_FUNCTION_SIZE) : Add macro to + generate function trailer (one additional local label) so we can do a + size calculation. + * config/arm/pe.h (ASM_DECLARE_FUNCTION_NAME) : Rename to + ARM_PE_DECLARE_FUNCTION_NAME so it can be called from + ASM_DECLARE_FUNCTION_NAME in config/arm/wince-pe.h . Code reuse + instead of code duplication. + Modified: trunk/cegcc/src/gcc/gcc/c-common.c =================================================================== --- trunk/cegcc/src/gcc/gcc/c-common.c 2007-08-01 00:04:32 UTC (rev 1039) +++ trunk/cegcc/src/gcc/gcc/c-common.c 2007-08-05 10:20:47 UTC (rev 1040) @@ -505,6 +505,8 @@ static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); static tree handle_always_inline_attribute (tree *, tree, tree, int, bool *); +static tree handle_exception_handler_attribute (tree *, tree, tree, int, + bool *); static tree handle_flatten_attribute (tree *, tree, tree, int, bool *); static tree handle_used_attribute (tree *, tree, tree, int, bool *); static tree handle_unused_attribute (tree *, tree, tree, int, bool *); @@ -633,6 +635,8 @@ handle_cleanup_attribute }, { "warn_unused_result", 0, 0, false, true, true, handle_warn_unused_result_attribute }, + { "exception_handler", 1, 1, true, false, false, + handle_exception_handler_attribute }, { "sentinel", 0, 1, false, true, true, handle_sentinel_attribute }, { NULL, 0, 0, false, false, false, NULL } @@ -4216,6 +4220,59 @@ return NULL_TREE; } +/* + * Handle a "exception_handler" attribute. + * + * One argument is required : the name of a function to call in case of exceptions. + * Example syntax : + * + * int main(int argc, char *argv[]) + * __attribute__((__exception_handler__(handler))); + */ + +static tree +handle_exception_handler_attribute (tree *node, tree name, + tree args, + int ARG_UNUSED (flags), + bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + { + /* + * We need to pass the name of the exception handler. The + * right code then gets generated from config/arm/mingw32.h + * or similar, the assembler and linker will do the hard work. + * + * FIX ME We don't support passing data to the exception handler. + * + * This should be possible though, by using an additional argument + * which needs to fit in the dword (e.g. a pointer) and storing that + * in the right field as we do with the exception handler. + */ + + /* Handle mode attribute, handle_section_attribute, .. use args */ + tree id = TREE_VALUE (args); + tree attr = NULL_TREE; + +#if 1 + attr = tree_cons (get_identifier ("exception_handler"), args, attr); +#else + /* Works too */ + const char *x = IDENTIFIER_POINTER(id); + + attr = tree_cons (get_identifier ("exception_handler"), + build_string (strlen (x), x), attr); +#endif + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle a "flatten" attribute; arguments as in struct attribute_spec.handler. */ Modified: trunk/cegcc/src/gcc/gcc/config/arm/arm.c =================================================================== --- trunk/cegcc/src/gcc/gcc/config/arm/arm.c 2007-08-01 00:04:32 UTC (rev 1039) +++ trunk/cegcc/src/gcc/gcc/config/arm/arm.c 2007-08-05 10:20:47 UTC (rev 1040) @@ -15553,4 +15553,28 @@ return (insn_flags & FL_THUMB) == FL_THUMB; } +/* + * called from ASM_DECLARE_FUNCTION_NAME in gcc/config/arm/wince-pe.h + */ +char * +arm_exception_handler (FILE *fp, char *name, tree decl) +{ + tree attr, a2; + + attr = DECL_ATTRIBUTES (decl); + if (! attr) + return NULL; + a2 = lookup_attribute ("__exception_handler__", attr); + if (! a2) + return NULL; + if (a2) + { + return IDENTIFIER_POINTER (TREE_VALUE (TREE_VALUE (a2))); + } + + warning (0, "exception handler information not found for function %s", + name); + return NULL; +} + #include "gt-arm.h" Modified: trunk/cegcc/src/gcc/gcc/config/arm/pe.h =================================================================== --- trunk/cegcc/src/gcc/gcc/config/arm/pe.h 2007-08-01 00:04:32 UTC (rev 1039) +++ trunk/cegcc/src/gcc/gcc/config/arm/pe.h 2007-08-05 10:20:47 UTC (rev 1040) @@ -117,8 +117,11 @@ /* Write the extra assembler code needed to declare a function properly. If we are generating SDB debugging information, this will happen automatically, so we only need to handle other cases. */ -#undef ASM_DECLARE_FUNCTION_NAME -#define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \ +/* Give this another name so more sub-architectures can overrule ARM_DECLARE_FUNCTION_NAME + * and still call ARM_PE_DECLARE_FUNCTION_NAME. The alternative is to duplicate the code + * below to the sub-architectures, that's a bad idea. + * This is currently done in wince-pe.h . */ +#define ARM_PE_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \ do \ { \ if (arm_pe_dllexport_name_p (NAME)) \ @@ -132,6 +135,9 @@ } \ while (0) +#undef ASM_DECLARE_FUNCTION_NAME +#define ASM_DECLARE_FUNCTION_NAME ARM_PE_DECLARE_FUNCTION_NAME + /* Output function declarations at the end of the file. */ #undef TARGET_ASM_FILE_END #define TARGET_ASM_FILE_END arm_pe_file_end Modified: trunk/cegcc/src/gcc/gcc/config/arm/wince-pe.h =================================================================== --- trunk/cegcc/src/gcc/gcc/config/arm/wince-pe.h 2007-08-01 00:04:32 UTC (rev 1039) +++ trunk/cegcc/src/gcc/gcc/config/arm/wince-pe.h 2007-08-05 10:20:47 UTC (rev 1040) @@ -234,3 +234,48 @@ #ifndef BUFSIZ # undef FILE #endif + +/* + * An ARM specific header for function declarations. + * + * This one is needed for exception handlers : the entry in the pdata section + * needs to know the size of the function for which we handle exceptions. + */ +#undef ASM_DECLARE_FUNCTION_NAME +#define ASM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \ + do \ + { \ + char *eh; \ + eh = arm_exception_handler(STREAM, NAME, DECL); \ + if (eh) \ + { \ + asm_fprintf (STREAM, "%@ %s has exception handler %s\n", \ + NAME, eh); \ + asm_fprintf (STREAM, "\t.section .pdata\n"); \ + asm_fprintf (STREAM, "\t.word %s\n", NAME); \ + asm_fprintf (STREAM, "\t.word 0xc0000002 | " \ + "((((.L%s_end - %s) / 4) & 0x3ffffff) << 8) " \ + "/* _cegcc_%s size */\n", NAME, NAME, NAME); \ + asm_fprintf (STREAM, "\t.text\n"); \ + asm_fprintf (STREAM, ".L%s_data:\n", NAME); \ + asm_fprintf (STREAM, "\t.word %s /* .L%s_handler */\n", \ + eh, NAME); \ + asm_fprintf (STREAM, "\t.word 0 /* .L%s_handler_data */\n", \ + NAME); \ + } \ + ARM_PE_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL); \ + } \ + while (0) + +/* + * An ARM specific trailer for function declarations. + * + * This one is needed for exception handlers : the entry in the pdata section + * needs to know the size of the function for which we handle exceptions. + */ +#undef ASM_DECLARE_FUNCTION_SIZE +#define ASM_DECLARE_FUNCTION_SIZE(STREAM, NAME, DECL) \ + { \ + if (arm_exception_handler(STREAM, NAME, DECL)) \ + asm_fprintf (STREAM, ".L%s_end:\n", NAME); \ + } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |