aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/Makefile.in11
-rw-r--r--gcc/collect2.c565
-rw-r--r--gcc/config/alpha/alpha.h7
-rw-r--r--gcc/config/i386/sol2.h13
-rw-r--r--gcc/config/i386/t-sol28
-rw-r--r--gcc/config/i860/sysv4.h19
-rw-r--r--gcc/config/m88k/dgux.h14
-rw-r--r--gcc/config/m88k/sysv4.h22
-rw-r--r--gcc/config/m88k/t-sysv48
-rw-r--r--gcc/config/mips/iris5.h15
-rw-r--r--gcc/config/pa/pa-hpux.h5
-rw-r--r--gcc/config/pa/pa.h18
-rw-r--r--gcc/config/sparc/sol2.h26
-rw-r--r--gcc/config/sparc/sparc.h23
-rw-r--r--gcc/config/sparc/sysv4.h44
-rw-r--r--gcc/config/sparc/t-sol28
-rw-r--r--gcc/config/svr4.h75
-rw-r--r--gcc/config/t-svr48
-rw-r--r--gcc/crtstuff.c163
-rw-r--r--gcc/gcc.c48
-rw-r--r--gcc/libgcc2.c37
21 files changed, 955 insertions, 182 deletions
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 7e9231f..eb8794d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -340,6 +340,9 @@ FLOAT_H=float.h-nat
# Extra symbols for fixproto to define when parsing headers.
FIXPROTO_DEFINES =
+# Extra flags to use when compiling crt{begin,end}.o.
+CRTSTUFF_T_CFLAGS =
+
# End of variables for you to override.
# Definition of `all' is here so that new rules inserted by sed
@@ -943,13 +946,13 @@ sublibobjc.a: cc1obj stmp-int-hdrs libgcc2.ready
# Compile two additional files that are linked with every program
# linked using GCC on system V, for the sake of C++ constructors.
crtbegin.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) gbl-ctors.h
- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) -DCRT_BEGIN \
- -finhibit-size-directive -fno-inline-functions \
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS) \
+ -DCRT_BEGIN -finhibit-size-directive -fno-inline-functions \
-g0 -c $(srcdir)/crtstuff.c -o crtbegin.o
crtend.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) gbl-ctors.h
- $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) -DCRT_END \
- -finhibit-size-directive -fno-inline-functions \
+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS) \
+ -DCRT_END -finhibit-size-directive -fno-inline-functions \
-g0 -c $(srcdir)/crtstuff.c -o crtend.o
# Compiling object files from source files.
diff --git a/gcc/collect2.c b/gcc/collect2.c
index 356bad0..e46b9fa 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -107,6 +107,7 @@ extern int sys_nerr;
cross-versions are in the proper directories. */
#ifdef CROSS_COMPILE
+#undef SUNOS4_SHARED_LIBRARIES
#undef OBJECT_FORMAT_COFF
#undef OBJECT_FORMAT_ROSE
#undef MD_EXEC_PREFIX
@@ -188,6 +189,9 @@ extern int sys_nerr;
#define SYMBOL__MAIN __main
#endif
+#if defined (LDD_SUFFIX) || defined (SUNOS4_SHARED_LIBRARIES)
+#define SCAN_LIBRARIES
+#endif
/* Linked lists of constructor and destructor names. */
@@ -209,6 +213,7 @@ struct head
enum pass {
PASS_FIRST, /* without constructors */
+ PASS_LIB, /* looking for shared libraries */
PASS_SECOND /* with constructors linked in */
};
@@ -225,12 +230,15 @@ static int strip_flag; /* true if -s */
static int debug; /* true if -debug */
+static int shared_obj; /* true if -shared */
+
static int temp_filename_length; /* Length of temp_filename */
static char *temp_filename; /* Base of temp filenames */
static char *c_file; /* <xxx>.c for constructor/destructor list. */
static char *o_file; /* <xxx>.o for constructor/destructor list. */
static char *output_file; /* Output file for ld. */
static char *nm_file_name; /* pathname of nm */
+static char *ldd_file_name; /* pathname of ldd (or equivalent) */
static char *strip_file_name; /* pathname of strip */
static struct head constructors; /* list of constructors found */
@@ -272,6 +280,7 @@ static void write_list PROTO((FILE *, char *, struct id *));
static void write_list_with_asm PROTO((FILE *, char *, struct id *));
static void write_c_file PROTO((FILE *, char *));
static void scan_prog_file PROTO((char *, enum pass));
+static void scan_libraries PROTO((char *));
generic *xcalloc ();
generic *xmalloc ();
@@ -467,6 +476,8 @@ is_ctor_dtor (s)
{ "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 },
{ "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 },
#endif
+ { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 },
+ { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 },
#ifdef CFRONT_LOSSAGE /* Don't collect cfront initialization functions.
cfront has its own linker procedure to collect them;
if collect2 gets them too, they get collected twice
@@ -792,6 +803,10 @@ main (argc, argv)
char *full_nm_suffix = nm_suffix;
char *gnm_suffix = "gnm";
char *full_gnm_suffix = gnm_suffix;
+#ifdef LDD_SUFFIX
+ char *ldd_suffix = LDD_SUFFIX;
+ char *full_ldd_suffix = ldd_suffix;
+#endif
char *strip_suffix = "strip";
char *full_strip_suffix = strip_suffix;
char *gstrip_suffix = "gstrip";
@@ -943,6 +958,14 @@ main (argc, argv)
strcat (full_gnm_suffix, "-");
strcat (full_gnm_suffix, gnm_suffix);
+#ifdef LDD_SUFFIX
+ full_ldd_suffix
+ = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1);
+ strcpy (full_ldd_suffix, target_machine);
+ strcat (full_ldd_suffix, "-");
+ strcat (full_ldd_suffix, ldd_suffix);
+#endif
+
full_strip_suffix
= xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1);
strcpy (full_strip_suffix, target_machine);
@@ -1011,6 +1034,12 @@ main (argc, argv)
if (nm_file_name == 0)
nm_file_name = find_a_file (&path, full_nm_suffix);
+#ifdef LDD_SUFFIX
+ ldd_file_name = find_a_file (&cpath, ldd_suffix);
+ if (ldd_file_name == 0)
+ ldd_file_name = find_a_file (&path, full_ldd_suffix);
+#endif
+
#ifdef REAL_STRIP_FILE_NAME
strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME);
if (strip_file_name == 0)
@@ -1088,6 +1117,17 @@ main (argc, argv)
}
break;
+ case 'l':
+ if (first_file)
+ {
+ /* place o_file BEFORE this argument! */
+ first_file = 0;
+ ld2--;
+ *ld2++ = o_file;
+ *ld2++ = arg;
+ }
+ break;
+
case 'o':
output_file = (arg[2] == '\0') ? argv[1] : &arg[2];
break;
@@ -1116,10 +1156,13 @@ main (argc, argv)
}
else if (first_file
&& (p = rindex (arg, '.')) != (char *)0
- && strcmp (p, ".o") == 0)
+ && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0))
{
first_file = 0;
+ /* place o_file BEFORE this argument! */
+ ld2--;
*ld2++ = o_file;
+ *ld2++ = arg;
}
}
@@ -1132,11 +1175,24 @@ main (argc, argv)
while (*q && *q != ' ') q++;
if (*p == '-' && (p[1] == 'm' || p[1] == 'f'))
*c_ptr++ = savestring (p, q - p);
+ if (strncmp (p, "-shared", sizeof ("shared") - 1) == 0)
+ shared_obj = 1;
if (*q) q++;
p = q;
}
+#ifdef LD_INIT_SWITCH
+ /* Tell the linker that we have initializer and finalizer functions. */
+ if (shared_obj)
+ {
+ *ld2++ = LD_INIT_SWITCH;
+ *ld2++ = "_GLOBAL__DI";
+ *ld2++ = LD_FINI_SWITCH;
+ *ld2++ = "_GLOBAL__DD";
+ }
+#endif
+
*c_ptr++ = c_file;
*c_ptr = *ld1 = *ld2 = (char *)0;
@@ -1158,6 +1214,10 @@ main (argc, argv)
(c_file_name ? c_file_name : "not found"));
fprintf (stderr, "nm_file_name = %s\n",
(nm_file_name ? nm_file_name : "not found"));
+#ifdef LDD_SUFFIX
+ fprintf (stderr, "ldd_file_name = %s\n",
+ (ldd_file_name ? ldd_file_name : "not found"));
+#endif
fprintf (stderr, "strip_file_name = %s\n",
(strip_file_name ? strip_file_name : "not found"));
fprintf (stderr, "c_file = %s\n",
@@ -1195,19 +1255,30 @@ main (argc, argv)
fork_execute ("ld", ld1_argv);
- /* If -r, don't build the constructor or destructor list, just return now. */
+ /* If -r, don't build the constructor or destructor list, just return now. */
if (rflag)
return 0;
scan_prog_file (output_file, PASS_FIRST);
+#ifdef SCAN_LIBRARIES
+ scan_libraries (output_file);
+#endif
+
if (debug)
{
fprintf (stderr, "%d constructor(s) found\n", constructors.number);
fprintf (stderr, "%d destructor(s) found\n", destructors.number);
}
- if (constructors.number == 0 && destructors.number == 0)
+ if (constructors.number == 0 && destructors.number == 0
+#ifdef LDD_SUFFIX
+ /* 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. */
+ && ! shared_obj
+#endif
+ )
{
/* Strip now if it was requested on the command line. */
if (strip_flag)
@@ -1429,10 +1500,107 @@ write_list_with_asm (stream, prefix, list)
}
}
+/* Write out the constructor and destructor tables statically (for a shared
+ object), along with the functions to execute them. */
+
+static void
+write_c_file_stat (stream, name)
+ FILE *stream;
+ char *name;
+{
+ char *prefix, *p, *q;
+ char *initname, *fininame;
+
+ /* Figure out name of output_file, stripping off .so version. */
+ p = rindex (output_file, '/');
+ if (p == 0)
+ p = (char *) output_file;
+ else
+ p++;
+ q = p;
+ while (q)
+ {
+ q = index (q,'.');
+ if (q == 0)
+ {
+ q = p + strlen (p);
+ break;
+ }
+ else
+ {
+ if (strncmp (q, ".so", 3) == 0)
+ {
+ q += 3;
+ break;
+ }
+ else
+ q++;
+ }
+ }
+ /* q points to null at end of the string (or . of the .so version) */
+ prefix = xmalloc (q - p + 1);
+ strncpy (prefix, p, q - p);
+ prefix[q - p] = 0;
+ for (q = prefix; *q; q++)
+ if (!isalnum (*q))
+ *q = '_';
+ if (debug)
+ fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n",
+ output_file, prefix);
+
+#define INIT_NAME_FORMAT "_GLOBAL__FI_%s"
+ initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2);
+ sprintf (initname, INIT_NAME_FORMAT, prefix);
+
+#define FINI_NAME_FORMAT "_GLOBAL__FD_%s"
+ fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2);
+ sprintf (fininame, FINI_NAME_FORMAT, prefix);
+
+ free (prefix);
+
+ /* Write the tables as C code */
+
+ fprintf (stream, "static int count;\n");
+ fprintf (stream, "typedef void entry_pt();\n");
+ write_list_with_asm (stream, "extern entry_pt ", constructors.first);
+ fprintf (stream, "void %s() {\n", initname);
+ if (constructors.number > 0)
+ {
+ fprintf (stream, "\tstatic entry_pt *ctors[] = {\n");
+ write_list (stream, "\t\t", constructors.first);
+ 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, "\twhile (p > ctors) (*--p)();\n");
+ }
+ fprintf (stream, "}\n");
+ write_list_with_asm (stream, "extern entry_pt ", destructors.first);
+ fprintf (stream, "void %s() {\n", fininame);
+ if (destructors.number > 0)
+ {
+ fprintf (stream, "\tstatic entry_pt *dtors[] = {\n");
+ write_list (stream, "\t\t", destructors.first);
+ 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);
+ }
+ fprintf (stream, "}\n");
+
+ fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname);
+ fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame);
+
+ free (initname);
+ free (fininame);
+}
+
/* Write the constructor/destructor tables. */
static void
-write_c_file (stream, name)
+write_c_file_glob (stream, name)
FILE *stream;
char *name;
{
@@ -1458,6 +1626,16 @@ write_c_file (stream, name)
fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN);
}
+static void
+write_c_file (stream, name)
+ FILE *stream;
+ char *name;
+{
+ if (shared_obj)
+ write_c_file_stat (stream, name);
+ else
+ write_c_file_glob (stream, name);
+}
#ifdef OBJECT_FORMAT_NONE
@@ -1484,14 +1662,14 @@ scan_prog_file (prog_name, which_pass)
char *p, buf[1024];
FILE *inf;
- if (which_pass != PASS_FIRST)
+ if (which_pass == PASS_SECOND)
return;
/* If we don't have an `nm', complain. */
if (nm_file_name == 0)
fatal ("cannot find `nm'");
- nm_argv[argc++] = "nm";
+ nm_argv[argc++] = nm_file_name;
if (NM_FLAGS[0] != '\0')
nm_argv[argc++] = NM_FLAGS;
@@ -1511,8 +1689,7 @@ scan_prog_file (prog_name, which_pass)
char **p_argv;
char *str;
- fprintf (stderr, "%s", nm_file_name);
- for (p_argv = &nm_argv[1]; (str = *p_argv) != (char *)0; p_argv++)
+ for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *)0; p_argv++)
fprintf (stderr, " %s", str);
fprintf (stderr, "\n");
@@ -1570,9 +1747,10 @@ scan_prog_file (prog_name, which_pass)
to the appropriate list. */
for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++)
- ;
+ if (ch == ' ' && p[1] == 'U' && p[2] == ' ')
+ break;
- if (ch == '\0' || ch == '\n')
+ if (ch != '_')
continue;
name = p;
@@ -1587,10 +1765,24 @@ scan_prog_file (prog_name, which_pass)
switch (is_ctor_dtor (name))
{
case 1:
- add_to_list (&constructors, name);
+ if (which_pass != PASS_LIB)
+ add_to_list (&constructors, name);
break;
case 2:
+ if (which_pass != PASS_LIB)
+ add_to_list (&destructors, name);
+ break;
+
+ case 3:
+ if (which_pass != PASS_LIB)
+ fatal ("init function found in object %s", prog_name);
+ add_to_list (&constructors, name);
+ break;
+
+ case 4:
+ if (which_pass != PASS_LIB)
+ fatal ("init function found in object %s", prog_name);
add_to_list (&destructors, name);
break;
@@ -1616,6 +1808,357 @@ scan_prog_file (prog_name, which_pass)
#endif
}
+#ifdef SUNOS4_SHARED_LIBRARIES
+
+/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries
+ that the output file depends upon and their initialization/finalization
+ routines, if any. */
+
+#include <a.out.h>
+#include <fcntl.h>
+#include <link.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <sys/unistd.h>
+
+/* pointers to the object file */
+unsigned object; /* address of memory mapped file */
+unsigned objsize; /* size of memory mapped to file */
+char * code; /* pointer to code segment */
+char * data; /* pointer to data segment */
+struct nlist *symtab; /* pointer to symbol table */
+struct link_dynamic *ld;
+struct link_dynamic_2 *ld_2;
+struct head libraries;
+
+/* Map the file indicated by NAME into memory and store its address. */
+
+static void
+mapfile (name)
+ char *name;
+{
+ int fp;
+ struct stat s;
+ if ((fp = open (name, O_RDONLY)) == -1)
+ fatal ("unable to open file '%s'", name);
+ if (fstat (fp, &s) == -1)
+ fatal ("unable to stat file '%s'", name);
+
+ objsize = s.st_size;
+ object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE,
+ fp, 0);
+ if (object == -1)
+ fatal ("unable to mmap file '%s'", name);
+
+ close (fp);
+}
+
+/* Given the name NAME of a dynamic dependency, find its pathname and add
+ it to the list of libraries. */
+
+static void
+locatelib (name)
+ char *name;
+{
+ static char **l;
+ static int cnt;
+ char buf[MAXPATHLEN];
+ char *p, *q;
+ char **pp;
+
+ if (l == 0)
+ {
+ char *ld_rules;
+ char *ldr = 0;
+ /* counting elements in array, need 1 extra for null */
+ cnt = 1;
+ ld_rules = (char *) (ld_2->ld_rules + code);
+ if (ld_rules)
+ {
+ cnt++;
+ for (; *ld_rules != 0; ld_rules++)
+ if (*ld_rules == ':')
+ cnt++;
+ ld_rules = (char *) (ld_2->ld_rules + code);
+ ldr = (char *) malloc (strlen (ld_rules) + 1);
+ strcpy (ldr, ld_rules);
+ }
+ p = getenv ("LD_LIBRARY_PATH");
+ q = 0;
+ if (p)
+ {
+ cnt++;
+ for (q = p ; *q != 0; q++)
+ if (*q == ':')
+ cnt++;
+ q = (char *) malloc (strlen (p) + 1);
+ strcpy (q, p);
+ }
+ l = (char **) malloc ((cnt + 3) * sizeof (char *));
+ pp = l;
+ if (ldr)
+ {
+ *pp++ = ldr;
+ for (; *ldr != 0; ldr++)
+ if (*ldr == ':')
+ {
+ *ldr++ = 0;
+ *pp++ = ldr;
+ }
+ }
+ if (q)
+ {
+ *pp++ = q;
+ for (; *q != 0; q++)
+ if (*q == ':')
+ {
+ *q++ = 0;
+ *pp++ = p;
+ }
+ }
+ /* built in directories are /lib, /usr/lib, and /usr/local/lib */
+ *pp++ = "/lib";
+ *pp++ = "/usr/lib";
+ *pp++ = "/usr/local/lib";
+ *pp = 0;
+ }
+ for (pp = l; *pp != 0 ; pp++)
+ {
+ sprintf (buf, "%s/%s", *pp, name);
+ if (access (buf, R_OK) == 0)
+ {
+ add_to_list (&libraries, buf);
+ if (debug)
+ fprintf (stderr, "%s\n", buf);
+ break;
+ }
+ }
+ if (*pp == 0)
+ {
+ if (debug)
+ fprintf (stderr, "not found\n");
+ else
+ fatal ("dynamic dependency %s not found", name);
+ }
+}
+
+/* Scan the _DYNAMIC structure of the output file to find shared libraries
+ that it depends upon and any constructors or destructors they contain. */
+
+static void
+scan_libraries (prog_name)
+ char *prog_name;
+{
+ struct exec *header;
+ char *base;
+ struct link_object *lo;
+ char buff[MAXPATHLEN];
+ struct id *list;
+
+ mapfile (prog_name);
+ header = (struct exec *)object;
+ if (N_BADMAG (*header))
+ fatal ("bad magic number in file '%s'", prog_name);
+ if (header->a_dynamic == 0)
+ return;
+
+ code = (char *) (N_TXTOFF (*header) + (long) header);
+ data = (char *) (N_DATOFF (*header) + (long) header);
+ symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header);
+
+ if (header->a_magic == ZMAGIC && header->a_entry == 0x20)
+ {
+ /* shared object */
+ ld = (struct link_dynamic *) (symtab->n_value + code);
+ base = code;
+ }
+ else
+ {
+ /* executable */
+ ld = (struct link_dynamic *) data;
+ base = code-PAGSIZ;
+ }
+
+ if (debug)
+ fprintf (stderr, "dynamic dependencies.\n");
+
+ ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base);
+ for (lo = (struct link_object *) ld_2->ld_need; lo;
+ lo = (struct link_object *) lo->lo_next)
+ {
+ char *name;
+ lo = (struct link_object *) ((long) lo + code);
+ name = (char *) (code + lo->lo_name);
+ if (lo->lo_library)
+ {
+ if (debug)
+ fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major);
+ sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor);
+ locatelib (buff);
+ }
+ else
+ {
+ if (debug)
+ fprintf (stderr, "\t%s\n", name);
+ add_to_list (&libraries, name);
+ }
+ }
+
+ if (debug)
+ fprintf (stderr, "\n");
+
+ /* now iterate through the library list adding their symbols to
+ the list. */
+ for (list = libraries.first; list; list = list->next)
+ scan_prog_file (list->name, PASS_LIB);
+}
+
+#else /* SUNOS4_SHARED_LIBRARIES */
+#ifdef LDD_SUFFIX
+
+/* Use the List Dynamic Dependencies program to find shared libraries that
+ the output file depends upon and their initialization/finalization
+ routines, if any. */
+
+static void
+scan_libraries (prog_name)
+ char *prog_name;
+{
+ static struct head libraries; /* list of shared libraries found */
+ struct id *list;
+ void (*int_handler) ();
+ void (*quit_handler) ();
+ char *ldd_argv[4];
+ int pid;
+ int argc = 0;
+ int pipe_fd[2];
+ char buf[1024];
+ FILE *inf;
+
+ /* If we don't have an `ldd', complain. */
+ if (ldd_file_name == 0)
+ {
+ error ("cannot find `ldd'");
+ return;
+ }
+
+ ldd_argv[argc++] = ldd_file_name;
+ ldd_argv[argc++] = prog_name;
+ ldd_argv[argc++] = (char *) 0;
+
+ if (pipe (pipe_fd) < 0)
+ fatal_perror ("pipe");
+
+ inf = fdopen (pipe_fd[0], "r");
+ if (inf == (FILE *) 0)
+ fatal_perror ("fdopen");
+
+ /* Trace if needed. */
+ if (vflag)
+ {
+ char **p_argv;
+ char *str;
+
+ for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++)
+ fprintf (stderr, " %s", str);
+
+ fprintf (stderr, "\n");
+ }
+
+ fflush (stdout);
+ fflush (stderr);
+
+ /* Spawn child ldd on pipe */
+ pid = vfork ();
+ if (pid == -1)
+ {
+#ifdef vfork
+ fatal_perror ("fork");
+#else
+ fatal_perror ("vfork");
+#endif
+ }
+
+ if (pid == 0) /* child context */
+ {
+ /* setup stdout */
+ if (dup2 (pipe_fd[1], 1) < 0)
+ fatal_perror ("dup2 (%d, 1)", pipe_fd[1]);
+
+ if (close (pipe_fd[0]) < 0)
+ fatal_perror ("close (%d)", pipe_fd[0]);
+
+ if (close (pipe_fd[1]) < 0)
+ fatal_perror ("close (%d)", pipe_fd[1]);
+
+ execv (ldd_file_name, ldd_argv);
+ fatal_perror ("executing %s", ldd_file_name);
+ }
+
+ /* Parent context from here on. */
+ int_handler = (void (*) ()) signal (SIGINT, SIG_IGN);
+#ifdef SIGQUIT
+ quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN);
+#endif
+
+ if (close (pipe_fd[1]) < 0)
+ fatal_perror ("close (%d)", pipe_fd[1]);
+
+ if (debug)
+ fprintf (stderr, "\nldd output with constructors/destructors.\n");
+
+ /* Read each line of ldd output. */
+ while (fgets (buf, sizeof buf, inf) != (char *) 0)
+ {
+ int ch, ch2;
+ char *name, *end, *p = buf;
+
+ /* Extract names of libraries and add to list. */
+ PARSE_LDD_OUTPUT (p);
+ if (p == 0)
+ continue;
+
+ name = p;
+ if (strncmp (name, "not found", sizeof ("not found") - 1) == 0)
+ fatal ("dynamic dependency %s not found", buf);
+
+ /* Find the end of the symbol name. */
+ for (end = p;
+ (ch2 = *end) != '\0' && ch2 != '\n' && !isspace (ch2) && ch2 != '|';
+ end++)
+ continue;
+ *end = '\0';
+
+ if (access (name, R_OK) == 0)
+ add_to_list (&libraries, name);
+ else
+ fatal ("unable to open dynamic dependency '%s'", buf);
+
+ if (debug)
+ fprintf (stderr, "\t%s\n", buf);
+ }
+ if (debug)
+ fprintf (stderr, "\n");
+
+ if (fclose (inf) != 0)
+ fatal_perror ("fclose of pipe");
+
+ do_wait (ldd_file_name);
+
+ signal (SIGINT, int_handler);
+#ifdef SIGQUIT
+ signal (SIGQUIT, quit_handler);
+#endif
+
+ /* now iterate through the library list adding their symbols to
+ the list. */
+ for (list = libraries.first; list; list = list->next)
+ scan_prog_file (list->name, PASS_LIB);
+}
+
+#endif /* LDD_SUFFIX */
+#endif /* SUNOS4_SHARED_LIBRARIES */
+
#endif /* OBJECT_FORMAT_NONE */
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index eb5db36..a7d339b 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -2019,5 +2019,8 @@ do { \
/* The linker will stick __main into the .init section. */
#define HAS_INIT_SECTION
-#define INIT_NAME_FORMAT "__init_%s"
-#define FINI_NAME_FORMAT "__fini_%s"
+#define LD_INIT_SWITCH "-init"
+#define LD_FINI_SWITCH "-fini"
+
+/* We do want to link in libgcc when building shared libraries under OSF/1. */
+#define LIBGCC_SPEC "-lgcc"
diff --git a/gcc/config/i386/sol2.h b/gcc/config/i386/sol2.h
index 9f80162..90deb5c 100644
--- a/gcc/config/i386/sol2.h
+++ b/gcc/config/i386/sol2.h
@@ -31,6 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
it knows what it is doing. */
#define FORCE_INIT_SECTION_ALIGN do { asm (ALIGN_ASM_OP ## " 16"); } while (0)
+#define FORCE_FINI_SECTION_ALIGN FORCE_INIT_SECTION_ALIGN
/* Add "sun" to the list of symbols defined for SVR4. */
#undef CPP_PREDEFINES
@@ -44,10 +45,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef LIB_SPEC
#define LIB_SPEC \
- "%{compat-bsd:-lucb -lsocket -lnsl -lelf -laio} \
- %{!shared:%{!symbolic:-lc}} \
- crtend.o%s \
- %{!shared:%{!symbolic:%{pg:crtn.o%s}%{!pg:crtn.o%s}}}"
+ "%{compat-bsd:-lucb -lsocket -lnsl -lelf -laio} %{!shared:%{!symbolic:-lc}}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend.o%s %{pg:crtn.o%s}%{!pg:crtn.o%s}"
/* This should be the same as in svr4.h, except with -R added. */
#undef LINK_SPEC
@@ -55,8 +56,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
"%{h*} %{V} %{v:%{!V:-V}} \
%{b} %{Wl,*:%*} \
%{static:-dn -Bstatic} \
- %{shared:-G -dy} \
- %{symbolic:-Bsymbolic -G -dy} \
+ %{shared:-G -dy -z text} \
+ %{symbolic:-Bsymbolic -G -dy -z text} \
%{G:-G} \
%{YP,*} \
%{R*} \
diff --git a/gcc/config/i386/t-sol2 b/gcc/config/i386/t-sol2
index a669b7c..eddad5d 100644
--- a/gcc/config/i386/t-sol2
+++ b/gcc/config/i386/t-sol2
@@ -22,3 +22,11 @@ crti.o: $(srcdir)/config/i386/sol2-ci.asm
crtn.o: $(srcdir)/config/i386/sol2-cn.asm
sed -e '/^!/d' <$(srcdir)/config/i386/sol2-cn.asm >crtn.s
$(AS) -o crtn.o crtn.s
+
+# We need to use -fpic when we are using gcc to compile the routines in
+# crtstuff.c. This is only really needed when we are going to use gcc/g++
+# to produce a shared library, but since we don't know ahead of time when
+# we will be doing that, we just always use -fpic when compiling the
+# routines in crtstuff.c.
+
+CRTSTUFF_T_CFLAGS = -fpic
diff --git a/gcc/config/i860/sysv4.h b/gcc/config/i860/sysv4.h
index 3108a74..189c20b 100644
--- a/gcc/config/i860/sysv4.h
+++ b/gcc/config/i860/sysv4.h
@@ -148,10 +148,25 @@ extern char *current_function_original_name;
fprintf (FILE, ":\n"); \
} while (0)
+/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
+
+ Note that we want to give these sections the SHF_WRITE attribute
+ because these sections will actually contain data (i.e. tables of
+ addresses of functions in the current root executable or shared library
+ file) and, in the case of a shared library, the relocatable addresses
+ will have to be properly resolved/relocated (and then written into) by
+ the dynamic linker when it actually attaches the given shared library
+ to the executing process. (Note that on SVR4, you may wish to use the
+ `-z text' option to the ELF linker, when building a shared library, as
+ an additional check that you are doing everything right. But if you do
+ use the `-z text' option when building a shared library, you will get
+ errors unless the .ctors and .dtors sections are marked as writable
+ via the SHF_WRITE attribute.) */
+
#undef CTORS_SECTION_ASM_OP
-#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"a\",\"progbits\""
+#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\""
#undef DTORS_SECTION_ASM_OP
-#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"a\",\"progbits\""
+#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
/* Add definitions to support the .tdesc section as specified in the svr4
ABI for the i860. */
diff --git a/gcc/config/m88k/dgux.h b/gcc/config/m88k/dgux.h
index 9765cbe..8cc0080 100644
--- a/gcc/config/m88k/dgux.h
+++ b/gcc/config/m88k/dgux.h
@@ -31,7 +31,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
(TARGET_SVR4 ? DWARF_DEBUG : SDB_DEBUG)
#ifndef VERSION_INFO2
-#define VERSION_INFO2 "$Revision: 1.14 $"
+#define VERSION_INFO2 "$Revision: 1.15 $"
#endif
#ifndef NO_BUGS
#define AS_BUG_IMMEDIATE_LABEL
@@ -119,8 +119,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#undef LINK_SPEC
#define LINK_SPEC "%{z*} %{h*} %{V} %{v:%{!V:-V}} \
%{static:-dn -Bstatic} \
- %{shared:-G -dy} \
- %{symbolic:-Bsymbolic -G -dy} \
+ %{shared:-G -dy -z text} \
+ %{symbolic:-Bsymbolic -G -dy -z text} \
%{pg:-L/usr/lib/libp}%{p:-L/usr/lib/libp}"
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{!shared:%{!symbolic:%{pg:gcrt0.o%s} \
@@ -176,7 +176,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Override svr4.h and m88k.h except when compiling crtstuff.c. These must
be constant strings when compiling crtstuff.c. Otherwise, respect the
-mversion-STRING option used. */
-#undef INIT_SECTION_PREAMBLE
#undef INIT_SECTION_ASM_OP
#undef FINI_SECTION_ASM_OP
#undef CTORS_SECTION_ASM_OP
@@ -196,12 +195,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
? "section\t .dtors,\"aw\"" \
: "section\t .dtors,\"d\"")
#else
-/* These must be constant strings for crtstuff.c.
- An elf and bcs crtbegin.o are needed since bcs does not
- increment the stack pointer in the init section as elf does */
-#ifndef BCS
-#define INIT_SECTION_PREAMBLE asm ("\taddu\tr31,r31,0x20")
-#endif
+/* These must be constant strings for crtstuff.c. */
#define INIT_SECTION_ASM_OP "section\t .init,\"x\""
#define FINI_SECTION_ASM_OP "section\t .fini,\"x\""
#define CTORS_SECTION_ASM_OP "section\t .ctors,\"d\""
diff --git a/gcc/config/m88k/sysv4.h b/gcc/config/m88k/sysv4.h
index 428c2cf..cb774a5 100644
--- a/gcc/config/m88k/sysv4.h
+++ b/gcc/config/m88k/sysv4.h
@@ -60,7 +60,25 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Override svr4.h and m88k.h. */
#undef INIT_SECTION_ASM_OP
#define INIT_SECTION_ASM_OP "section\t.init,\"xa\",#progbits"
+#undef FINI_SECTION_ASM_OP
+#define FINI_SECTION_ASM_OP "section\t.fini,\"xa\",#progbits"
+
+/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
+
+ Note that we want to give these sections the SHF_WRITE attribute
+ because these sections will actually contain data (i.e. tables of
+ addresses of functions in the current root executable or shared library
+ file) and, in the case of a shared library, the relocatable addresses
+ will have to be properly resolved/relocated (and then written into) by
+ the dynamic linker when it actually attaches the given shared library
+ to the executing process. (Note that on SVR4, you may wish to use the
+ `-z text' option to the ELF linker, when building a shared library, as
+ an additional check that you are doing everything right. But if you do
+ use the `-z text' option when building a shared library, you will get
+ errors unless the .ctors and .dtors sections are marked as writable
+ via the SHF_WRITE attribute.) */
+
#undef CTORS_SECTION_ASM_OP
-#define CTORS_SECTION_ASM_OP "section\t.ctors,\"a\",#progbits"
+#define CTORS_SECTION_ASM_OP "section\t.ctors,\"aw\""
#undef DTORS_SECTION_ASM_OP
-#define DTORS_SECTION_ASM_OP "section\t.dtors,\"a\",#progbits"
+#define DTORS_SECTION_ASM_OP "section\t.dtors,\"aw\""
diff --git a/gcc/config/m88k/t-sysv4 b/gcc/config/m88k/t-sysv4
index 419a9db..6a77edb 100644
--- a/gcc/config/m88k/t-sysv4
+++ b/gcc/config/m88k/t-sysv4
@@ -12,3 +12,11 @@ $(MOVE_ASM): $(srcdir)/config/m88k/m88k-move.sh
LIB2FUNCS_EXTRA = $(MOVE_ASM)
LIBGCC1 = libgcc1.null
CROSS_LIBGCC1 = libgcc1.null
+
+# We need to use -fpic when we are using gcc to compile the routines in
+# crtstuff.c. This is only really needed when we are going to use gcc/g++
+# to produce a shared library, but since we don't know ahead of time when
+# we will be doing that, we just always use -fpic when compiling the
+# routines in crtstuff.c.
+
+CRTSTUFF_T_CFLAGS=-fpic
diff --git a/gcc/config/mips/iris5.h b/gcc/config/mips/iris5.h
index 5b1987b..e1c40b1 100644
--- a/gcc/config/mips/iris5.h
+++ b/gcc/config/mips/iris5.h
@@ -34,6 +34,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
options, but using this would require modifying how crtstuff works, and
I will leave that for another time (or someone else). */
#define OBJECT_FORMAT_ELF
+#define HAS_INIT_SECTION
+#define LD_INIT_SWITCH "-init"
+#define LD_FINI_SWITCH "-fini"
/* Specify wchar_t types. */
#undef WCHAR_TYPE
@@ -82,12 +85,20 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
%{G*} %{EB} %{EL} %{mips1} %{mips2} %{mips3} \
%{bestGnum} %{shared} %{non_shared} \
%{call_shared} %{no_archive} %{exact_version} \
-%{!shared: %{!non_shared: \
+%{!shared: -u __main -init __main %{!non_shared: \
%{!call_shared: -call_shared -no_unresolved}}} \
-_SYSTYPE_SVR4"
+/* We now support shared libraries. */
+#undef STARTFILE_SPEC
+#define STARTFILE_SPEC \
+ "%{!shared:%{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s libprof1.a%s}%{!p:crt1.o%s}}}"
+
#undef LIB_SPEC
-#define LIB_SPEC "%{p:-lprof1} %{pg:-lprof1} -lc crtn.o%s"
+#define LIB_SPEC "%{!shared:%{p:-lprof1} %{pg:-lprof1} -lc}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "%{!shared:crtn.o%s}"
/* We do not want to run mips-tfile! */
#undef ASM_FINAL_SPEC
diff --git a/gcc/config/pa/pa-hpux.h b/gcc/config/pa/pa-hpux.h
index 66719e8..10fa503 100644
--- a/gcc/config/pa/pa-hpux.h
+++ b/gcc/config/pa/pa-hpux.h
@@ -36,13 +36,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define DEFAULT_GDB_EXTENSIONS 0
/* Like the default, except no -lg. */
-#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}"
+#define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}}"
#undef CPP_PREDEFINES
#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -D_HPUX_SOURCE -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)"
#undef LINK_SPEC
-#define LINK_SPEC "-u main %{static: -a archive}%{g*: -a archive}"
+#define LINK_SPEC \
+ "%{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
/* hpux8 and later have C++ compatable include files, so do not
pretend they are `extern "C"'. */
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index ceef67d7..0c9a217 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -196,7 +196,7 @@ extern int target_flags;
#define CC1_SPEC "%{pg:} %{p:}"
-#define LINK_SPEC "-u main"
+#define LINK_SPEC "%{!shared:-u main} %{shared:-b}"
/* Allow $ in identifiers. */
#define DOLLARS_IN_IDENTIFIERS 2
@@ -214,6 +214,22 @@ extern int target_flags;
/* Names to predefine in the preprocessor for this target machine. */
#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -D_HPUX_SOURCE -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Asystem(unix) -Asystem(bsd) -Acpu(hppa) -Amachine(hppa)"
+
+/* HPUX has a program 'chatr' to list the dependencies of dynamically
+ linked executables and shared libraries. */
+#define LDD_SUFFIX "chatr"
+/* look for lines like "dynamic /usr/lib/X11R5/libX11.sl". */
+#define PARSE_LDD_OUTPUT(PTR) \
+do { \
+ while (*PTR == ' ') PTR++; \
+ if (strncmp (PTR, "dynamic", sizeof ("dynamic") - 1) == 0) \
+ { \
+ PTR += sizeof ("dynamic") - 1; \
+ while (*p == ' ') PTR++; \
+ } \
+ else \
+ PTR = 0; \
+} while (0)
/* target machine storage layout */
diff --git a/gcc/config/sparc/sol2.h b/gcc/config/sparc/sol2.h
index e6856bc..0d05365 100644
--- a/gcc/config/sparc/sol2.h
+++ b/gcc/config/sparc/sol2.h
@@ -102,13 +102,13 @@ do { \
#define STARTFILE_SPEC "%{!shared: \
%{!symbolic: \
%{pg:crt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}} \
- %{pg:gmon.o%s} \
- %{pg:crti.o%s}%{!pg:crti.o%s} \
- %{ansi:/usr/ccs/lib/values-Xc.o%s} \
- %{!ansi: \
- %{traditional:/usr/ccs/lib/values-Xt.o%s} \
- %{!traditional:/usr/ccs/lib/values-Xa.o%s}}}} \
- crtbegin.o%s"
+ %{pg:gmon.o%s}}} \
+ %{pg:crti.o%s}%{!pg:crti.o%s} \
+ %{ansi:/usr/ccs/lib/values-Xc.o%s} \
+ %{!ansi: \
+ %{traditional:/usr/ccs/lib/values-Xt.o%s} \
+ %{!traditional:/usr/ccs/lib/values-Xa.o%s}} \
+ crtbegin.o%s"
/* ??? Note: in order for -compat-bsd to work fully,
we must somehow arrange to fixincludes /usr/ucbinclude
@@ -116,10 +116,10 @@ do { \
#undef LIB_SPEC
#define LIB_SPEC \
- "%{compat-bsd:-lucb -lsocket -lnsl -lelf -laio} \
- %{!shared:%{!symbolic:-lc}} \
- crtend.o%s \
- %{!shared:%{!symbolic:%{pg:crtn.o%s}%{!pg:crtn.o%s}}}"
+ "%{compat-bsd:-lucb -lsocket -lnsl -lelf -laio} %{!shared:%{!symbolic:-lc}}"
+
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend.o%s %{pg:crtn.o%s}%{!pg:crtn.o%s}"
/* This should be the same as in svr4.h, except with -R added. */
#undef LINK_SPEC
@@ -127,8 +127,8 @@ do { \
"%{h*} %{V} %{v:%{!V:-V}} \
%{b} %{Wl,*:%*} \
%{static:-dn -Bstatic} \
- %{shared:-G -dy} \
- %{symbolic:-Bsymbolic -G -dy} \
+ %{shared:-G -dy -z text} \
+ %{symbolic:-Bsymbolic -G -dy -z text} \
%{G:-G} \
%{YP,*} \
%{R*} \
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 674bdd2..80bdec2 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -60,12 +60,13 @@ extern enum arch_type sparc_arch_type;
-Asystem(unix) -Asystem(bsd) -Acpu(sparc) -Amachine(sparc)"
#endif
-#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} %{g:-lg}"
+#define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p} %{g:-lg}}"
/* Provide required defaults for linker -e and -d switches. */
#define LINK_SPEC \
- "%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp %{static:-Bstatic} %{assert*}"
+ "%{!shared:%{!nostdlib:%{!r*:%{!e*:-e start}}} -dc -dp} %{static:-Bstatic} \
+ %{assert*} %{shared:-assert pure-text}"
/* Special flags to the Sun-4 assembler when using pipe for input. */
@@ -445,6 +446,15 @@ extern int target_flags;
Put them in the data section. This macro is only used in this file. */
#define MAX_TEXT_ALIGN 32
+/* This forces all variables and constants to the data section when PIC.
+ This is because the SunOS 4 shared library scheme thinks everything in
+ text is a function, and patches the address to point to a loader stub. */
+/* This is defined to zero for every system which doesn't use the a.out object
+ file format. */
+#ifndef SUNOS4_SHARED_LIBRARIES
+#define SUNOS4_SHARED_LIBRARIES 0
+#endif
+
/* This is defined differently for v9 in a cover file. */
#define SELECT_SECTION(T,RELOC) \
{ \
@@ -455,20 +465,21 @@ extern int target_flags;
&& (DECL_INITIAL (T) == error_mark_node \
|| TREE_CONSTANT (DECL_INITIAL (T))) \
&& DECL_ALIGN (T) <= MAX_TEXT_ALIGN \
- && ! (flag_pic && (RELOC))) \
+ && ! (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES))) \
text_section (); \
else \
data_section (); \
} \
else if (TREE_CODE (T) == CONSTRUCTOR) \
{ \
- if (flag_pic != 0 && (RELOC) != 0) \
+ if (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES)) \
data_section (); \
} \
else if (*tree_code_type[(int) TREE_CODE (T)] == 'c') \
{ \
if ((TREE_CODE (T) == STRING_CST && flag_writable_strings) \
- || TYPE_ALIGN (TREE_TYPE (T)) > MAX_TEXT_ALIGN) \
+ || TYPE_ALIGN (TREE_TYPE (T)) > MAX_TEXT_ALIGN \
+ || (flag_pic && ((RELOC) || SUNOS4_SHARED_LIBRARIES))) \
data_section (); \
else \
text_section (); \
@@ -481,7 +492,7 @@ extern int target_flags;
#define SELECT_RTX_SECTION(MODE, X) \
{ \
if (GET_MODE_BITSIZE (MODE) <= MAX_TEXT_ALIGN \
- && ! (flag_pic && symbolic_operand (X))) \
+ && ! (flag_pic && (symbolic_operand (X) || SUNOS4_SHARED_LIBRARIES))) \
text_section (); \
else \
data_section (); \
diff --git a/gcc/config/sparc/sysv4.h b/gcc/config/sparc/sysv4.h
index f81a4f7..5a0f7a4 100644
--- a/gcc/config/sparc/sysv4.h
+++ b/gcc/config/sparc/sysv4.h
@@ -37,9 +37,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
appropriate only for typical svr4 systems, but not for the specific
case of svr4 running on a Sparc. */
-#undef CTORS_SECTION_ASM_OP
-#undef DTORS_SECTION_ASM_OP
#undef INIT_SECTION_ASM_OP
+#undef FINI_SECTION_ASM_OP
#undef CONST_SECTION_ASM_OP
#undef TYPE_OPERAND_FMT
#undef PUSHSECTION_FORMAT
@@ -77,24 +76,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
const_section (); \
}
-/* The specialized code which needs to appear in the .init section prior
- to the prologue code for `__do_global_ctors' (see crtstuff.c).
-
- On Sparcs running svr4, the /usr/ccs/lib/crti.o file (with gets linked
- in prior to the crtbegin.o file) has a single `save' instruction in its
- .init section. That `save' instruction tries to setup a stack frame for
- the sake of any subsequent code in the .init section. Unfortunately,
- the size it uses for the stack frame is only a guess, and is not really
- adequate for our purposes. More importantly, we independently put our
- own standard function prologue (for __do_global_ctors) into the .init
- section and that function prologue includes its own `save' instruction!
- Thus, unless we do something to correct the situation, we'll get *two*
- stack frames allocated when crt0.o calls the code in the .init section,
- and havoc will ensue. The following macro definition prevents such woes.
-*/
-
-#define INIT_SECTION_PREAMBLE asm ("restore")
-
/* This is the string used to begin an assembly language comment for the
Sparc/svr4 assembler. */
@@ -172,8 +153,27 @@ do { ASM_OUTPUT_ALIGN ((FILE), Pmode == SImode ? 2 : 3); \
#define BSS_SECTION_ASM_OP ".section\t\".bss\""
#define CONST_SECTION_ASM_OP ".section\t\".rodata\""
#define INIT_SECTION_ASM_OP ".section\t\".init\""
-#define CTORS_SECTION_ASM_OP ".section\t\".ctors\",#alloc,#execinstr"
-#define DTORS_SECTION_ASM_OP ".section\t\".dtors\",#alloc,#execinstr"
+#define FINI_SECTION_ASM_OP ".section\t\".fini\""
+
+/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
+
+ Note that we want to give these sections the SHF_WRITE attribute
+ because these sections will actually contain data (i.e. tables of
+ addresses of functions in the current root executable or shared library
+ file) and, in the case of a shared library, the relocatable addresses
+ will have to be properly resolved/relocated (and then written into) by
+ the dynamic linker when it actually attaches the given shared library
+ to the executing process. (Note that on SVR4, you may wish to use the
+ `-z text' option to the ELF linker, when building a shared library, as
+ an additional check that you are doing everything right. But if you do
+ use the `-z text' option when building a shared library, you will get
+ errors unless the .ctors and .dtors sections are marked as writable
+ via the SHF_WRITE attribute.) */
+
+#undef CTORS_SECTION_ASM_OP
+#define CTORS_SECTION_ASM_OP ".section\t\".ctors\",#alloc,#write"
+#undef DTORS_SECTION_ASM_OP
+#define DTORS_SECTION_ASM_OP ".section\t\".dtors\",#alloc,#write"
/* A C statement to output something to the assembler file to switch to section
NAME for object DECL which is either a FUNCTION_DECL, a VAR_DECL or
diff --git a/gcc/config/sparc/t-sol2 b/gcc/config/sparc/t-sol2
index 9f79b1f..1160c87 100644
--- a/gcc/config/sparc/t-sol2
+++ b/gcc/config/sparc/t-sol2
@@ -16,3 +16,11 @@ crti.o: $(srcdir)/config/sparc/sol2-ci.asm
$(AS) -o crti.o $(srcdir)/config/sparc/sol2-ci.asm
crtn.o: $(srcdir)/config/sparc/sol2-cn.asm
$(AS) -o crtn.o $(srcdir)/config/sparc/sol2-cn.asm
+
+# We need to use -fpic when we are using gcc to compile the routines in
+# crtstuff.c. This is only really needed when we are going to use gcc/g++
+# to produce a shared library, but since we don't know ahead of time when
+# we will be doing that, we just always use -fpic when compiling the
+# routines in crtstuff.c.
+
+CRTSTUFF_T_CFLAGS = -fpic
diff --git a/gcc/config/svr4.h b/gcc/config/svr4.h
index 663ff4b..5b40116 100644
--- a/gcc/config/svr4.h
+++ b/gcc/config/svr4.h
@@ -122,17 +122,25 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#define MD_STARTFILE_PREFIX "/usr/ccs/lib/"
/* Provide a LIB_SPEC appropriate for svr4. Here we tack on the default
- standard C library (unless we are building a shared library) followed by
- our own magical crtend.o file (see crtstuff.c) which provides part of
- the support for getting C++ file-scope static object constructed before
+ standard C library (unless we are building a shared library). */
+
+#undef LIB_SPEC
+#define LIB_SPEC "%{!shared:%{!symbolic:-lc}}"
+
+/* Provide a LIBGCC_SPEC appropriate for svr4. We also want to exclude
+ libgcc when -symbolic. */
+
+#undef LIBGCC_SPEC
+#define LIBGCC_SPEC "%{!shared:%{!symbolic:-lgcc}}"
+
+/* Provide an ENDFILE_SPEC appropriate for svr4. Here we tack on our own
+ magical crtend.o file (see crtstuff.c) which provides part of the
+ support for getting C++ file-scope static object constructed before
entering `main', followed by the normal svr3/svr4 "finalizer" file,
which is either `gcrtn.o' or `crtn.o'. */
-#undef LIB_SPEC
-#define LIB_SPEC \
- "%{!shared:%{!symbolic:-lc}} \
- crtend.o%s \
- %{!shared:%{!symbolic:%{pg:gcrtn.o}%{!pg:crtn.o%s}}}"
+#undef ENDFILE_SPEC
+#define ENDFILE_SPEC "crtend.o%s %{pg:gcrtn.o}%{!pg:crtn.o%s}"
/* Provide a LINK_SPEC appropriate for svr4. Here we provide support
for the special GCC options -static, -shared, and -symbolic which
@@ -161,8 +169,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#define LINK_SPEC "%{h*} %{V} %{v:%{!V:-V}} \
%{b} %{Wl,*:%*} \
%{static:-dn -Bstatic} \
- %{shared:-G -dy} \
- %{symbolic:-Bsymbolic -G -dy} \
+ %{shared:-G -dy -z text} \
+ %{symbolic:-Bsymbolic -G -dy -z text} \
%{G:-G} \
%{YP,*} \
%{!YP,*:%{p:-Y P,/usr/ccs/lib/libp:/usr/lib/libp:/usr/ccs/lib:/usr/lib} \
@@ -184,12 +192,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "%{!shared: \
%{!symbolic: \
- %{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}} \
- %{pg:gcrti.o%s}%{!pg:crti.o%s} \
- %{ansi:values-Xc.o%s} \
- %{!ansi: \
- %{traditional:values-Xt.o%s} \
- %{!traditional:values-Xa.o%s}}}} crtbegin.o%s"
+ %{pg:gcrt1.o%s}%{!pg:%{p:mcrt1.o%s}%{!p:crt1.o%s}}}}\
+ %{pg:gcrti.o%s}%{!pg:crti.o%s} \
+ %{ansi:values-Xc.o%s} \
+ %{!ansi: \
+ %{traditional:values-Xt.o%s} \
+ %{!traditional:values-Xa.o%s}} \
+ crtbegin.o%s"
/* Attach a special .ident directive to the end of the file to identify
the version of GCC which compiled this code. The format of the
@@ -468,16 +477,33 @@ do { \
#define USE_CONST_SECTION 1
#define CONST_SECTION_ASM_OP ".section\t.rodata"
-#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"a\",@progbits"
-#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"a\",@progbits"
-/* On svr4, we *do* have support for the .init section, and we can put
- stuff in there to be executed before `main'. We let crtstuff.c and
- other files know this by defining the following symbol. The definition
- says how to change sections to the .init section. This is the same
- for all know svr4 assemblers. */
+/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
+
+ Note that we want to give these sections the SHF_WRITE attribute
+ because these sections will actually contain data (i.e. tables of
+ addresses of functions in the current root executable or shared library
+ file) and, in the case of a shared library, the relocatable addresses
+ will have to be properly resolved/relocated (and then written into) by
+ the dynamic linker when it actually attaches the given shared library
+ to the executing process. (Note that on SVR4, you may wish to use the
+ `-z text' option to the ELF linker, when building a shared library, as
+ an additional check that you are doing everything right. But if you do
+ use the `-z text' option when building a shared library, you will get
+ errors unless the .ctors and .dtors sections are marked as writable
+ via the SHF_WRITE attribute.) */
+
+#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\""
+#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
+
+/* On svr4, we *do* have support for the .init and .fini sections, and we
+ can put stuff in there to be executed before and after `main'. We let
+ crtstuff.c and other files know this by defining the following symbols.
+ The definitions say how to change sections to the .init and .fini
+ sections. This is the same for all known svr4 assemblers. */
#define INIT_SECTION_ASM_OP ".section\t.init"
+#define FINI_SECTION_ASM_OP ".section\t.fini"
/* A default list of other sections which we might be "in" at any given
time. For targets that use additional sections (e.g. .tdesc) you
@@ -844,3 +870,6 @@ do { \
fprintf ((FILE), "\"\n"); \
} \
while (0)
+
+/* All SVR4 targets use the ELF object file format. */
+#define OBJECT_FORMAT_ELF
diff --git a/gcc/config/t-svr4 b/gcc/config/t-svr4
index 9560d90..f060a9d 100644
--- a/gcc/config/t-svr4
+++ b/gcc/config/t-svr4
@@ -2,3 +2,11 @@
# end labels to the .ctors and .dtors section when we link using gcc.
EXTRA_PARTS=crtbegin.o crtend.o
+
+# We need to use -fpic when we are using gcc to compile the routines in
+# crtstuff.c. This is only really needed when we are going to use gcc/g++
+# to produce a shared library, but since we don't know ahead of time when
+# we will be doing that, we just always use -fpic when compiling the
+# routines in crtstuff.c.
+
+CRTSTUFF_T_CFLAGS = -fpic
diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c
index dcfd819..bf1ddb4 100644
--- a/gcc/crtstuff.c
+++ b/gcc/crtstuff.c
@@ -54,23 +54,89 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "tm.h"
+/* Provide default definitions for the pseudo-ops used to switch to the
+ .ctors and .dtors sections.
+
+ Note that we want to give these sections the SHF_WRITE attribute
+ because these sections will actually contain data (i.e. tables of
+ addresses of functions in the current root executable or shared library
+ file) and, in the case of a shared library, the relocatable addresses
+ will have to be properly resolved/relocated (and then written into) by
+ the dynamic linker when it actually attaches the given shared library
+ to the executing process. (Note that on SVR4, you may wish to use the
+ `-z text' option to the ELF linker, when building a shared library, as
+ an additional check that you are doing everything right. But if you do
+ use the `-z text' option when building a shared library, you will get
+ errors unless the .ctors and .dtors sections are marked as writable
+ via the SHF_WRITE attribute.) */
+
#ifndef CTORS_SECTION_ASM_OP
-#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"a\",@progbits"
+#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\""
#endif
#ifndef DTORS_SECTION_ASM_OP
-#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"a\",@progbits"
+#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\""
#endif
+#ifdef OBJECT_FORMAT_ELF
+
+/* Declare a pointer to void function type. */
+typedef void (*func_ptr) (void);
+#define STATIC static
+
+#else /* OBJECT_FORMAT_ELF */
+
#include "gbl-ctors.h"
#ifndef ON_EXIT
#define ON_EXIT(a, b)
#endif
+#define STATIC
+
+#endif /* OBJECT_FORMAT_ELF */
#ifdef CRT_BEGIN
#ifdef INIT_SECTION_ASM_OP
+#ifdef OBJECT_FORMAT_ELF
+
+/* Run all the global destructors on exit from the program. */
+
+/* Some systems place the number of pointers in the first word of the
+ table. On SVR4 however, that word is -1. In all cases, the table is
+ null-terminated. On SVR4, we start from the beginning of the list and
+ invoke each per-compilation-unit destructor routine in order
+ until we find that null.
+
+ Note that this function MUST be static. There will be one of these
+ functions in each root executable and one in each shared library, but
+ although they all have the same code, each one is unique in that it
+ refers to one particular associated `__DTOR_LIST__' which belongs to the
+ same particular root executable or shared library file. */
+
+static func_ptr __DTOR_LIST__[];
+static void
+__do_global_dtors_aux ()
+{
+ func_ptr *p;
+ for (p = __DTOR_LIST__ + 1; *p; p++)
+ (*p) ();
+}
+
+/* Stick a call to __do_global_dtors_aux into the .fini section. */
+static void
+fini_dummy ()
+{
+ asm (FINI_SECTION_ASM_OP);
+ __do_global_dtors_aux ();
+#ifdef FORCE_FINI_SECTION_ALIGN
+ FORCE_FINI_SECTION_ALIGN;
+#endif
+ asm (TEXT_SECTION_ASM_OP);
+}
+
+#else /* OBJECT_FORMAT_ELF */
+
/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o
and once in crtend.o). It must be declared static to avoid a link
error. Here, we define __do_global_ctors as an externally callable
@@ -92,16 +158,6 @@ void __do_global_ctors ()
asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
-/* On some svr4 systems, the .init section preamble code provided in
- crti.o may do some evil things which we have to undo before we reach
- the function prologue code for __do_global_ctors (directly below).
- For such systems, define the macro INIT_SECTION_PREAMBLE to
- expand into the code needed to undo the actions of the crti.o file. */
-
-#ifdef INIT_SECTION_PREAMBLE
- INIT_SECTION_PREAMBLE;
-#endif
-
/* A routine to invoke all of the global constructors upon entry to the
program. We put this into the .init section (for systems that have
such a thing) so that we can properly perform the construction of
@@ -118,25 +174,38 @@ __do_global_ctors_aux () /* prologue goes in .init section */
ON_EXIT (__do_global_dtors, 0);
}
+#endif /* OBJECT_FORMAT_ELF */
#endif /* defined(INIT_SECTION_ASM_OP) */
/* Force cc1 to switch to .data section. */
static func_ptr force_to_data[0] = { };
+/* NOTE: In order to be able to support SVR4 shared libraries, we arrange
+ to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__,
+ __DTOR_END__ } per root executable and also one set of these symbols
+ per shared library. So in any given whole process image, we may have
+ multiple definitions of each of these symbols. In order to prevent
+ these definitions from conflicting with one another, and in order to
+ ensure that the proper lists are used for the initialization/finalization
+ of each individual shared library (respectively), we give these symbols
+ only internal (i.e. `static') linkage, and we also make it a point to
+ refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__
+ symbol in crtbegin.o, where they are defined. */
+
/* The -1 is a flag to __do_global_[cd]tors
indicating that this table does not start with a count of elements. */
#ifdef CTOR_LIST_BEGIN
CTOR_LIST_BEGIN;
#else
asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
-func_ptr __CTOR_LIST__[1] = { (func_ptr) (-1) };
+STATIC func_ptr __CTOR_LIST__[1] = { (func_ptr) (-1) };
#endif
#ifdef DTOR_LIST_BEGIN
DTOR_LIST_BEGIN;
#else
asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
-func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
+STATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
#endif
#endif /* defined(CRT_BEGIN) */
@@ -145,17 +214,51 @@ func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) };
#ifdef INIT_SECTION_ASM_OP
-/* A routine to invoke all of the global constructors upon entry to the
- program. We put this into the .init section (for systems that have
- such a thing) so that we can properly perform the construction of
- file-scope static-storage C++ objects within shared libraries.
+#ifdef OBJECT_FORMAT_ELF
- This must be virtually identical to the one above so that we can
- insure that the function prologue from the one above works correctly
- with the epilogue from this one. (They will both go into the .init
- section as the first and last things (respectively) that the linker
- will put in that section.)
-*/
+static func_ptr __CTOR_END__[];
+static void
+__do_global_ctors_aux ()
+{
+ func_ptr *p;
+ for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
+ (*p) ();
+}
+
+/* Stick a call to __do_global_ctors_aux into the .init section. */
+static void
+init_dummy ()
+{
+ asm (INIT_SECTION_ASM_OP);
+ __do_global_ctors_aux ();
+#ifdef FORCE_INIT_SECTION_ALIGN
+ FORCE_INIT_SECTION_ALIGN;
+#endif
+ asm (TEXT_SECTION_ASM_OP);
+}
+
+#else /* OBJECT_FORMAT_ELF */
+
+/* Stick the real initialization code, followed by a normal sort of
+ function epilogue at the very end of the .init section for this
+ entire root executable file or for this entire shared library file.
+
+ Note that we use some tricks here to get *just* the body and just
+ a function epilogue (but no function prologue) into the .init
+ section of the crtend.o file. Sepcifically, we switch to the .text
+ section, start to define a function, and then we switch to the .init
+ section just before the body code.
+
+ Earlier on, we put the corresponding function prologue into the .init
+ section of the crtbegin.o file (which will be linked in first).
+
+ Note that we want to invoke all constructors for C++ file-scope static-
+ storage objects AFTER any other possible initialization actions which
+ may be performed by the code in the .init section contributions made by
+ other libraries, etc. That's because those other initializations may
+ include setup operations for very primitive things (e.g. initializing
+ the state of the floating-point coprocessor, etc.) which should be done
+ before we start to execute any of the user's code. */
static void
__do_global_ctors_aux () /* prologue goes in .text section */
@@ -165,23 +268,31 @@ __do_global_ctors_aux () /* prologue goes in .text section */
ON_EXIT (__do_global_dtors, 0);
} /* epilogue and body go in .init section */
+#endif /* OBJECT_FORMAT_ELF */
+
#endif /* defined(INIT_SECTION_ASM_OP) */
/* Force cc1 to switch to .data section. */
static func_ptr force_to_data[0] = { };
+/* Put a word containing zero at the end of each of our two lists of function
+ addresses. Note that the words defined here go into the .ctors and .dtors
+ sections of the crtend.o file, and since that file is always linked in
+ last, these words naturally end up at the very ends of the two lists
+ contained in these two sections. */
+
#ifdef CTOR_LIST_END
CTOR_LIST_END;
#else
asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
-func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
+STATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 };
#endif
#ifdef DTOR_LIST_END
DTOR_LIST_END;
#else
asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */
-func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
+STATIC func_ptr __DTOR_END__[1] = { (func_ptr) 0 };
#endif
#endif /* defined(CRT_END) */
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 4f9e2c0..79ea185 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -362,6 +362,7 @@ or with constant text in a single argument.
If multilib_dir is set, extra entries are generated with it affixed.
%l process LINK_SPEC as a spec.
%L process LIB_SPEC as a spec.
+ %G process LIBGCC_SPEC as a spec.
%S process STARTFILE_SPEC as a spec. A capital S is actually used here.
%E process ENDFILE_SPEC as a spec. A capital E is actually used here.
%c process SIGNED_CHAR_SPEC as a spec.
@@ -458,7 +459,18 @@ proper position among the other output files. */
/* config.h can define LIB_SPEC to override the default libraries. */
#ifndef LIB_SPEC
-#define LIB_SPEC "%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
+#define LIB_SPEC "%{!shared:%{g*:-lg} %{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}}"
+#endif
+
+/* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
+ included. */
+#ifndef LIBGCC_SPEC
+#if defined(LINK_LIBGCC_SPECIAL) || defined(LINK_LIBGCC_SPECIAL_1)
+/* Have gcc do the search for libgcc.a. */
+#define LIBGCC_SPEC "%{!shared:libgcc.a%s}"
+#else
+#define LIBGCC_SPEC "%{!shared:-lgcc}"
+#endif
#endif
/* config.h can define STARTFILE_SPEC to override the default crt0 files. */
@@ -505,6 +517,7 @@ static char *asm_spec = ASM_SPEC;
static char *asm_final_spec = ASM_FINAL_SPEC;
static char *link_spec = LINK_SPEC;
static char *lib_spec = LIB_SPEC;
+static char *libgcc_spec = LIBGCC_SPEC;
static char *endfile_spec = ENDFILE_SPEC;
static char *startfile_spec = STARTFILE_SPEC;
static char *switches_need_spaces = SWITCHES_NEED_SPACES;
@@ -728,32 +741,22 @@ static int n_default_compilers
/* We want %{T*} after %{L*} and %D so that it can be used to specify linker
scripts which exist in user specified directories, or in standard
directories. */
-#ifdef LINK_LIBGCC_SPECIAL_1
-/* Have gcc do the search for libgcc.a, but generate -L options as usual. */
-static char *link_command_spec = "\
-%{!fsyntax-only: \
- %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
- %{r} %{s} %{t} %{u*} %{x} %{z} %{Z}\
- %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
- %{L*} %D %{T*} %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}";
-#else
#ifdef LINK_LIBGCC_SPECIAL
-/* Have gcc do the search for libgcc.a, and don't generate -L options. */
+/* Don't generate -L options. */
static char *link_command_spec = "\
%{!fsyntax-only: \
%{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
%{r} %{s} %{t} %{u*} %{x} %{z} %{Z}\
%{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
- %{L*} %{T*} %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}";
+ %{L*} %{T*} %o %{!nostdlib:%G %L %G %{!A:%E}}\n }}}}}}";
#else
-/* Use -L and have the linker do the search for -lgcc. */
+/* Use -L. */
static char *link_command_spec = "\
%{!fsyntax-only: \
%{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
%{r} %{s} %{t} %{u*} %{x} %{z} %{Z}\
%{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
- %{L*} %D %{T*} %o %{!nostdlib:-lgcc %L -lgcc %{!A:%E}}\n }}}}}}";
-#endif
+ %{L*} %D %{T*} %o %{!nostdlib:%G %L %G %{!A:%E}}\n }}}}}}";
#endif
/* A vector of options to give to the linker.
@@ -1229,6 +1232,8 @@ set_spec (name, spec)
endfile_spec = sl->spec;
else if (! strcmp (name, "lib"))
lib_spec = sl->spec;
+ else if (! strcmp (name, "libgcc"))
+ libgcc_spec = sl->spec;
else if (! strcmp (name, "link"))
link_spec = sl->spec;
else if (! strcmp (name, "predefines"))
@@ -2490,6 +2495,7 @@ process_command (argc, argv)
printf ("*endfile:\n%s\n\n", endfile_spec);
printf ("*link:\n%s\n\n", link_spec);
printf ("*lib:\n%s\n\n", lib_spec);
+ printf ("*libgcc:\n%s\n\n", libgcc_spec);
printf ("*startfile:\n%s\n\n", startfile_spec);
printf ("*switches_need_spaces:\n%s\n\n", switches_need_spaces);
printf ("*signed_char:\n%s\n\n", signed_char_spec);
@@ -3504,6 +3510,12 @@ do_spec_1 (spec, inswitch, soft_matched_part)
return value;
break;
+ case 'G':
+ value = do_spec_1 (libgcc_spec, 0, NULL_PTR);
+ if (value != 0)
+ return value;
+ break;
+
case 'p':
{
char *x = (char *) alloca (strlen (cpp_predefines) + 1);
@@ -4872,6 +4884,12 @@ validate_all_switches ()
/* We have a switch spec. */
validate_switches (p + 1);
+ p = libgcc_spec;
+ while (c = *p++)
+ if (c == '%' && *p == '{')
+ /* We have a switch spec. */
+ validate_switches (p + 1);
+
p = startfile_spec;
while (c = *p++)
if (c == '%' && *p == '{')
diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c
index 247b835..44b4de5 100644
--- a/gcc/libgcc2.c
+++ b/gcc/libgcc2.c
@@ -1996,6 +1996,7 @@ __enable_execute_stack ()
#define SYMBOL__MAIN __main
#endif
+#if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF)
/* Run all the global destructors on exit from the program. */
void
@@ -2009,6 +2010,7 @@ __do_global_dtors ()
(*p++) ();
#endif
}
+#endif
#ifndef INIT_SECTION_ASM_OP
/* Run all the global constructors on entry to the program. */
@@ -2112,41 +2114,6 @@ int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */
#endif /* L_exit */
-/* In a.out systems, we need to have these dummy constructor and destructor
- lists in the library.
-
- When using `collect', the first link will resolve __CTOR_LIST__
- and __DTOR_LIST__ to these symbols. We will then run "nm" on the
- result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
- Since we don't do the second link if no constructors existed, these
- dummies must be fully functional empty lists.
-
- When using `gnu ld', these symbols will be used if there are no
- constructors. If there are constructors, the N_SETV symbol defined
- by the linker from the N_SETT's in input files will define __CTOR_LIST__
- and __DTOR_LIST__ rather than its being allocated as common storage
- by the definitions below.
-
- When using a linker that supports constructor and destructor segments,
- these definitions will not be used, since crtbegin.o and crtend.o
- (from crtstuff.c) will have already defined __CTOR_LIST__ and
- __DTOR_LIST__. The crt*.o files are passed directly to the linker
- on its command line, by gcc. */
-
-/* The list needs two elements: one is ignored (the old count); the
- second is the terminating zero. Since both values are zero, this
- declaration is not initialized, and it becomes `common'. */
-
-#ifdef L_ctor_list
-#include "gbl-ctors.h"
-func_ptr __CTOR_LIST__[2];
-#endif
-
-#ifdef L_dtor_list
-#include "gbl-ctors.h"
-func_ptr __DTOR_LIST__[2];
-#endif
-
#ifdef L_eh
typedef struct {
void *start;