X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fcollect2.c;h=f4cc46aad504958e98365574f1d9b913ee0ff24a;hp=a8eaf11130988d94c97b1361ea57132201a671f5;hb=f9c6f14d623ddb87a40b7815a3b052d57a1f2c38;hpb=d66cc6a31125cb36fd37bd865593e0aa2b4a2aaf diff --git a/gcc/collect2.c b/gcc/collect2.c index a8eaf111309..f4cc46aad50 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 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005 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). @@ -20,8 +20,8 @@ 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, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ +Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301, USA. */ /* Build tables of static constructors and destructors and run ld. */ @@ -35,19 +35,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA # define SIGCHLD SIGCLD #endif -#ifdef vfork /* Autoconf may define this to fork for us. */ -# define VFORK_STRING "fork" -#else -# define VFORK_STRING "vfork" -#endif -#ifdef HAVE_VFORK_H -#include -#endif -#ifdef VMS -#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \ - lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1) -#endif /* VMS */ - #ifndef LIBRARY_PATH_ENV #define LIBRARY_PATH_ENV "LIBRARY_PATH" #endif @@ -185,6 +172,7 @@ static const char *demangle_flag; #ifdef COLLECT_EXPORT_LIST static int export_flag; /* true if -bE */ static int aix64_flag; /* true if -b64 */ +static int aixrtl_flag; /* true if -brtl */ #endif int debug; /* true if -debug */ @@ -196,7 +184,8 @@ static const char *o_file; /* .o for constructor/destructor list. */ #ifdef COLLECT_EXPORT_LIST static const char *export_file; /* .x for AIX export list. */ #endif -const char *ldout; /* File for ld errors. */ +const char *ldout; /* File for ld stdout. */ +const char *lderrout; /* File for ld stderr. */ static const char *output_file; /* Output file for ld. */ static const char *nm_file_name; /* pathname of nm */ #ifdef LDD_SUFFIX @@ -216,9 +205,6 @@ static struct head frame_tables; /* list of frame unwind info tables */ struct obstack temporary_obstack; char * temporary_firstobj; -/* Holds the return value of pexecute and fork. */ -int pid; - /* Structure to hold all the directories in which to search for files to execute. */ @@ -242,7 +228,6 @@ static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */ static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */ static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs, &libpath_lib_dirs, NULL}; -static const char *const libexts[3] = {"a", "so", NULL}; /* possible library extensions */ #endif static void handler (int); @@ -251,7 +236,7 @@ static char *find_a_file (struct path_prefix *, const char *); static void add_prefix (struct path_prefix *, const char *); static void prefix_from_env (const char *, struct path_prefix *); static void prefix_from_string (const char *, struct path_prefix *); -static void do_wait (const char *); +static void do_wait (const char *, struct pex_obj *); static void fork_execute (const char *, char **); static void maybe_unlink (const char *); static void add_to_list (struct head *, const char *); @@ -286,26 +271,6 @@ static char *resolve_lib_name (const char *); #endif static char *extract_string (const char **); -#ifndef HAVE_DUP2 -static int -dup2 (int oldfd, int newfd) -{ - int fdtmp[256]; - int fdx = 0; - int fd; - - if (oldfd == newfd) - return oldfd; - close (newfd); - while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */ - fdtmp[fdx++] = fd; - while (fdx > 0) - close (fdtmp[--fdx]); - - return fd; -} -#endif /* ! HAVE_DUP2 */ - /* Delete tempfiles and exit function. */ void @@ -324,10 +289,16 @@ collect_exit (int status) if (ldout != 0 && ldout[0]) { - dump_file (ldout); + dump_file (ldout, stdout); maybe_unlink (ldout); } + if (lderrout != 0 && lderrout[0]) + { + dump_file (lderrout, stderr); + maybe_unlink (lderrout); + } + if (status != 0 && output_file != 0 && output_file[0]) maybe_unlink (output_file); @@ -337,26 +308,26 @@ collect_exit (int status) /* Notify user of a non-error. */ void -notice (const char *msgid, ...) +notice (const char *cmsgid, ...) { va_list ap; - va_start (ap, msgid); - vfprintf (stderr, _(msgid), ap); + va_start (ap, cmsgid); + vfprintf (stderr, _(cmsgid), ap); va_end (ap); } /* Die when sys call fails. */ void -fatal_perror (const char * msgid, ...) +fatal_perror (const char * cmsgid, ...) { int e = errno; va_list ap; - va_start (ap, msgid); + va_start (ap, cmsgid); fprintf (stderr, "collect2: "); - vfprintf (stderr, _(msgid), ap); + vfprintf (stderr, _(cmsgid), ap); fprintf (stderr, ": %s\n", xstrerror (e)); va_end (ap); @@ -366,13 +337,13 @@ fatal_perror (const char * msgid, ...) /* Just die. */ void -fatal (const char * msgid, ...) +fatal (const char * cmsgid, ...) { va_list ap; - va_start (ap, msgid); + va_start (ap, cmsgid); fprintf (stderr, "collect2: "); - vfprintf (stderr, _(msgid), ap); + vfprintf (stderr, _(cmsgid), ap); fprintf (stderr, "\n"); va_end (ap); @@ -382,13 +353,13 @@ fatal (const char * msgid, ...) /* Write error message. */ void -error (const char * msgid, ...) +error (const char * gmsgid, ...) { va_list ap; - va_start (ap, msgid); + va_start (ap, gmsgid); fprintf (stderr, "collect2: "); - vfprintf (stderr, _(msgid), ap); + vfprintf (stderr, _(gmsgid), ap); fprintf (stderr, "\n"); va_end(ap); } @@ -414,13 +385,16 @@ handler (int signo) if (ldout != 0 && ldout[0]) maybe_unlink (ldout); + if (lderrout != 0 && lderrout[0]) + maybe_unlink (lderrout); + #ifdef COLLECT_EXPORT_LIST if (export_file != 0 && export_file[0]) maybe_unlink (export_file); #endif signal (signo, SIG_DFL); - kill (getpid (), signo); + raise (signo); } @@ -459,11 +433,11 @@ extract_string (const char **pp) obstack_1grow (&temporary_obstack, '\0'); *pp = p; - return obstack_finish (&temporary_obstack); + return XOBFINISH (&temporary_obstack, char *); } void -dump_file (const char *name) +dump_file (const char *name, FILE *to) { FILE *stream = fopen (name, "r"); @@ -480,10 +454,10 @@ dump_file (const char *name) const char *word, *p; char *result; obstack_1grow (&temporary_obstack, '\0'); - word = obstack_finish (&temporary_obstack); + word = XOBFINISH (&temporary_obstack, const char *); if (*word == '.') - ++word, putc ('.', stderr); + ++word, putc ('.', to); p = word; if (!strncmp (p, USER_LABEL_PREFIX, strlen (USER_LABEL_PREFIX))) p += strlen (USER_LABEL_PREFIX); @@ -500,25 +474,25 @@ dump_file (const char *name) if (result) { int diff; - fputs (result, stderr); + fputs (result, to); diff = strlen (word) - strlen (result); while (diff > 0 && c == ' ') - --diff, putc (' ', stderr); + --diff, putc (' ', to); while (diff < 0 && c == ' ') ++diff, c = getc (stream); free (result); } else - fputs (word, stderr); + fputs (word, to); - fflush (stderr); + fflush (to); obstack_free (&temporary_obstack, temporary_firstobj); } if (c == EOF) break; - putc (c, stderr); + putc (c, to); } fclose (stream); } @@ -837,6 +811,9 @@ main (int argc, char **argv) signal (SIGCHLD, SIG_DFL); #endif + /* Unlock the stdio streams. */ + unlock_std_streams (); + gcc_init_libintl (); /* Do not invoke xcalloc before this point, since locale needs to be @@ -1006,6 +983,7 @@ main (int argc, char **argv) export_file = make_temp_file (".x"); #endif ldout = make_temp_file (".ld"); + lderrout = make_temp_file (".le"); *c_ptr++ = c_file_name; *c_ptr++ = "-x"; *c_ptr++ = "c"; @@ -1087,6 +1065,8 @@ main (int argc, char **argv) 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') + aixrtl_flag = 1; break; #endif @@ -1097,6 +1077,11 @@ main (int argc, char **argv) ld1--; ld2--; } + if (!strcmp (arg, "-dynamic-linker") && argv[1]) + { + ++argv; + *ld1++ = *ld2++ = *argv; + } break; case 'l': @@ -1494,11 +1479,14 @@ main (int argc, char **argv) /* Wait for a process to finish, and exit if a nonzero status is found. */ int -collect_wait (const char *prog) +collect_wait (const char *prog, struct pex_obj *pex) { int status; - pwait (pid, &status, 0); + if (!pex_get_status (pex, 1, &status)) + fatal_perror ("can't get program status"); + pex_free (pex); + if (status) { if (WIFSIGNALED (status)) @@ -1517,9 +1505,9 @@ collect_wait (const char *prog) } static void -do_wait (const char *prog) +do_wait (const char *prog, struct pex_obj *pex) { - int ret = collect_wait (prog); + int ret = collect_wait (prog, pex); if (ret != 0) { error ("%s returned %d exit status", prog, ret); @@ -1530,14 +1518,13 @@ do_wait (const char *prog) /* Execute a program, and wait for the reply. */ -void -collect_execute (const char *prog, char **argv, const char *redir) +struct pex_obj * +collect_execute (const char *prog, char **argv, const char *outname, + const char *errname) { - char *errmsg_fmt; - char *errmsg_arg; - int redir_handle = -1; - int stdout_save = -1; - int stderr_save = -1; + struct pex_obj *pex; + const char *errmsg; + int err; if (vflag || debug) { @@ -1562,49 +1549,35 @@ collect_execute (const char *prog, char **argv, const char *redir) since we might not end up needing something that we could not find. */ if (argv[0] == 0) - fatal ("cannot find `%s'", prog); - - if (redir) - { - /* Open response file. */ - redir_handle = open (redir, O_WRONLY | O_TRUNC | O_CREAT); - - /* Duplicate the stdout and stderr file handles - so they can be restored later. */ - stdout_save = dup (STDOUT_FILENO); - if (stdout_save == -1) - fatal_perror ("redirecting stdout: %s", redir); - stderr_save = dup (STDERR_FILENO); - if (stderr_save == -1) - fatal_perror ("redirecting stdout: %s", redir); - - /* Redirect stdout & stderr to our response file. */ - dup2 (redir_handle, STDOUT_FILENO); - dup2 (redir_handle, STDERR_FILENO); - } + fatal ("cannot find '%s'", prog); - pid = pexecute (argv[0], argv, argv[0], NULL, &errmsg_fmt, &errmsg_arg, - (PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH)); + pex = pex_init (0, "collect2", NULL); + if (pex == NULL) + fatal_perror ("pex_init failed"); - if (redir) + errmsg = pex_run (pex, PEX_LAST | PEX_SEARCH, argv[0], argv, outname, + errname, &err); + if (errmsg != NULL) { - /* Restore stdout and stderr to their previous settings. */ - dup2 (stdout_save, STDOUT_FILENO); - dup2 (stderr_save, STDERR_FILENO); - - /* Close response file. */ - close (redir_handle); + if (err != 0) + { + errno = err; + fatal_perror (errmsg); + } + else + fatal (errmsg); } - if (pid == -1) - fatal_perror (errmsg_fmt, errmsg_arg); + return pex; } static void fork_execute (const char *prog, char **argv) { - collect_execute (prog, argv, NULL); - do_wait (prog); + struct pex_obj *pex; + + pex = collect_execute (prog, argv, NULL, NULL); + do_wait (prog, pex); } /* Unlink a file unless we are debugging. */ @@ -1613,7 +1586,7 @@ static void maybe_unlink (const char *file) { if (!debug) - unlink (file); + unlink_if_ordinary (file); else notice ("[Leaving %s]\n", file); } @@ -2026,11 +1999,15 @@ static void scan_prog_file (const char *prog_name, enum pass which_pass) { void (*int_handler) (int); +#ifdef SIGQUIT void (*quit_handler) (int); +#endif char *real_nm_argv[4]; const char **nm_argv = (const char **) real_nm_argv; int argc = 0; - int pipe_fd[2]; + struct pex_obj *pex; + const char *errmsg; + int err; char *p, buf[1024]; FILE *inf; @@ -2039,7 +2016,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass) /* If we do not have an `nm', complain. */ if (nm_file_name == 0) - fatal ("cannot find `nm'"); + fatal ("cannot find 'nm'"); nm_argv[argc++] = nm_file_name; if (NM_FLAGS[0] != '\0') @@ -2048,13 +2025,6 @@ scan_prog_file (const char *prog_name, enum pass which_pass) nm_argv[argc++] = prog_name; nm_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) { @@ -2070,35 +2040,30 @@ scan_prog_file (const char *prog_name, enum pass which_pass) fflush (stdout); fflush (stderr); - /* Spawn child nm on pipe. */ - pid = vfork (); - if (pid == -1) - fatal_perror (VFORK_STRING); + pex = pex_init (PEX_USE_PIPES, "collect2", NULL); + if (pex == NULL) + fatal_perror ("pex_init failed"); - if (pid == 0) /* child context */ + errmsg = pex_run (pex, 0, nm_file_name, real_nm_argv, NULL, NULL, &err); + if (errmsg != NULL) { - /* 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 (nm_file_name, real_nm_argv); - fatal_perror ("execv %s", nm_file_name); + if (err != 0) + { + errno = err; + fatal_perror (errmsg); + } + else + fatal (errmsg); } - /* Parent context from here on. */ int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN); #ifdef SIGQUIT quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN); #endif - if (close (pipe_fd[1]) < 0) - fatal_perror ("close %d", pipe_fd[1]); + inf = pex_read_output (pex, 0); + if (inf == NULL) + fatal_perror ("can't open nm output"); if (debug) fprintf (stderr, "\nnm output with constructors/destructors.\n"); @@ -2172,10 +2137,7 @@ scan_prog_file (const char *prog_name, enum pass which_pass) if (debug) fprintf (stderr, "\n"); - if (fclose (inf) != 0) - fatal_perror ("fclose"); - - do_wait (nm_file_name); + do_wait (nm_file_name, pex); signal (SIGINT, int_handler); #ifdef SIGQUIT @@ -2195,18 +2157,22 @@ scan_libraries (const char *prog_name) static struct head libraries; /* list of shared libraries found */ struct id *list; void (*int_handler) (int); +#ifdef SIGQUIT void (*quit_handler) (int); +#endif char *real_ldd_argv[4]; const char **ldd_argv = (const char **) real_ldd_argv; int argc = 0; - int pipe_fd[2]; + struct pex_obj *pex; + const char *errmsg; + int err; char buf[1024]; FILE *inf; /* If we do not have an `ldd', complain. */ if (ldd_file_name == 0) { - error ("cannot find `ldd'"); + error ("cannot find 'ldd'"); return; } @@ -2214,13 +2180,6 @@ scan_libraries (const char *prog_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) { @@ -2236,35 +2195,30 @@ scan_libraries (const char *prog_name) fflush (stdout); fflush (stderr); - /* Spawn child ldd on pipe. */ - pid = vfork (); - if (pid == -1) - fatal_perror (VFORK_STRING); + pex = pex_init (PEX_USE_PIPES, "collect2", NULL); + if (pex == NULL) + fatal_perror ("pex_init failed"); - if (pid == 0) /* child context */ + errmsg = pex_run (pex, 0, ldd_file_name, real_ldd_argv, NULL, NULL, &err); + if (errmsg != NULL) { - /* 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, real_ldd_argv); - fatal_perror ("execv %s", ldd_file_name); + if (err != 0) + { + errno = err; + fatal_perror (errmsg); + } + else + fatal (errmsg); } - /* Parent context from here on. */ int_handler = (void (*) (int)) signal (SIGINT, SIG_IGN); #ifdef SIGQUIT quit_handler = (void (*) (int)) signal (SIGQUIT, SIG_IGN); #endif - if (close (pipe_fd[1]) < 0) - fatal_perror ("close %d", pipe_fd[1]); + inf = pex_read_output (pex, 0); + if (inf == NULL) + fatal_perror ("can't open ldd output"); if (debug) notice ("\nldd output with constructors/destructors.\n"); @@ -2302,10 +2256,7 @@ scan_libraries (const char *prog_name) if (debug) fprintf (stderr, "\n"); - if (fclose (inf) != 0) - fatal_perror ("fclose"); - - do_wait (ldd_file_name); + do_wait (ldd_file_name, pex); signal (SIGINT, int_handler); #ifdef SIGQUIT @@ -2594,6 +2545,8 @@ resolve_lib_name (const char *name) { char *lib_buf; int i, j, l = 0; + /* Library extensions for AIX dynamic linking. */ + const char * const libexts[2] = {"a", "so"}; for (i = 0; libpaths[i]; i++) if (libpaths[i]->max_len > l) @@ -2612,14 +2565,15 @@ resolve_lib_name (const char *name) const char *p = ""; if (list->prefix[strlen(list->prefix)-1] != '/') p = "/"; - for (j = 0; libexts[j]; j++) + for (j = 0; j < 2; j++) { sprintf (lib_buf, "%s%slib%s.%s", - list->prefix, p, name, libexts[j]); -if (debug) fprintf (stderr, "searching for: %s\n", lib_buf); + list->prefix, p, name, + libexts[(j + aixrtl_flag) % 2]); + if (debug) fprintf (stderr, "searching for: %s\n", lib_buf); if (file_exists (lib_buf)) { -if (debug) fprintf (stderr, "found: %s\n", lib_buf); + if (debug) fprintf (stderr, "found: %s\n", lib_buf); return (lib_buf); } }