X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcollect2.c;h=bba108d27491d895e72f4a23b57e7e726806c789;hp=d03d5a28d00896d55377d68b0925bd38036d97c3;hb=06f2e3c68e4f31e2efca41ecee92c441acfc044d;hpb=4c36ffe68d981c213d168cf07f42dcc558bc7f1b
diff --git a/gcc/collect2.c b/gcc/collect2.c
index d03d5a28d00..bba108d2749 100644
--- a/gcc/collect2.c
+++ b/gcc/collect2.c
@@ -1,7 +1,7 @@
/* Collect static initialization info into data structures that can be
traversed by C++ initialization and finalization routines.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc.
Contributed by Chris Smith (csmith@convex.com).
Heavily modified by Michael Meissner (meissner@cygnus.com),
Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@cygnus.com).
@@ -10,7 +10,7 @@ This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -19,9 +19,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA. */
+along with GCC; see the file COPYING3. If not see
+. */
/* Build tables of static constructors and destructors and run ld. */
@@ -53,7 +52,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
the utilities are not correct for a cross-compiler; we have to hope that
cross-versions are in the proper directories. */
-#ifdef CROSS_COMPILE
+#ifdef CROSS_DIRECTORY_STRUCTURE
#undef OBJECT_FORMAT_COFF
#undef MD_EXEC_PREFIX
#undef REAL_LD_FILE_NAME
@@ -130,6 +129,10 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#define SCAN_LIBRARIES
#endif
+#ifndef SHLIB_SUFFIX
+#define SHLIB_SUFFIX ".so"
+#endif
+
#ifdef USE_COLLECT2
int do_collecting = 1;
#else
@@ -161,7 +164,7 @@ struct head
enum pass {
PASS_FIRST, /* without constructors */
PASS_OBJ, /* individual objects */
- PASS_LIB, /* looking for shared libraries */
+ PASS_LIB, /* looking for shared libraries */
PASS_SECOND /* with constructors linked in */
};
@@ -177,12 +180,12 @@ static int aixrtl_flag; /* true if -brtl */
int debug; /* true if -debug */
-static int shared_obj; /* true if -shared */
+static int shared_obj; /* true if -shared */
static const char *c_file; /* .c for constructor/destructor list. */
static const char *o_file; /* .o for constructor/destructor list. */
#ifdef COLLECT_EXPORT_LIST
-static const char *export_file; /* .x for AIX export list. */
+static const char *export_file; /* .x for AIX export list. */
#endif
const char *ldout; /* File for ld stdout. */
const char *lderrout; /* File for ld stderr. */
@@ -192,7 +195,7 @@ static const char *nm_file_name; /* pathname of nm */
static const char *ldd_file_name; /* pathname of ldd (or equivalent) */
#endif
static const char *strip_file_name; /* pathname of strip */
-const char *c_file_name; /* pathname of gcc */
+const char *c_file_name; /* pathname of gcc */
static char *initname, *fininame; /* names of init and fini funcs */
static struct head constructors; /* list of constructors found */
@@ -202,6 +205,9 @@ static struct head exports; /* list of exported symbols */
#endif
static struct head frame_tables; /* list of frame unwind info tables */
+static bool at_file_supplied; /* Whether to use @file arguments */
+static char *response_file; /* Name of any current response file */
+
struct obstack temporary_obstack;
char * temporary_firstobj;
@@ -302,6 +308,9 @@ collect_exit (int status)
if (status != 0 && output_file != 0 && output_file[0])
maybe_unlink (output_file);
+ if (response_file)
+ maybe_unlink (response_file);
+
exit (status);
}
@@ -393,6 +402,9 @@ handler (int signo)
maybe_unlink (export_file);
#endif
+ if (response_file)
+ maybe_unlink (response_file);
+
signal (signo, SIG_DFL);
raise (signo);
}
@@ -479,8 +491,18 @@ dump_file (const char *name, FILE *to)
diff = strlen (word) - strlen (result);
while (diff > 0 && c == ' ')
--diff, putc (' ', to);
- while (diff < 0 && c == ' ')
- ++diff, c = getc (stream);
+ if (diff < 0 && c == ' ')
+ {
+ while (diff < 0 && c == ' ')
+ ++diff, c = getc (stream);
+ if (!ISSPACE (c))
+ {
+ /* Make sure we output at least one space, or
+ the demangled symbol name will run into
+ whatever text follows. */
+ putc (' ', to);
+ }
+ }
free (result);
}
@@ -553,7 +575,7 @@ is_ctor_dtor (const char *s)
static struct path_prefix cpath, path;
-#ifdef CROSS_COMPILE
+#ifdef CROSS_DIRECTORY_STRUCTURE
/* This is the name of the target machine. We use it to form the name
of the files to execute. */
@@ -728,6 +750,7 @@ prefix_from_string (const char *p, struct path_prefix *pprefix)
else
endp++;
}
+ free (nstore);
}
/* Main program. */
@@ -746,7 +769,7 @@ main (int argc, char **argv)
static const char *const strip_suffix = "strip";
static const char *const gstrip_suffix = "gstrip";
-#ifdef CROSS_COMPILE
+#ifdef CROSS_DIRECTORY_STRUCTURE
/* If we look for a program in the compiler directories, we just use
the short name, since these directories are already system-specific.
But it we look for a program in the system directories, we need to
@@ -775,7 +798,7 @@ main (int argc, char **argv)
#endif
const char *const full_strip_suffix = strip_suffix;
const char *const full_gstrip_suffix = gstrip_suffix;
-#endif /* CROSS_COMPILE */
+#endif /* CROSS_DIRECTORY_STRUCTURE */
const char *arg;
FILE *outf;
@@ -793,7 +816,15 @@ main (int argc, char **argv)
char **object_lst;
const char **object;
int first_file;
- int num_c_args = argc+9;
+ int num_c_args;
+ char **old_argv;
+
+ old_argv = argv;
+ expandargv (&argc, &argv);
+ if (argv != old_argv)
+ at_file_supplied = 1;
+
+ num_c_args = argc + 9;
no_demangle = !! getenv ("COLLECT_NO_DEMANGLE");
@@ -957,7 +988,7 @@ main (int argc, char **argv)
c_file_name = getenv ("COLLECT_GCC");
if (c_file_name == 0)
{
-#ifdef CROSS_COMPILE
+#ifdef CROSS_DIRECTORY_STRUCTURE
c_file_name = concat (target_machine, "-gcc", NULL);
#else
c_file_name = "gcc";
@@ -1062,7 +1093,7 @@ main (int argc, char **argv)
explicitly puts an export list in command line */
case 'b':
if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0)
- export_flag = 1;
+ export_flag = 1;
else if (arg[2] == '6' && arg[3] == '4')
aix64_flag = 1;
else if (arg[2] == 'r' && arg[3] == 't' && arg[4] == 'l')
@@ -1078,7 +1109,7 @@ main (int argc, char **argv)
ld2--;
}
if (!strcmp (arg, "-dynamic-linker") && argv[1])
- {
+ {
++argv;
*ld1++ = *ld2++ = *argv;
}
@@ -1095,7 +1126,7 @@ main (int argc, char **argv)
}
#ifdef COLLECT_EXPORT_LIST
{
- /* Resolving full library name. */
+ /* Resolving full library name. */
const char *s = resolve_lib_name (arg+2);
/* Saving a full library name. */
@@ -1205,8 +1236,8 @@ main (int argc, char **argv)
else
{
/* Saving a full library name. */
- add_to_list (&libs, arg);
- }
+ add_to_list (&libs, arg);
+ }
#endif
}
}
@@ -1513,6 +1544,12 @@ do_wait (const char *prog, struct pex_obj *pex)
error ("%s returned %d exit status", prog, ret);
collect_exit (ret);
}
+
+ if (response_file)
+ {
+ unlink (response_file);
+ response_file = NULL;
+ }
}
@@ -1525,6 +1562,47 @@ collect_execute (const char *prog, char **argv, const char *outname,
struct pex_obj *pex;
const char *errmsg;
int err;
+ char *response_arg = NULL;
+ char *response_argv[3] ATTRIBUTE_UNUSED;
+
+ if (HAVE_GNU_LD && at_file_supplied && argv[0] != NULL)
+ {
+ /* If using @file arguments, create a temporary file and put the
+ contents of argv into it. Then change argv to an array corresponding
+ to a single argument @FILE, where FILE is the temporary filename. */
+
+ char **current_argv = argv + 1;
+ char *argv0 = argv[0];
+ int status;
+ FILE *f;
+
+ /* Note: we assume argv contains at least one element; this is
+ checked above. */
+
+ response_file = make_temp_file ("");
+
+ f = fopen (response_file, "w");
+
+ if (f == NULL)
+ fatal ("could not open response file %s", response_file);
+
+ status = writeargv (current_argv, f);
+
+ if (status)
+ fatal ("could not write to response file %s", response_file);
+
+ status = fclose (f);
+
+ if (EOF == status)
+ fatal ("could not close response file %s", response_file);
+
+ response_arg = concat ("@", response_file, NULL);
+ response_argv[0] = argv0;
+ response_argv[1] = response_arg;
+ response_argv[2] = NULL;
+
+ argv = response_argv;
+ }
if (vflag || debug)
{
@@ -1568,6 +1646,9 @@ collect_execute (const char *prog, char **argv, const char *outname,
fatal (errmsg);
}
+ if (response_arg)
+ free (response_arg);
+
return pex;
}
@@ -1670,7 +1751,7 @@ sort_ids (struct head *head_ptr)
|| id->sequence > (*id_ptr)->sequence
/* Hack: do lexical compare, too.
|| (id->sequence == (*id_ptr)->sequence
- && strcmp (id->name, (*id_ptr)->name) > 0) */
+ && strcmp (id->name, (*id_ptr)->name) > 0) */
)
{
id->next = *id_ptr;
@@ -1791,9 +1872,9 @@ write_c_file_stat (FILE *stream, const char *name ATTRIBUTE_UNUSED)
}
else
{
- if (strncmp (q, ".so", 3) == 0)
+ if (strncmp (q, SHLIB_SUFFIX, strlen (SHLIB_SUFFIX)) == 0)
{
- q += 3;
+ q += strlen (SHLIB_SUFFIX);
break;
}
else
@@ -2246,7 +2327,7 @@ scan_libraries (const char *prog_name)
*end = '\0';
if (access (name, R_OK) == 0)
- add_to_list (&libraries, name);
+ add_to_list (&libraries, name);
else
fatal ("unable to open dynamic dependency '%s'", buf);
@@ -2296,20 +2377,20 @@ scan_libraries (const char *prog_name)
# if defined (C_WEAKEXT)
# define GCC_OK_SYMBOL(X) \
(((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
- ((X).n_scnum > N_UNDEF) && \
- (aix64_flag \
- || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
- || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
+ ((X).n_scnum > N_UNDEF) && \
+ (aix64_flag \
+ || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
+ || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
# define GCC_UNDEF_SYMBOL(X) \
(((X).n_sclass == C_EXT || (X).n_sclass == C_WEAKEXT) && \
- ((X).n_scnum == N_UNDEF))
+ ((X).n_scnum == N_UNDEF))
# else
# define GCC_OK_SYMBOL(X) \
(((X).n_sclass == C_EXT) && \
- ((X).n_scnum > N_UNDEF) && \
- (aix64_flag \
- || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
- || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
+ ((X).n_scnum > N_UNDEF) && \
+ (aix64_flag \
+ || (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) \
+ || ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))))
# define GCC_UNDEF_SYMBOL(X) \
(((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF))
# endif
@@ -2398,9 +2479,9 @@ scan_prog_file (const char *prog_name, enum pass which_pass)
{
#endif
/* Some platforms (e.g. OSF4) declare ldopen as taking a
- non-const char * filename parameter, even though it will not
- modify that string. So we must cast away const-ness here,
- which will cause -Wcast-qual to burp. */
+ non-const char * filename parameter, even though it will not
+ modify that string. So we must cast away const-ness here,
+ which will cause -Wcast-qual to burp. */
if ((ldptr = ldopen ((char *)prog_name, ldptr)) != NULL)
{
if (! MY_ISCOFF (HEADER (ldptr).f_magic))