From 2cf2492a13512f5ca2fb2d5fd3ca5e787b59624d Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Sat, 20 Dec 1997 12:37:59 +0000 Subject: [PATCH] frame.h (__register_frame, [...]): New. * frame.h (__register_frame, __register_frame_table, __deregister_frame): New. * frame.c (__register_frame, __register_frame_table, __deregister_frame): New. * frame.c (__deregister_frame_info): Return void *. * frame.h (__deregister_frame_info): Ditto. * collect2.c (__deregister_frame_info): Ditto. * frame.h (__register_frame_info_table): Fix typo in declaration. * frame.c (__register_frame_info): Renamed from __register_frame. (__register_frame_info_table, __deregister_frame_info): Similarly. * frame.h (__{,de}register_frame_info): Likewise. (__register_frame_info_table): New declaration. * crtstuff.c (__do_global_dtors{,_aux}): Rename __deregister_frame. (frame_dummy, __do_global_ctors): Likewise for __register_frame. * collect2.c (write_c_file_{stat,glob}): Rename __register_frame to __register_frame_info and similarly for __deregister_frame and __register_frame_table. * collect2.c (write_c_file_glob): Allocate initial frame object in static storage and pass its address. * crtstuff.c (__do_global_ctors): Fix typo in last change. * crtstuff.c (__do_global_ctors): Add missing arg to __register_frame. * collect2.c (write_c_file_stat): Fix error in last change; use __SIZE_TYPE__, not size_t. Alter C startup code so that it doesn't invoke malloc on Solaris. * frame.h (struct object): Decl moved here from frame.c. * frame.c (struct object): Move decl to frame.h. ("frame.h"): Include after , so that size_t is defined. (__register_frame, __register_frame_table, __deregister_frame): It's now the caller's responsibility to allocate storage for object. * crtstuff.c (frame_dummy), collect2.c (write_c_file_stat): Allocate initial frame object in static storage and pass its address. * crtstuff.c (, "frame.h"): Include. * Makefile.in ($(T)crtbegin.o, $(T)crtend.o, stamp-crtS): Depend on defaults.h and frame.h. The oh so fun changes in __register_frame* interface stuff. Co-Authored-By: H.J. Lu Co-Authored-By: Richard Kenner From-SVN: r17160 --- gcc/ChangeLog | 46 ++++++++++++++++++++++++++++++++++++++++++++ gcc/collect2.c | 38 ++++++++++++++++++++++++++++-------- gcc/crtstuff.c | 18 ++++++++++------- gcc/except.c | 4 ++-- gcc/frame.c | 52 ++++++++++++++++++++++++++++---------------------- gcc/frame.h | 29 ++++++++++++++++++++++++++-- 6 files changed, 145 insertions(+), 42 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2bfb4bded0f5..06911c39a868 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,49 @@ +Sat Dec 20 13:36:06 1997 Paul Eggert + Richard Kenner + H.J. Lu (hjl@gnu.org) + + * frame.h (__register_frame, __register_frame_table, + __deregister_frame): New. + * frame.c (__register_frame, __register_frame_table, + __deregister_frame): New. + * frame.c (__deregister_frame_info): Return void *. + * frame.h (__deregister_frame_info): Ditto. + * collect2.c (__deregister_frame_info): Ditto. + + * frame.h (__register_frame_info_table): Fix typo in declaration. + + * frame.c (__register_frame_info): Renamed from __register_frame. + (__register_frame_info_table, __deregister_frame_info): Similarly. + * frame.h (__{,de}register_frame_info): Likewise. + (__register_frame_info_table): New declaration. + * crtstuff.c (__do_global_dtors{,_aux}): Rename __deregister_frame. + (frame_dummy, __do_global_ctors): Likewise for __register_frame. + * collect2.c (write_c_file_{stat,glob}): Rename __register_frame + to __register_frame_info and similarly for __deregister_frame and + __register_frame_table. + + * collect2.c (write_c_file_glob): + Allocate initial frame object in static storage and pass its address. + + * crtstuff.c (__do_global_ctors): Fix typo in last change. + + * crtstuff.c (__do_global_ctors): Add missing arg to __register_frame. + + * collect2.c (write_c_file_stat): Fix error in last change; + use __SIZE_TYPE__, not size_t. + + Alter C startup code so that it doesn't invoke malloc on Solaris. + * frame.h (struct object): Decl moved here from frame.c. + * frame.c (struct object): Move decl to frame.h. + ("frame.h"): Include after , so that size_t is defined. + (__register_frame, __register_frame_table, __deregister_frame): + It's now the caller's responsibility to allocate storage for object. + * crtstuff.c (frame_dummy), collect2.c (write_c_file_stat): + Allocate initial frame object in static storage and pass its address. + * crtstuff.c (, "frame.h"): Include. + * Makefile.in ($(T)crtbegin.o, $(T)crtend.o, stamp-crtS): + Depend on defaults.h and frame.h. + Fri Dec 19 10:02:57 1997 Richard Kenner * i386.h (INITIAL_ELIMINATION_OFFSET): Correctly test for PIC diff --git a/gcc/collect2.c b/gcc/collect2.c index 576bc74669f8..060e4645ab13 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -1760,15 +1760,26 @@ write_c_file_stat (stream, name) write_list (stream, "\t\t&", frame_tables.first); fprintf (stream, "\t0\n};\n"); - fprintf (stream, "extern void __register_frame_table (void *);\n"); - fprintf (stream, "extern void __deregister_frame (void *);\n"); + /* This must match what's in frame.h. */ + fprintf (stream, "struct object {\n"); + fprintf (stream, " void *pc_begin;\n"); + fprintf (stream, " void *pc_end;\n"); + fprintf (stream, " void *fde_begin;\n"); + fprintf (stream, " void *fde_array;\n"); + fprintf (stream, " __SIZE_TYPE__ count;\n"); + fprintf (stream, " struct object *next;\n"); + fprintf (stream, "};\n"); + + fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); + fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); fprintf (stream, "static void reg_frame () {\n"); - fprintf (stream, "\t__register_frame_table (frame_table);\n"); + fprintf (stream, "\tstatic struct object ob;\n"); + fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); fprintf (stream, "\t}\n"); fprintf (stream, "static void dereg_frame () {\n"); - fprintf (stream, "\t__deregister_frame (frame_table);\n"); + fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); fprintf (stream, "\t}\n"); } @@ -1835,15 +1846,26 @@ write_c_file_glob (stream, name) write_list (stream, "\t\t&", frame_tables.first); fprintf (stream, "\t0\n};\n"); - fprintf (stream, "extern void __register_frame_table (void *);\n"); - fprintf (stream, "extern void __deregister_frame (void *);\n"); + /* This must match what's in frame.h. */ + fprintf (stream, "struct object {\n"); + fprintf (stream, " void *pc_begin;\n"); + fprintf (stream, " void *pc_end;\n"); + fprintf (stream, " void *fde_begin;\n"); + fprintf (stream, " void *fde_array;\n"); + fprintf (stream, " __SIZE_TYPE__ count;\n"); + fprintf (stream, " struct object *next;\n"); + fprintf (stream, "};\n"); + + fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); + fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); fprintf (stream, "static void reg_frame () {\n"); - fprintf (stream, "\t__register_frame_table (frame_table);\n"); + fprintf (stream, "\tstatic struct object ob;\n"); + fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); fprintf (stream, "\t}\n"); fprintf (stream, "static void dereg_frame () {\n"); - fprintf (stream, "\t__deregister_frame (frame_table);\n"); + fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); fprintf (stream, "\t}\n"); } diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c index c120862139a2..7e3c3edb25ac 100644 --- a/gcc/crtstuff.c +++ b/gcc/crtstuff.c @@ -53,6 +53,8 @@ Boston, MA 02111-1307, USA. */ #include "tm.h" #include "defaults.h" +#include +#include "frame.h" /* Provide default definitions for the pseudo-ops used to switch to the .ctors and .dtors sections. @@ -140,7 +142,7 @@ __do_global_dtors_aux () } #ifdef EH_FRAME_SECTION_ASM_OP - __deregister_frame (__EH_FRAME_BEGIN__); + __deregister_frame_info (__EH_FRAME_BEGIN__); #endif completed = 1; } @@ -160,14 +162,15 @@ fini_dummy () } #ifdef EH_FRAME_SECTION_ASM_OP -/* Stick a call to __register_frame into the .init section. For some reason - calls with no arguments work more reliably in .init, so stick the call - in another function. */ +/* Stick a call to __register_frame_info into the .init section. For some + reason calls with no arguments work more reliably in .init, so stick the + call in another function. */ static void frame_dummy () { - __register_frame (__EH_FRAME_BEGIN__); + static struct object object; + __register_frame_info (__EH_FRAME_BEGIN__, &object); } static void @@ -251,7 +254,7 @@ __do_global_dtors () (*p) (); #ifdef EH_FRAME_SECTION_ASM_OP - __deregister_frame (__EH_FRAME_BEGIN__); + __deregister_frame_info (__EH_FRAME_BEGIN__); #endif } #endif @@ -391,7 +394,8 @@ __do_global_ctors () { func_ptr *p; #ifdef EH_FRAME_SECTION_ASM_OP - __register_frame (__EH_FRAME_BEGIN__); + static struct object object; + __register_frame_info (__EH_FRAME_BEGIN__, &object); #endif for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) (*p) (); diff --git a/gcc/except.c b/gcc/except.c index 95ea683c6137..3336471bd86d 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -97,9 +97,9 @@ Boston, MA 02111-1307, USA. */ On targets that support crtstuff.c, the unwind information is stored in a section named .eh_frame and the information for the entire shared object or program is registered with a call to - __register_frame. On other targets, the information for each + __register_frame_info. On other targets, the information for each translation unit is registered from the file generated by collect2. - __register_frame is defined in frame.c, and is responsible for + __register_frame_info is defined in frame.c, and is responsible for recording all of the unwind regions into one list (which is kept in a static variable named unwind_table_list). diff --git a/gcc/frame.c b/gcc/frame.c index 118329bbfd5e..ddf5d3f415a2 100644 --- a/gcc/frame.c +++ b/gcc/frame.c @@ -74,18 +74,7 @@ struct dwarf_fde { typedef struct dwarf_fde fde; -/* The representation for an "object" to be searched for frame unwind info. - For targets with named sections, one object is an executable or shared - library; for other targets, one object is one translation unit. */ - -struct object { - void *pc_begin; - void *pc_end; - fde *fde_begin; - fde ** fde_array; - size_t count; - struct object *next; -}; +/* Objects to be searched for frame unwind info. */ static struct object *objects; @@ -511,10 +500,8 @@ execute_cfa_insn (void *p, struct frame_state_internal *state, /* Called from crtbegin.o to register the unwind info for an object. */ void -__register_frame (void *begin) +__register_frame_info (void *begin, struct object *ob) { - struct object *ob = (struct object *) malloc (sizeof (struct object)); - ob->fde_begin = begin; ob->pc_begin = ob->pc_end = 0; @@ -525,15 +512,20 @@ __register_frame (void *begin) objects = ob; } +void +__register_frame (void *begin) +{ + struct object *ob = (struct object *) malloc (sizeof (struct object)); + __register_frame_info (begin, ob); +} + /* Similar, but BEGIN is actually a pointer to a table of unwind entries for different translation units. Called from the file generated by collect2. */ void -__register_frame_table (void *begin) +__register_frame_info_table (void *begin, struct object *ob) { - struct object *ob = (struct object *) malloc (sizeof (struct object)); - ob->fde_begin = begin; ob->fde_array = begin; @@ -544,13 +536,21 @@ __register_frame_table (void *begin) objects = ob; } +void +__register_frame_table (void *begin) +{ + struct object *ob = (struct object *) malloc (sizeof (struct object)); + __register_frame_info_table (begin, ob); +} + /* Called from crtend.o to deregister the unwind info for an object. */ -void -__deregister_frame (void *begin) +void * +__deregister_frame_info (void *begin) { - struct object **p = &objects; + struct object **p; + p = &objects; while (*p) { if ((*p)->fde_begin == begin) @@ -561,15 +561,21 @@ __deregister_frame (void *begin) /* If we've run init_frame for this object, free the FDE array. */ if (ob->pc_begin) free (ob->fde_array); - free (ob); - return; + return (void *) ob; } p = &((*p)->next); } + abort (); } +void +__deregister_frame (void *begin) +{ + free (__deregister_frame_info (begin)); +} + /* Called from __throw to find the registers to restore for a given PC_TARGET. The caller should allocate a local variable of `struct frame_state' (declared in frame.h) and pass its address to STATE_IN. */ diff --git a/gcc/frame.h b/gcc/frame.h index 3b3805368842..7493d92f80bd 100644 --- a/gcc/frame.h +++ b/gcc/frame.h @@ -18,14 +18,39 @@ typedef struct frame_state #define REG_SAVED_OFFSET 1 #define REG_SAVED_REG 2 +/* The representation for an "object" to be searched for frame unwind info. + For targets with named sections, one object is an executable or shared + library; for other targets, one object is one translation unit. + + A copy of this structure declaration is printed by collect2.c; + keep the copies synchronized! */ + +struct object { + void *pc_begin; + void *pc_end; + struct dwarf_fde *fde_begin; + struct dwarf_fde **fde_array; + size_t count; + struct object *next; +}; + +extern void __register_frame (void * ); +extern void __register_frame_table (void *); +extern void __deregister_frame (void *); + /* Called either from crtbegin.o or a static constructor to register the unwind info for an object or translation unit, respectively. */ -extern void __register_frame (void *); +extern void __register_frame_info (void *, struct object *); + +/* Similar, but BEGIN is actually a pointer to a table of unwind entries + for different translation units. Called from the file generated by + collect2. */ +extern void __register_frame_info_table (void *, struct object *); /* Called from crtend.o to deregister the unwind info for an object. */ -extern void __deregister_frame (void *); +extern void *__deregister_frame_info (void *); /* Called from __throw to find the registers to restore for a given PC_TARGET. The caller should allocate a local variable of `struct -- 2.47.2