Shared library support.

From-SVN: r8519
This commit is contained in:
Jason Merrill 1994-11-19 04:09:58 +00:00
parent 822ef9dfda
commit 68d69835ac
21 changed files with 955 additions and 182 deletions

View file

@ -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.

View file

@ -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 */

View file

@ -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"

View file

@ -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*} \

View file

@ -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

View file

@ -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. */

View file

@ -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\""

View file

@ -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\""

View file

@ -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

View file

@ -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

View file

@ -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"'. */

View file

@ -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 */

View file

@ -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*} \

View file

@ -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 (); \

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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) */

View file

@ -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 == '{')

View file

@ -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;