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