This is lib-exce.c in view mode; [Download] [Up]
/* terminate(), unexpected(), set_terminate(), set_unexpected() as well as the default terminate func and default unexpected func ====================================================================== */ typedef void (*vfp)(); void __default_terminate() { abort(); } void __default_unexpected() { __default_terminate(); } static vfp __terminate_func = __default_terminate; static vfp __unexpected_func = __default_unexpected; vfp set_terminate(func) vfp func; { vfp old = __terminate_func; __terminate_func = func; return old; } vfp set_unexpected(func) vfp func; { vfp old = __unexpected_func; __unexpected_func = func; return old; } void terminate() { __terminate_func(); } void unexpected() { __unexpected_func(); } /* ====================================================================== */ typedef struct { void *start; void *end; void *exception_handler; } exception_table; static int except_table_pos = 0; static void *except_pc = (void *)0; extern exception_table __EXCEPTION_TABLE__[]; /* this routine takes a pc, and the address of the exception handler associated with the closest exception table handler entry associated with that PC, or 0 if there are no table entries the PC fits in. The algorithm works something like this: while(current_entry exists) { if(current_entry.start < pc ) current_entry = next_entry; else { if(prev_entry.start <= pc && prev_entry.end > pc) { save pointer to prev_entry; return prev_entry.exception_handler; } else return 0; } } return 0; Assuming a correctly sorted table (ascending order) this routine should return the tighest match... In the advent of a tie, we have to give the last entry, as it represents an inner block. */ void * __find_first_exception_table_match(pc) void *pc; { extern int printf(...); exception_table *table = __EXCEPTION_TABLE__; int pos = 0; int best = 0; #if 0 printf("find_first_exception_table_match(): pc = %x!\n",pc); #endif except_pc = pc; #if 0 /* We can't do this yet, as we don't know that the table is sorted. */ do { ++pos; if (table[pos].start > except_pc) /* found the first table[pos].start > except_pc, so the previous entry better be the one we want! */ break; } while(table[pos].exception_handler != (void*)-1); --pos; if (table[pos].start <= except_pc && table[pos].end > except_pc) { except_table_pos = pos; #if 0 printf("find_first_eh_table_match(): found match: %x\n",table[pos].exception_handler); #endif return table[pos].exception_handler; } #else while (table[++pos].exception_handler != (void*)-1) { if (table[pos].start <= except_pc && table[pos].end > except_pc) { /* This can apply. Make sure it is better or as good as the previous best. */ /* The best one ends first. */ if (best == 0 || (table[pos].end <= table[best].end /* The best one starts last. */ && table[pos].start >= table[best].start)) best = pos; } } if (best != 0) return table[best].exception_handler; #endif #if 0 printf("find_first_eh_table_match(): else: returning NULL!\n"); #endif return (void*)0; } #if 0 /* this routine returns the next tighest exception table match for the current except_pc, or 0 if there aren't any wider entries (meaning we need to either unwind a level and call find_first_exception_table_match() with the new pc, or we need to call terminate() because there are no more layers to unwind. */ void * __find_next_exception_table_match() { exception_table *table = __EXCEPTION_TABLE__; int pos = except_table_pos; extern int printf(...); printf("__find_next_exception_table_match(): table = %x, pos = %d, except_pc = %x\n",table,pos,except_pc); if(! --pos) { except_table_pos = 1; return (void*)0; } if(table[pos].start <= except_pc && table[pos].end >= except_pc) { except_table_pos = pos; printf("__find_next_exception_table_match(): found match: %x\n",table[pos].exception_handler); return table[pos].exception_handler; } else { except_table_pos = 1; return (void*)0; } } #endif #if 0 void __unwind_function(void *frameaddr) { extern int printf(...); printf("__unwind_function(): frameaddr = %x\n",frameaddr); } #endif int __throw_type_match (const char *catch_type, const char *throw_type) { extern int printf(...); #if 0 printf("__throw_type_match (): catch_type = %s, throw_type = %s\n", catch_type, throw_type); #endif return strcmp (catch_type, throw_type); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.