diff options
author | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-09-10 18:00:28 +0000 |
---|---|---|
committer | jason <jason@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-09-10 18:00:28 +0000 |
commit | d757b8c9a564c5dfe7a77df8a896cc8a8cb3009e (patch) | |
tree | 0928096722cf7e87c6973bd7bb029f787ab959db /gcc/collect2.c | |
parent | bb92b9f46e94086ea5307416fce72be178ab276d (diff) | |
download | gcc-d757b8c9a564c5dfe7a77df8a896cc8a8cb3009e.tar.gz |
dwarf2 EH support
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@15255 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/collect2.c')
-rw-r--r-- | gcc/collect2.c | 79 |
1 files changed, 71 insertions, 8 deletions
diff --git a/gcc/collect2.c b/gcc/collect2.c index 7c17824cc01..576bc74669f 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -239,6 +239,7 @@ static char *initname, *fininame; /* names of init and fini funcs */ static struct head constructors; /* list of constructors found */ static struct head destructors; /* list of destructors found */ static struct head exports; /* list of exported symbols */ +static struct head frame_tables; /* list of frame unwind info tables */ struct obstack temporary_obstack; struct obstack permanent_obstack; @@ -599,13 +600,16 @@ is_ctor_dtor (s) #ifdef NO_DOT_IN_LABEL { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 }, { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 }, + { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 }, #else { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 }, { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 }, + { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 }, #endif #else { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 }, { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 }, + { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 }, #endif { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 }, { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 }, @@ -993,6 +997,7 @@ main (argc, argv) num_c_args++; } obstack_free (&temporary_obstack, temporary_firstobj); + ++num_c_args; c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args); @@ -1288,6 +1293,7 @@ main (argc, argv) shared_obj = 1; } obstack_free (&temporary_obstack, temporary_firstobj); + *c_ptr++ = "-fno-exceptions"; #ifdef COLLECT_EXPORT_LIST /* The AIX linker will discard static constructors in object files if @@ -1396,7 +1402,8 @@ main (argc, argv) } if (constructors.number == 0 && destructors.number == 0 -#ifdef LDD_SUFFIX + && frame_tables.number == 0 +#ifdef SCAN_LIBRARIES /* If we will be running these functions ourselves, we want to emit stubs into the shared library so that we don't have to relink dependent programs when we add static objects. */ @@ -1690,6 +1697,7 @@ write_c_file_stat (stream, name) char *name; { char *prefix, *p, *q; + int frames = (frame_tables.number > 0); /* Figure out name of output_file, stripping off .so version. */ p = rindex (output_file, '/'); @@ -1743,15 +1751,38 @@ write_c_file_stat (stream, name) fprintf (stream, "static int count;\n"); fprintf (stream, "typedef void entry_pt();\n"); write_list_with_asm (stream, "extern entry_pt ", constructors.first); + + if (frames) + { + write_list_with_asm (stream, "extern void *", frame_tables.first); + + fprintf (stream, "\tstatic void *frame_table[] = {\n"); + 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"); + + fprintf (stream, "static void reg_frame () {\n"); + fprintf (stream, "\t__register_frame_table (frame_table);\n"); + fprintf (stream, "\t}\n"); + + fprintf (stream, "static void dereg_frame () {\n"); + fprintf (stream, "\t__deregister_frame (frame_table);\n"); + fprintf (stream, "\t}\n"); + } + fprintf (stream, "void %s() {\n", initname); - if (constructors.number > 0) + if (constructors.number > 0 || frames) { fprintf (stream, "\tstatic entry_pt *ctors[] = {\n"); write_list (stream, "\t\t", constructors.first); + if (frames) + fprintf (stream, "\treg_frame,\n"); fprintf (stream, "\t};\n"); fprintf (stream, "\tentry_pt **p;\n"); fprintf (stream, "\tif (count++ != 0) return;\n"); - fprintf (stream, "\tp = ctors + %d;\n", constructors.number); + fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames); fprintf (stream, "\twhile (p > ctors) (*--p)();\n"); } else @@ -1759,16 +1790,18 @@ write_c_file_stat (stream, name) fprintf (stream, "}\n"); write_list_with_asm (stream, "extern entry_pt ", destructors.first); fprintf (stream, "void %s() {\n", fininame); - if (destructors.number > 0) + if (destructors.number > 0 || frames) { fprintf (stream, "\tstatic entry_pt *dtors[] = {\n"); write_list (stream, "\t\t", destructors.first); + if (frames) + fprintf (stream, "\tdereg_frame,\n"); fprintf (stream, "\t};\n"); fprintf (stream, "\tentry_pt **p;\n"); fprintf (stream, "\tif (--count != 0) return;\n"); fprintf (stream, "\tp = dtors;\n"); fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n", - destructors.number); + destructors.number + frames); } fprintf (stream, "}\n"); @@ -1788,20 +1821,46 @@ write_c_file_glob (stream, name) { /* Write the tables as C code */ + int frames = (frame_tables.number > 0); + fprintf (stream, "typedef void entry_pt();\n\n"); write_list_with_asm (stream, "extern entry_pt ", constructors.first); - + + if (frames) + { + write_list_with_asm (stream, "extern void *", frame_tables.first); + + fprintf (stream, "\tstatic void *frame_table[] = {\n"); + 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"); + + fprintf (stream, "static void reg_frame () {\n"); + fprintf (stream, "\t__register_frame_table (frame_table);\n"); + fprintf (stream, "\t}\n"); + + fprintf (stream, "static void dereg_frame () {\n"); + fprintf (stream, "\t__deregister_frame (frame_table);\n"); + fprintf (stream, "\t}\n"); + } + fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n"); - fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number); + fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames); write_list (stream, "\t", constructors.first); + if (frames) + fprintf (stream, "\treg_frame,\n"); fprintf (stream, "\t0\n};\n\n"); write_list_with_asm (stream, "extern entry_pt ", destructors.first); fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n"); - fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number); + fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames); write_list (stream, "\t", destructors.first); + if (frames) + fprintf (stream, "\tdereg_frame,\n"); fprintf (stream, "\t0\n};\n\n"); fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN); @@ -1985,6 +2044,10 @@ scan_prog_file (prog_name, which_pass) #endif break; + case 5: + if (which_pass != PASS_LIB) + add_to_list (&frame_tables, name); + default: /* not a constructor or destructor */ continue; } |