home *** CD-ROM | disk | FTP | other *** search
- /* 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);
- }
-