Shared library support.
From-SVN: r8519
This commit is contained in:
parent
822ef9dfda
commit
68d69835ac
21 changed files with 955 additions and 182 deletions
|
@ -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.
|
||||
|
|
565
gcc/collect2.c
565
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 */
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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*} \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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\""
|
||||
|
|
|
@ -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\""
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"'. */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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*} \
|
||||
|
|
|
@ -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 (); \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
163
gcc/crtstuff.c
163
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) */
|
||||
|
|
48
gcc/gcc.c
48
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 == '{')
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue