summaryrefslogtreecommitdiff
path: root/lto-plugin/lto-plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'lto-plugin/lto-plugin.c')
-rw-r--r--lto-plugin/lto-plugin.c97
1 files changed, 76 insertions, 21 deletions
diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
index 3788fdbb64c..92bca50b094 100644
--- a/lto-plugin/lto-plugin.c
+++ b/lto-plugin/lto-plugin.c
@@ -41,6 +41,7 @@ along with this program; see the file COPYING3. If not see
#if HAVE_STDINT_H
#include <stdint.h>
#endif
+#include <stdbool.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
@@ -184,12 +185,15 @@ static int lto_wrapper_num_args;
static char **pass_through_items = NULL;
static unsigned int num_pass_through_items;
-static char debug;
+static bool debug;
+static bool save_temps;
+static bool verbose;
static char nop;
static char *resolution_file = NULL;
static enum ld_plugin_output_file_type linker_output;
static int linker_output_set;
static int linker_output_known;
+static const char *link_output_name = NULL;
/* The version of gold being used, or -1 if not gold. The number is
MAJOR * 100 + MINOR. */
@@ -560,8 +564,17 @@ exec_lto_wrapper (char *argv[])
struct pex_obj *pex;
const char *errmsg;
- /* Write argv to a file to avoid a command line that is too long. */
- arguments_file_name = make_temp_file ("");
+ /* Write argv to a file to avoid a command line that is too long
+ Save the file locally on save-temps. */
+ if (save_temps && link_output_name)
+ {
+ arguments_file_name = (char *) xmalloc (strlen (link_output_name)
+ + sizeof (".lto_wrapper_args") + 1);
+ strcpy (arguments_file_name, link_output_name);
+ strcat (arguments_file_name, ".lto_wrapper_args");
+ }
+ else
+ arguments_file_name = make_temp_file (".lto_wrapper_args");
check (arguments_file_name, LDPL_FATAL,
"Failed to generate a temorary file name");
@@ -579,15 +592,21 @@ exec_lto_wrapper (char *argv[])
for (i = 1; argv[i]; i++)
{
char *a = argv[i];
+ /* Check the input argument list for a verbose marker too. */
if (a[0] == '-' && a[1] == 'v' && a[2] == '\0')
{
- for (i = 0; argv[i]; i++)
- fprintf (stderr, "%s ", argv[i]);
- fprintf (stderr, "\n");
+ verbose = true;
break;
}
}
+ if (verbose)
+ {
+ for (i = 0; argv[i]; i++)
+ fprintf (stderr, "%s ", argv[i]);
+ fprintf (stderr, "\n");
+ }
+
new_argv[0] = argv[0];
new_argv[1] = at_args;
new_argv[2] = NULL;
@@ -599,7 +618,6 @@ exec_lto_wrapper (char *argv[])
fprintf (stderr, "\n");
}
-
pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
@@ -759,6 +777,29 @@ all_symbols_read_handler (void)
return LDPS_OK;
}
+/* Helper, as used in collect2. */
+static int
+file_exists (const char *name)
+{
+ return access (name, R_OK) == 0;
+}
+
+/* Unlink FILE unless we have save-temps set.
+ Note that we're saving files if verbose output is set. */
+
+static void
+maybe_unlink (const char *file)
+{
+ if (save_temps && file_exists (file))
+ {
+ if (verbose)
+ fprintf (stderr, "[Leaving %s]\n", file);
+ return;
+ }
+
+ unlink_if_ordinary (file);
+}
+
/* Remove temporary files at the end of the link. */
static enum ld_plugin_status
@@ -771,16 +812,10 @@ cleanup_handler (void)
return LDPS_OK;
if (arguments_file_name)
- {
- t = unlink (arguments_file_name);
- check (t == 0, LDPL_FATAL, "could not unlink arguments file");
- }
+ maybe_unlink (arguments_file_name);
for (i = 0; i < num_output_files; i++)
- {
- t = unlink (output_files[i]);
- check (t == 0, LDPL_FATAL, "could not unlink output file");
- }
+ maybe_unlink (output_files[i]);
free_2 ();
return LDPS_OK;
@@ -1143,7 +1178,12 @@ process_option (const char *option)
if (strcmp (option, "-linker-output-known") == 0)
linker_output_known = 1;
if (strcmp (option, "-debug") == 0)
- debug = 1;
+ debug = true;
+ else if ((strcmp (option, "-v") == 0)
+ || (strcmp (option, "--verbose") == 0))
+ verbose = true;
+ else if (strcmp (option, "-save-temps") == 0)
+ save_temps = true;
else if (strcmp (option, "-nop") == 0)
nop = 1;
else if (!strncmp (option, "-pass-through=", strlen("-pass-through=")))
@@ -1180,6 +1220,8 @@ process_option (const char *option)
if (strncmp (option, "-fresolution=", sizeof ("-fresolution=") - 1) == 0)
resolution_file = opt + sizeof ("-fresolution=") - 1;
}
+ save_temps = save_temps || debug;
+ verbose = verbose || debug;
}
/* Called by gold after loading the plugin. TV is the transfer vector. */
@@ -1232,6 +1274,10 @@ onload (struct ld_plugin_tv *tv)
linker_output = (enum ld_plugin_output_file_type) p->tv_u.tv_val;
linker_output_set = 1;
break;
+ case LDPT_OUTPUT_NAME:
+ /* We only use this to make user-friendly temp file names. */
+ link_output_name = p->tv_u.tv_string;
+ break;
default:
break;
}
@@ -1259,12 +1305,21 @@ onload (struct ld_plugin_tv *tv)
"could not register the all_symbols_read callback");
}
- /* Support -fno-use-linker-plugin by failing to load the plugin
- for the case where it is auto-loaded by BFD. */
char *collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
- if (collect_gcc_options
- && strstr (collect_gcc_options, "'-fno-use-linker-plugin'"))
- return LDPS_ERR;
+ if (collect_gcc_options)
+ {
+ /* Support -fno-use-linker-plugin by failing to load the plugin
+ for the case where it is auto-loaded by BFD. */
+ if (strstr (collect_gcc_options, "'-fno-use-linker-plugin'"))
+ return LDPS_ERR;
+
+ if ( strstr (collect_gcc_options, "'-save-temps'"))
+ save_temps = true;
+
+ if (strstr (collect_gcc_options, "'-v'")
+ || strstr (collect_gcc_options, "'--verbose'"))
+ verbose = true;
+ }
return LDPS_OK;
}