diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ff5c32fc8c0..f33c86f404f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2001-05-22 Richard Henderson + + * unwind-dw2-fde.c (__deregister_frame_info): Stubbify in favour of... + (__deregister_frame_info_bases): New. + * unwind-dw2-fde.h: Declare it. + * libgcc-std.ver: Export it. + * crtstuff.c (__do_global_dtors_aux): Call it if we would have + called __register_frame_info_bases. + 2001-05-22 Loren J. Rittle * config/freebsd.h (FBSD_CPP_PREDEFINES): Use #endif/#if pair diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c index 1897185f3d1..862eeacfc61 100644 --- a/gcc/crtstuff.c +++ b/gcc/crtstuff.c @@ -95,6 +95,8 @@ extern void __register_frame_info_bases (void *, struct object *, TARGET_ATTRIBUTE_WEAK; extern void *__deregister_frame_info (void *) TARGET_ATTRIBUTE_WEAK; +extern void *__deregister_frame_info_bases (void *) + TARGET_ATTRIBUTE_WEAK; #ifndef OBJECT_FORMAT_MACHO @@ -210,9 +212,17 @@ __do_global_dtors_aux (void) } #ifdef EH_FRAME_SECTION_ASM_OP +#if defined(CRT_GET_RFIB_TEXT) || defined(CRT_GET_RFIB_DATA) + /* If we used the new __register_frame_info_bases interface, + make sure that we deregister from the same place. */ + if (__deregister_frame_info_bases) + __deregister_frame_info_bases (__EH_FRAME_BEGIN__); +#else if (__deregister_frame_info) __deregister_frame_info (__EH_FRAME_BEGIN__); #endif +#endif + completed = 1; } diff --git a/gcc/libgcc-std.ver b/gcc/libgcc-std.ver index ae353e51f82..73c9f6fcbbe 100644 --- a/gcc/libgcc-std.ver +++ b/gcc/libgcc-std.ver @@ -125,6 +125,7 @@ GCC_3.0 { _Unwind_SetIP __deregister_frame __deregister_frame_info + __deregister_frame_info_bases __register_frame __register_frame_info __register_frame_info_bases diff --git a/gcc/unwind-dw2-fde.c b/gcc/unwind-dw2-fde.c index 3a42f29a6ce..7b5c7574d9c 100644 --- a/gcc/unwind-dw2-fde.c +++ b/gcc/unwind-dw2-fde.c @@ -140,9 +140,19 @@ __register_frame_table (void *begin) } /* Called from crtbegin.o to deregister the unwind info for an object. */ +/* ??? Glibc has for a while now exported __register_frame_info and + __deregister_frame_info. If we call __register_frame_info_bases + from crtbegin (wherein it is declared weak), and this object does + not get pulled from libgcc.a for other reasons, then the + invocation of __deregister_frame_info will be resolved from glibc. + Since the registration did not happen there, we'll abort. + + Therefore, declare a new deregistration entry point that does the + exact same thing, but will resolve to the same library as + implements __register_frame_info_bases. */ void * -__deregister_frame_info (void *begin) +__deregister_frame_info_bases (void *begin) { struct object **p; struct object *ob = 0; @@ -187,6 +197,18 @@ __deregister_frame_info (void *begin) return (void *) ob; } +#ifdef ASM_OUTPUT_DEF +void * +__deregister_frame_info (void *) + __attribute__((alias(__USER_LABEL_PREFIX__ "__deregister_frame_info_bases"))); +#else +void * +__deregister_frame_info (void *begin) +{ + return __deregister_frame_info_bases (begin); +} +#endif + void __deregister_frame (void *begin) { diff --git a/gcc/unwind-dw2-fde.h b/gcc/unwind-dw2-fde.h index efbded0fa99..3d7df409e64 100644 --- a/gcc/unwind-dw2-fde.h +++ b/gcc/unwind-dw2-fde.h @@ -94,6 +94,7 @@ extern void __register_frame_info_table_bases (void *, struct object *, extern void __register_frame_info_table (void *, struct object *); extern void __register_frame_table (void *); extern void *__deregister_frame_info (void *); +extern void *__deregister_frame_info_bases (void *); extern void __deregister_frame (void *);