@@ -49,6 +49,8 @@ along with GCC; see the file COPYING3. If not see
#include "lto-section-names.h"
#include "collect-utils.h"
+#define STATIC_LEN(x) (sizeof (x) / sizeof (*x))
+
/* Environment variable, used for passing the names of offload targets from GCC
driver to lto-wrapper. */
#define OFFLOAD_TARGET_NAMES_ENV "OFFLOAD_TARGET_NAMES"
@@ -74,6 +76,8 @@ static char *makefile;
static unsigned int num_deb_objs;
static const char **early_debug_object_names;
+static FILE *to_ld;
+
const char tool_name[] = "lto-wrapper";
/* Delete tempfiles. Called from utils_cleanup. */
@@ -955,7 +959,7 @@ find_crtoffloadtable (void)
/* The linker will delete the filename we give it, so make a copy. */
char *crtoffloadtable = make_temp_file (".crtoffloadtable.o");
copy_file (crtoffloadtable, paths[i]);
- printf ("%s\n", crtoffloadtable);
+ fprintf (to_ld, "%s\n", crtoffloadtable);
XDELETEVEC (crtoffloadtable);
break;
}
@@ -1556,7 +1560,7 @@ cont1:
{
find_crtoffloadtable ();
for (i = 0; offload_names[i]; i++)
- printf ("%s\n", offload_names[i]);
+ fprintf (to_ld, "%s\n", offload_names[i]);
free_array_of_ptrs ((void **) offload_names, i);
}
}
@@ -1686,12 +1690,12 @@ cont1:
if (lto_mode == LTO_MODE_LTO)
{
- printf ("%s\n", flto_out);
+ fprintf (to_ld, "%s\n", flto_out);
if (!skip_debug)
{
for (i = 0; i < ltoobj_argc; ++i)
if (early_debug_object_names[i] != NULL)
- printf ("%s\n", early_debug_object_names[i]);
+ fprintf (to_ld, "%s\n", early_debug_object_names[i]);
}
/* These now belong to collect2. */
free (flto_out);
@@ -1866,15 +1870,15 @@ cont:
}
for (i = 0; i < nr; ++i)
{
- fputs (output_names[i], stdout);
- putc ('\n', stdout);
+ fputs (output_names[i], to_ld);
+ putc ('\n', to_ld);
free (input_names[i]);
}
if (!skip_debug)
{
for (i = 0; i < ltoobj_argc; ++i)
if (early_debug_object_names[i] != NULL)
- printf ("%s\n", early_debug_object_names[i]);
+ fprintf (to_ld, "%s\n", early_debug_object_names[i]);
}
nr = 0;
free (ltrans_priorities);
@@ -1892,13 +1896,43 @@ cont:
obstack_free (&argv_obstack, NULL);
}
+/* Find out if lto-wrapper was called and output to lto-plugin will be in a file
+ instead of stdout. */
+
+static const char *find_ld_list_file (int* argc, char *argv[])
+{
+ int i;
+ static const char param[] = "--to_ld_list=";
+
+ for (i = 1; i < *argc; i++)
+ {
+ if (argv[i] != NULL && !strncmp (argv[i], param, STATIC_LEN (param) - 1))
+ {
+ /* Found. Retrieve the path to the file. */
+
+ /* This simple 'automata' just finds the first ':' of the string,
+ and then return a pointer from now foward. */
+ const char *path = argv[i];
+ argv[i] = NULL;
+ (*argc)--;
+ while (*path != '\0')
+ if (*path++ == '=')
+ return path;
+ }
+ }
+
+
+ /* Not found. */
+ return NULL;
+}
+
/* Entry point. */
int
main (int argc, char *argv[])
{
- const char *p;
+ const char *p, *files_list;
init_opts_obstack ();
@@ -1934,11 +1968,22 @@ main (int argc, char *argv[])
signal (SIGCHLD, SIG_DFL);
#endif
+ files_list = find_ld_list_file (&argc, argv);
+ to_ld = files_list ? fopen (files_list, "a") : stdout;
+
+ if (!to_ld)
+ {
+ fprintf (stderr, "%s: failed to open parameter file.\n", argv[0]);
+ abort ();
+ }
+
/* We may be called with all the arguments stored in some file and
passed with @file. Expand them into argv before processing. */
expandargv (&argc, &argv);
run_gcc (argc, argv);
+ fclose (to_ld);
+
return 0;
}
@@ -406,6 +406,9 @@ extern void hex_init (void);
/* Save files used for communication between processes. */
#define PEX_SAVE_TEMPS 0x4
+/* Don't close the standard I/O streams (stdout & stderr). */
+#define PEX_KEEP_STD_IO 0x8
+
/* Max number of alloca bytes per call before we must switch to malloc.
?? Swiped from gnulib's regex_internal.h header. Is this actually
@@ -651,14 +651,14 @@ pex_unix_exec_child (struct pex_obj *obj, int flags, const char *executable,
else if (close (in) < 0)
failed.fn = "close", failed.err = errno;
}
- if (!failed.fn && out != STDOUT_FILE_NO)
+ if (!failed.fn && out != STDOUT_FILE_NO && !(flags & PEX_KEEP_STD_IO))
{
if (dup2 (out, STDOUT_FILE_NO) < 0)
failed.fn = "dup2", failed.err = errno;
else if (close (out) < 0)
failed.fn = "close", failed.err = errno;
}
- if (!failed.fn && errdes != STDERR_FILE_NO)
+ if (!failed.fn && errdes != STDERR_FILE_NO && !(flags & PEX_KEEP_STD_IO))
{
if (dup2 (errdes, STDERR_FILE_NO) < 0)
failed.fn = "dup2", failed.err = errno;
@@ -560,9 +560,10 @@ exec_lto_wrapper (char *argv[])
char *at_args;
FILE *args;
FILE *wrapper_output;
- char *new_argv[3];
+ char *new_argv[4];
struct pex_obj *pex;
const char *errmsg;
+ char *temp_filename;
/* Write argv to a file to avoid a command line that is too long
Save the file locally on save-temps. */
@@ -607,10 +608,6 @@ exec_lto_wrapper (char *argv[])
fprintf (stderr, "\n");
}
- new_argv[0] = argv[0];
- new_argv[1] = at_args;
- new_argv[2] = NULL;
-
if (debug)
{
for (i = 0; new_argv[i]; i++)
@@ -618,26 +615,36 @@ exec_lto_wrapper (char *argv[])
fprintf (stderr, "\n");
}
- pex = pex_init (PEX_USE_PIPES, "lto-wrapper", NULL);
+ pex = pex_init (0, "lto-wrapper", NULL);
check (pex != NULL, LDPL_FATAL, "could not pex_init lto-wrapper");
- errmsg = pex_run (pex, 0, new_argv[0], new_argv, NULL, NULL, &t);
- check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
- check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
+ temp_filename = make_temp_file ("-ld-files.lto");
- wrapper_output = pex_read_output (pex, 0);
- check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
+ new_argv[0] = argv[0];
+ new_argv[1] = at_args;
+ new_argv[2] = concat ("--to_ld_list=", temp_filename, NULL);
+ new_argv[3] = NULL;
- add_output_files (wrapper_output);
+ errmsg = pex_run (pex, PEX_KEEP_STD_IO, new_argv[0], new_argv,
+ temp_filename, NULL, &t);
+ check (errmsg == NULL, LDPL_FATAL, "could not run lto-wrapper");
+ check (t == 0, LDPL_FATAL, "could not run lto-wrapper");
t = pex_get_status (pex, 1, &status);
check (t == 1, LDPL_FATAL, "could not get lto-wrapper exit status");
check (WIFEXITED (status) && WEXITSTATUS (status) == 0, LDPL_FATAL,
"lto-wrapper failed");
- pex_free (pex);
+ wrapper_output = fopen (temp_filename, "r");
+ check (wrapper_output, LDPL_FATAL, "could not read lto-wrapper output");
+
+ add_output_files (wrapper_output);
+ pex_free (pex);
+ free (temp_filename);
free (at_args);
+ free (argv[2]);
+ fclose (wrapper_output);
}
/* Pass the original files back to the linker. */