X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Flibgcc2.c;h=c32a7e03fa26d1ea45a784e10e0cb695555598a4;hb=9238bd6d3140e42e78f067948d12c288054a5cd3;hp=9fcd17eb58e6544e66c3d5e3344e51a776c6c9e6;hpb=73e44b25c16b40c281bb458e870ab5f423fe8085;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c index 9fcd17eb58e..c32a7e03fa2 100644 --- a/gcc/libgcc2.c +++ b/gcc/libgcc2.c @@ -1483,7 +1483,7 @@ __bb_exit_func (void) /* If the file exists, and the number of counts in it is the same, then merge them in. */ - if ((da_file = fopen (ptr->filename, "r")) != NULL) + if ((da_file = fopen (ptr->filename, "r")) != 0) { long n_counts = 0; unsigned char tmp; @@ -1815,8 +1815,8 @@ gopen (char *fn, char *mode) return (FILE *) 0; p = fn + strlen (fn)-1; - use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z')) || - (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z')); + use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z')) + || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z')); if (use_gzip) { @@ -1855,7 +1855,7 @@ gclose (FILE *f) { struct stat buf; - if (f != NULL) + if (f != 0) { if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode)) return pclose (f); @@ -2195,15 +2195,15 @@ __bb_trace_func () { struct bb_edge **startbucket, **oldnext; - oldnext = startbucket = - & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ]; + oldnext = startbucket + = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ]; bucket = *startbucket; for (bucket = *startbucket; bucket; oldnext = &(bucket->next), bucket = *oldnext) { - if ( bucket->src_addr == bb_src && - bucket->dst_addr == bb_dst ) + if (bucket->src_addr == bb_src + && bucket->dst_addr == bb_dst) { bucket->count++; *oldnext = bucket->next; @@ -2258,15 +2258,15 @@ __bb_trace_func_ret () { struct bb_edge **startbucket, **oldnext; - oldnext = startbucket = - & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ]; + oldnext = startbucket + = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ]; bucket = *startbucket; for (bucket = *startbucket; bucket; oldnext = &(bucket->next), bucket = *oldnext) { - if ( bucket->src_addr == bb_dst && - bucket->dst_addr == bb_src ) + if (bucket->src_addr == bb_dst + && bucket->dst_addr == bb_src) { bucket->count++; *oldnext = bucket->next; @@ -2321,8 +2321,8 @@ __bb_init_file (struct bb *blocks) bb_head = blocks; blocks->flags = 0; - if (!bb_func_head || - !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts))) + if (!bb_func_head + || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts))) return; for (blk = 0; blk < ncounts; blk++) @@ -2332,8 +2332,8 @@ __bb_init_file (struct bb *blocks) { for (p = bb_func_head; p; p = p->next) { - if (!strcmp (p->funcname, functions[blk]) && - (!p->filename || !strcmp (p->filename, blocks->filename))) + if (!strcmp (p->funcname, functions[blk]) + && (!p->filename || !strcmp (p->filename, blocks->filename))) { blocks->flags[blk] |= p->mode; } @@ -3022,7 +3022,7 @@ int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */ #ifdef NEED_ATEXIT # include -static func_ptr *atexit_chain = NULL; +static func_ptr *atexit_chain = 0; static long atexit_chain_length = 0; static volatile long last_atexit_chain_slot = -1; @@ -3032,10 +3032,11 @@ int atexit (func_ptr func) { atexit_chain_length += 32; if (atexit_chain) - atexit_chain = realloc (atexit_chain, - atexit_chain_length * sizeof (func_ptr)); + atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length + * sizeof (func_ptr)); else - atexit_chain = malloc (atexit_chain_length * sizeof (func_ptr)); + atexit_chain = (func_ptr *) malloc (atexit_chain_length + * sizeof (func_ptr)); if (! atexit_chain) { atexit_chain_length = 0; @@ -3068,10 +3069,10 @@ exit (int status) for ( ; last_atexit_chain_slot-- >= 0; ) { (*atexit_chain[last_atexit_chain_slot + 1]) (); - atexit_chain[last_atexit_chain_slot + 1] = NULL; + atexit_chain[last_atexit_chain_slot + 1] = 0; } free (atexit_chain); - atexit_chain = NULL; + atexit_chain = 0; } #else /* No NEED_ATEXIT */ __do_global_dtors (); @@ -3102,6 +3103,180 @@ EH_TABLE_LOOKUP #else +void +__default_terminate () +{ + abort (); +} + +void (*__terminate_func)() = __default_terminate; + +void +__terminate () +{ + (*__terminate_func)(); +} + +/* Calls to __sjthrow are generated by the compiler when an exception + is raised when using the setjmp/longjmp exception handling codegen + method. */ + +extern void longjmp (void *, int); + +extern void *__eh_type; + +static void *top_elt[2]; +void **__dynamic_handler_chain = top_elt; + +/* Routine to get the head of the current thread's dynamic handler chain + use for exception handling. + + TODO: make thread safe. */ + +void *** +__get_dynamic_handler_chain () +{ + return &__dynamic_handler_chain; +} + +/* This is used to throw an exception when the setjmp/longjmp codegen + method is used for exception handling. + + We call __terminate if there are no handlers left (we know this + when the dynamic handler chain is top_elt). Otherwise we run the + cleanup actions off the dynamic cleanup stack, and pop the top of + the dynamic handler chain, and use longjmp to transfer back to the + associated handler. */ + +void +__sjthrow () +{ + void ***dhc = __get_dynamic_handler_chain (); + void *jmpbuf; + void (*func)(void *, int); + void *arg; + void ***cleanup; + + /* The cleanup chain is one word into the buffer. Get the cleanup + chain. */ + cleanup = (void***)&(*dhc)[1]; + + /* If there are any cleanups in the chain, run them now. */ + if (cleanup[0]) + { + double store[200]; + void **buf = (void**)store; + buf[1] = 0; + buf[0] = (*dhc); + + /* try { */ +#ifdef DONT_USE_BUILTIN_SETJMP + if (! setjmp (&buf[2])) +#else + if (! __builtin_setjmp (&buf[2])) +#endif + { + *dhc = buf; + while (cleanup[0]) + { + func = (void(*)(void*, int))cleanup[0][1]; + arg = (void*)cleanup[0][2]; + + /* Update this before running the cleanup. */ + cleanup[0] = (void **)cleanup[0][0]; + + (*func)(arg, 2); + } + *dhc = buf[0]; + } + /* catch (...) */ + else + { + __terminate (); + } + } + + /* We must call terminate if we try and rethrow an exception, when + there is no exception currently active and when there are no + handlers left. */ + if (! __eh_type || (*dhc) == top_elt) + __terminate (); + + /* Find the jmpbuf associated with the top element of the dynamic + handler chain. The jumpbuf starts two words into the buffer. */ + jmpbuf = &(*dhc)[2]; + + /* Then we pop the top element off the dynamic handler chain. */ + *dhc = (void**)(*dhc)[0]; + + /* And then we jump to the handler. */ + +#ifdef DONT_USE_BUILTIN_SETJMP + longjmp (jmpbuf, 1); +#else + __builtin_longjmp (jmpbuf, 1); +#endif +} + +/* Run cleanups on the dynamic cleanup stack for the current dynamic + handler, then pop the handler off the dynamic handler stack, and + then throw. This is used to skip the first handler, and transfer + control to the next handler in the dynamic handler stack. */ + +void +__sjpopnthrow () +{ + void ***dhc = __get_dynamic_handler_chain (); + void *jmpbuf; + void (*func)(void *, int); + void *arg; + void ***cleanup; + + /* The cleanup chain is one word into the buffer. Get the cleanup + chain. */ + cleanup = (void***)&(*dhc)[1]; + + /* If there are any cleanups in the chain, run them now. */ + if (cleanup[0]) + { + double store[200]; + void **buf = (void**)store; + buf[1] = 0; + buf[0] = (*dhc); + + /* try { */ +#ifdef DONT_USE_BUILTIN_SETJMP + if (! setjmp (&buf[2])) +#else + if (! __builtin_setjmp (&buf[2])) +#endif + { + *dhc = buf; + while (cleanup[0]) + { + func = (void(*)(void*, int))cleanup[0][1]; + arg = (void*)cleanup[0][2]; + + /* Update this before running the cleanup. */ + cleanup[0] = (void **)cleanup[0][0]; + + (*func)(arg, 2); + } + *dhc = buf[0]; + } + /* catch (...) */ + else + { + __terminate (); + } + } + + /* Then we pop the top element off the dynamic handler chain. */ + *dhc = (void**)(*dhc)[0]; + + __sjthrow (); +} + typedef struct { void *start; void *end; @@ -3261,6 +3436,16 @@ __throw () void *__eh_pc; +/* See expand_builtin_throw for details. */ + +void **__eh_ffetmnpc () { + static void *buf[2] = { + &__find_first_exception_table_match, + &__eh_pc + }; + return buf; +} + void __empty () {