diff options
author | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-06-26 09:16:11 +0000 |
---|---|---|
committer | bernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-06-26 09:16:11 +0000 |
commit | eb9ccb017b3efc536a6ccacbc61c9736cac7cecf (patch) | |
tree | 7149ab9414fb61c620960a84164a685ca78e72d8 | |
parent | 334e3c3ae5777fea241fca82816bd69b6cbcb298 (diff) | |
download | gcc-eb9ccb017b3efc536a6ccacbc61c9736cac7cecf.tar.gz |
Make a collect-utils library for use by tools like collect2 and lto-wrapper.
* Makefile.in (ALL_HOST_BACKEND_OBJS): Add collect-utils.o.
(lto-wrapper$(exeext)): Link with collect-utils.o.
* collect-utils.c: New file.
* collect-utils.h: New file.
* lto-wrapper.c: Include "collect-utils.h".
(args_name): Delete variable.
(tool_name): New variable.
(tool_cleanup): New function.
(maybe_unlink): Renamed from maybe_unlink_file. All callers changed.
(lto_wrapper_cleanup, fatal_signal, collect_execute, collect_wait,
fork_execute): Remove functions.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@212018 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/Makefile.in | 7 | ||||
-rw-r--r-- | gcc/collect-utils.c | 222 | ||||
-rw-r--r-- | gcc/collect-utils.h | 40 | ||||
-rw-r--r-- | gcc/lto-wrapper.c | 171 |
5 files changed, 298 insertions, 156 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9b975ce09a3..2e1ff3fa71d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2014-06-26 Bernd Schmidt <bernds@codesourcery.com> + + * Makefile.in (ALL_HOST_BACKEND_OBJS): Add collect-utils.o. + (lto-wrapper$(exeext)): Link with collect-utils.o. + * collect-utils.c: New file. + * collect-utils.h: New file. + * lto-wrapper.c: Include "collect-utils.h". + (args_name): Delete variable. + (tool_name): New variable. + (tool_cleanup): New function. + (maybe_unlink): Renamed from maybe_unlink_file. All callers changed. + (lto_wrapper_cleanup, fatal_signal, collect_execute, collect_wait, + fork_execute): Remove functions. + 2014-06-26 Nick Clifton <nickc@redhat.com> * config/frv/frv.c (frv_in_small_data_p): Remove redundant assert. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index c9502736a83..51b4c292bb8 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1491,7 +1491,7 @@ ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS)) ALL_HOST_BACKEND_OBJS = $(GCC_OBJS) $(OBJS) $(OBJS-libcommon) \ $(OBJS-libcommon-target) @TREEBROWSER@ main.o c-family/cppspec.o \ $(COLLECT2_OBJS) $(EXTRA_GCC_OBJS) $(GCOV_OBJS) $(GCOV_DUMP_OBJS) \ - lto-wrapper.o + lto-wrapper.o collect-utils.o # This lists all host object files, whether they are included in this # compilation or not. @@ -1910,9 +1910,10 @@ collect2$(exeext): $(COLLECT2_OBJS) $(LIBDEPS) CFLAGS-collect2.o += -DTARGET_MACHINE=\"$(target_noncanonical)\" \ @TARGET_SYSTEM_ROOT_DEFINE@ -lto-wrapper$(exeext): lto-wrapper.o ggc-none.o libcommon-target.a $(LIBDEPS) +LTO_WRAPPER_OBJS = lto-wrapper.o collect-utils.o ggc-none.o +lto-wrapper$(exeext): $(LTO_WRAPPER_OBJS) libcommon-target.a $(LIBDEPS) +$(LINKER) $(ALL_COMPILERFLAGS) $(LDFLAGS) -o T$@ \ - lto-wrapper.o ggc-none.o libcommon-target.a $(LIBS) + $(LTO_WRAPPER_OBJS) libcommon-target.a $(LIBS) mv -f T$@ $@ # Files used by all variants of C or by the stand-alone pre-processor. diff --git a/gcc/collect-utils.c b/gcc/collect-utils.c new file mode 100644 index 00000000000..004569c9957 --- /dev/null +++ b/gcc/collect-utils.c @@ -0,0 +1,222 @@ +/* Utility functions used by tools like collect2 and lto-wrapper. + Copyright (C) 2009-2014 Free Software Foundation, Inc. + +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 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "intl.h" +#include "diagnostic.h" +#include "obstack.h" +#include "opts.h" +#include "options.h" +#include "simple-object.h" +#include "lto-section-names.h" +#include "collect-utils.h" + +static char *response_file; + +bool debug; +bool verbose; + +/* Delete tempfiles. */ + +void +utils_cleanup (void) +{ + static bool cleanup_done = false; + + if (cleanup_done) + return; + + /* Setting cleanup_done prevents an infinite loop if one of the + calls to maybe_unlink fails. */ + cleanup_done = true; + + if (response_file) + maybe_unlink (response_file); + tool_cleanup (); +} + +/* Notify user of a non-error. */ +void +notice (const char *cmsgid, ...) +{ + va_list ap; + + va_start (ap, cmsgid); + vfprintf (stderr, _(cmsgid), ap); + va_end (ap); +} + +void +fatal_signal (int signum) +{ + signal (signum, SIG_DFL); + utils_cleanup (); + /* Get the same signal again, this time not handled, + so its normal effect occurs. */ + kill (getpid (), signum); +} + +/* Execute a program, and wait for the reply. ARGV are the arguments. The + last one must be NULL. */ + +struct pex_obj * +collect_execute (char **argv) +{ + struct pex_obj *pex; + const char *errmsg; + int err; + + if (verbose) + { + char **p_argv; + const char *str; + + for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++) + fprintf (stderr, " %s", str); + + fprintf (stderr, "\n"); + } + + fflush (stdout); + fflush (stderr); + + pex = pex_init (0, tool_name, NULL); + if (pex == NULL) + fatal_error ("pex_init failed: %m"); + + /* Do not use PEX_LAST here, we use our stdout for communicating with + collect2 or the linker-plugin. Any output from the sub-process + will confuse that. */ + errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL, + NULL, &err); + if (errmsg != NULL) + { + if (err != 0) + { + errno = err; + fatal_error ("%s: %m", _(errmsg)); + } + else + fatal_error (errmsg); + } + + return pex; +} + + +/* Wait for a process to finish, and exit if a nonzero status is found. + PROG is the program name. PEX is the process we should wait for. */ + +int +collect_wait (const char *prog, struct pex_obj *pex) +{ + int status; + + if (!pex_get_status (pex, 1, &status)) + fatal_error ("can't get program status: %m"); + pex_free (pex); + + if (status) + { + if (WIFSIGNALED (status)) + { + int sig = WTERMSIG (status); + if (WCOREDUMP (status)) + fatal_error ("%s terminated with signal %d [%s], core dumped", + prog, sig, strsignal (sig)); + else + fatal_error ("%s terminated with signal %d [%s]", + prog, sig, strsignal (sig)); + } + + if (WIFEXITED (status)) + fatal_error ("%s returned %d exit status", prog, WEXITSTATUS (status)); + } + + return 0; +} + +void +do_wait (const char *prog, struct pex_obj *pex) +{ + int ret = collect_wait (prog, pex); + if (ret != 0) + { + error ("%s returned %d exit status", prog, ret); + exit (ret); + } + + if (response_file && !debug) + { + unlink (response_file); + response_file = NULL; + } +} + +/* Unlink a temporary LTRANS file unless requested otherwise. */ + +void +maybe_unlink_file (const char *file) +{ + if (!debug) + { + if (unlink_if_ordinary (file) + && errno != ENOENT) + fatal_error ("deleting file %s: %m", file); + } + else + fprintf (stderr, "[Leaving %s]\n", file); +} + + +/* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */ + +void +fork_execute (char **argv) +{ + struct pex_obj *pex; + char *new_argv[3]; + char *at_args; + FILE *args; + int status; + + response_file = make_temp_file (".args"); + at_args = concat ("@", response_file, NULL); + args = fopen (response_file, "w"); + if (args == NULL) + fatal_error ("failed to open %s", response_file); + + status = writeargv (&argv[1], args); + + if (status) + fatal_error ("could not write to temporary file %s", response_file); + + fclose (args); + + new_argv[0] = argv[0]; + new_argv[1] = at_args; + new_argv[2] = NULL; + + pex = collect_execute (new_argv); + do_wait (new_argv[0], pex); + + free (at_args); +} diff --git a/gcc/collect-utils.h b/gcc/collect-utils.h new file mode 100644 index 00000000000..e47ab294c16 --- /dev/null +++ b/gcc/collect-utils.h @@ -0,0 +1,40 @@ +/* Utility functions used by tools like collect2 and lto-wrapper. + Copyright (C) 2009-2014 Free Software Foundation, Inc. + +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 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +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 COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +/* Provided in collect-utils.c. */ +extern void notice (const char *, ...) + __attribute__ ((format (printf, 1, 2))); +extern void fatal_signal (int); + +extern struct pex_obj *collect_execute (char **); +extern int collect_wait (const char *, struct pex_obj *); +extern void do_wait (const char *, struct pex_obj *); +extern void fork_execute (char **); +extern void utils_cleanup (void); + +extern bool debug; +extern bool verbose; + +/* Provided by the tool itself. */ + +/* The name of the tool, printed in error messages. */ +extern const char tool_name[]; +/* Called by utils_cleanup. */ +extern void tool_cleanup (void); +extern void maybe_unlink (const char *); diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index f42b14efd5d..45ce32157c8 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -47,9 +47,7 @@ along with GCC; see the file COPYING3. If not see #include "options.h" #include "simple-object.h" #include "lto-section-names.h" - -int debug; /* true if -save-temps. */ -int verbose; /* true if -v. */ +#include "collect-utils.h" enum lto_mode_d { LTO_MODE_NONE, /* Not doing LTO. */ @@ -62,140 +60,44 @@ static enum lto_mode_d lto_mode = LTO_MODE_NONE; static char *ltrans_output_file; static char *flto_out; -static char *args_name; static unsigned int nr; static char **input_names; static char **output_names; static char *makefile; -static void maybe_unlink_file (const char *); +const char tool_name[] = "lto-wrapper"; - /* Delete tempfiles. */ +/* Delete tempfiles. Called from utils_cleanup. */ -static void -lto_wrapper_cleanup (void) +void +tool_cleanup (void) { - static bool cleanup_done = false; unsigned int i; - if (cleanup_done) - return; - - /* Setting cleanup_done prevents an infinite loop if one of the - calls to maybe_unlink_file fails. */ - cleanup_done = true; - if (ltrans_output_file) - maybe_unlink_file (ltrans_output_file); + maybe_unlink (ltrans_output_file); if (flto_out) - maybe_unlink_file (flto_out); - if (args_name) - maybe_unlink_file (args_name); + maybe_unlink (flto_out); if (makefile) - maybe_unlink_file (makefile); + maybe_unlink (makefile); for (i = 0; i < nr; ++i) { - maybe_unlink_file (input_names[i]); + maybe_unlink (input_names[i]); if (output_names[i]) - maybe_unlink_file (output_names[i]); + maybe_unlink (output_names[i]); } } static void -fatal_signal (int signum) -{ - signal (signum, SIG_DFL); - lto_wrapper_cleanup (); - /* Get the same signal again, this time not handled, - so its normal effect occurs. */ - kill (getpid (), signum); -} - -/* Execute a program, and wait for the reply. ARGV are the arguments. The - last one must be NULL. */ - -static struct pex_obj * -collect_execute (char **argv) -{ - struct pex_obj *pex; - const char *errmsg; - int err; - - if (verbose) - { - char **p_argv; - const char *str; - - for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++) - fprintf (stderr, " %s", str); - - fprintf (stderr, "\n"); - } - - fflush (stdout); - fflush (stderr); - - pex = pex_init (0, "lto-wrapper", NULL); - if (pex == NULL) - fatal_error ("pex_init failed: %m"); - - /* Do not use PEX_LAST here, we use our stdout for communicating with - collect2 or the linker-plugin. Any output from the sub-process - will confuse that. */ - errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL, - NULL, &err); - if (errmsg != NULL) - { - if (err != 0) - { - errno = err; - fatal_error ("%s: %m", _(errmsg)); - } - else - fatal_error (errmsg); - } - - return pex; -} - - -/* Wait for a process to finish, and exit if a nonzero status is found. - PROG is the program name. PEX is the process we should wait for. */ - -static int -collect_wait (const char *prog, struct pex_obj *pex) +lto_wrapper_cleanup (void) { - int status; - - if (!pex_get_status (pex, 1, &status)) - fatal_error ("can't get program status: %m"); - pex_free (pex); - - if (status) - { - if (WIFSIGNALED (status)) - { - int sig = WTERMSIG (status); - if (WCOREDUMP (status)) - fatal_error ("%s terminated with signal %d [%s], core dumped", - prog, sig, strsignal (sig)); - else - fatal_error ("%s terminated with signal %d [%s]", - prog, sig, strsignal (sig)); - } - - if (WIFEXITED (status)) - fatal_error ("%s returned %d exit status", prog, WEXITSTATUS (status)); - } - - return 0; + utils_cleanup (); } - /* Unlink a temporary LTRANS file unless requested otherwise. */ -static void -maybe_unlink_file (const char *file) +void +maybe_unlink (const char *file) { if (! debug) { @@ -207,43 +109,6 @@ maybe_unlink_file (const char *file) fprintf (stderr, "[Leaving LTRANS %s]\n", file); } - -/* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */ - -static void -fork_execute (char **argv) -{ - struct pex_obj *pex; - char *new_argv[3]; - char *at_args; - FILE *args; - int status; - - args_name = make_temp_file (".args"); - at_args = concat ("@", args_name, NULL); - args = fopen (args_name, "w"); - if (args == NULL) - fatal_error ("failed to open %s", args_name); - - status = writeargv (&argv[1], args); - - if (status) - fatal_error ("could not write to temporary file %s", args_name); - - fclose (args); - - new_argv[0] = argv[0]; - new_argv[1] = at_args; - new_argv[2] = NULL; - - pex = collect_execute (new_argv); - collect_wait (new_argv[0], pex); - - maybe_unlink_file (args_name); - args_name = NULL; - free (at_args); -} - /* Template of LTRANS dumpbase suffix. */ #define DUMPBASE_SUFFIX ".ltrans18446744073709551615" @@ -869,7 +734,7 @@ cont: output_names[nr-1] = output_name; } fclose (stream); - maybe_unlink_file (ltrans_output_file); + maybe_unlink (ltrans_output_file); ltrans_output_file = NULL; if (parallel) @@ -928,7 +793,7 @@ cont: else { fork_execute (CONST_CAST (char **, new_argv)); - maybe_unlink_file (input_name); + maybe_unlink (input_name); } output_names[i] = output_name; @@ -965,10 +830,10 @@ cont: new_argv[i++] = NULL; pex = collect_execute (CONST_CAST (char **, new_argv)); collect_wait (new_argv[0], pex); - maybe_unlink_file (makefile); + maybe_unlink (makefile); makefile = NULL; for (i = 0; i < nr; ++i) - maybe_unlink_file (input_names[i]); + maybe_unlink (input_names[i]); } for (i = 0; i < nr; ++i) { |