Hi,
On 28 Nov 09:36, Richard Biener wrote:
> On Fri, 28 Nov 2014, Ilya Verbin wrote:
> > I found a bug here, have_{lto,offload} must be set if at least one file
> > contains
> > lto/offload sections, but currently they are overwritten by the last file.
> > Fix is bootstrapped and regtested on x86_64-linux. OK for trunk?
> Ok.
Unfortunately, this fix was not general enough.
There might be cases when mixed object files get into lto-wrapper, ie some of
them contain only LTO sections, some contain only offload sections, and some
contain both. But when lto-wrapper will pass all these files to recompilation,
the compiler might crash (it depends on the order of input files), since in
read_cgraph_and_symbols it expects that *all* input files contain IR section of
given type.
This patch splits input objects from argv into lto_argv and offload_argv, so
that all files in arrays contain corresponding IR.
Similarly, in lto-plugin, it was bad idea to add objects, which contain offload
IR without LTO, to claimed_files, since this may corrupt a resolution file.
Tested on various combinations of files with/without -flto and with/without
offload, using trunk ld and gold, also tested on ld without plugin support.
Bootstrap and make check passed on x86_64-linux and i686-linux. Ok for trunk?
But I am unable to run lto-bootstrap on trunk, it says:
/x/build-x86_64-linux/./prev-gcc/gcc-ar -B/x/build-x86_64-linux/./prev-gcc/ cru
libdecnumber.a decNumber.o decContext.o decimal32.o decimal64.o decimal128.o
bid2dpd_dpd2bid.o host-ieee32.o host-ieee64.o host-ieee128.o
/usr/bin/ar terminated with signal 11 [Segmentation fault], core dumped
make[4]: *** [libdecnumber.a] Error 1
gcc/
* lto-wrapper.c (compile_offload_image): Start processing in_argv
from 0 instead of 1.
(run_gcc): Put offload objects into offload_argv, put LTO objects and
possible preceding arguments into lto_argv.
Pass offload_argv to compile_images_for_offload_targets instead of argv.
Use lto_argv for LTO recompilation instead of argv.
lto-plugin/
* lto-plugin.c (offload_files, num_offload_files): New static variables.
(free_1): Use arguments instead of global variables.
(free_2): Free offload_files.
(all_symbols_read_handler): Add names from offload_files to lto-wrapper
arguments.
(claim_file_handler): Do not add file to claimed_files if it contains
offload sections without LTO sections. Add it to offload_files instead.
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 0f69457..f75c0dc 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -669,7 +669,7 @@ compile_offload_image (const char *target, const char
*compiler_path,
obstack_ptr_grow (&argv_obstack, filename);
/* Append names of input object files. */
- for (unsigned i = 1; i < in_argc; i++)
+ for (unsigned i = 0; i < in_argc; i++)
obstack_ptr_grow (&argv_obstack, in_argv[i]);
/* Append options from offload_lto sections. */
@@ -883,6 +883,8 @@ run_gcc (unsigned argc, char *argv[])
int new_head_argc;
bool have_lto = false;
bool have_offload = false;
+ unsigned lto_argc = 0, offload_argc = 0;
+ char **lto_argv, **offload_argv;
/* Get the driver and options. */
collect_gcc = getenv ("COLLECT_GCC");
@@ -896,6 +898,11 @@ run_gcc (unsigned argc, char *argv[])
&decoded_options,
&decoded_options_count);
+ /* Allocate arrays for input object files with LTO or offload IL,
+ and for possible preceding arguments. */
+ lto_argv = XNEWVEC (char *, argc);
+ offload_argv = XNEWVEC (char *, argc);
+
/* Look at saved options in the IL files. */
for (i = 1; i < argc; ++i)
{
@@ -918,17 +925,27 @@ run_gcc (unsigned argc, char *argv[])
}
fd = open (argv[i], O_RDONLY);
if (fd == -1)
- continue;
+ {
+ lto_argv[lto_argc++] = argv[i];
+ continue;
+ }
+
+ if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
+ &fdecoded_options, &fdecoded_options_count,
+ collect_gcc))
+ {
+ have_lto = true;
+ lto_argv[lto_argc++] = argv[i];
+ }
+
+ if (find_and_merge_options (fd, file_offset, OFFLOAD_SECTION_NAME_PREFIX,
+ &offload_fdecoded_options,
+ &offload_fdecoded_options_count, collect_gcc))
+ {
+ have_offload = true;
+ offload_argv[offload_argc++] = argv[i];
+ }
- have_lto
- |= find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
- &fdecoded_options, &fdecoded_options_count,
- collect_gcc);
- have_offload
- |= find_and_merge_options (fd, file_offset, OFFLOAD_SECTION_NAME_PREFIX,
- &offload_fdecoded_options,
- &offload_fdecoded_options_count,
- collect_gcc);
close (fd);
}
@@ -1027,7 +1044,8 @@ run_gcc (unsigned argc, char *argv[])
if (have_offload)
{
- compile_images_for_offload_targets (argc, argv, offload_fdecoded_options,
+ compile_images_for_offload_targets (offload_argc, offload_argv,
+ offload_fdecoded_options,
offload_fdecoded_options_count,
decoded_options,
decoded_options_count);
@@ -1119,8 +1137,8 @@ run_gcc (unsigned argc, char *argv[])
}
/* Append the input objects and possible preceding arguments. */
- for (i = 1; i < argc; ++i)
- obstack_ptr_grow (&argv_obstack, argv[i]);
+ for (i = 0; i < lto_argc; ++i)
+ obstack_ptr_grow (&argv_obstack, lto_argv[i]);
obstack_ptr_grow (&argv_obstack, NULL);
new_argv = XOBFINISH (&argv_obstack, const char **);
@@ -1295,6 +1313,8 @@ cont:
if (offloadend)
printf ("%s\n", offloadend);
+ XDELETE (lto_argv);
+ XDELETE (offload_argv);
obstack_free (&argv_obstack, NULL);
}
diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
index fb6555d..8d957402 100644
--- a/lto-plugin/lto-plugin.c
+++ b/lto-plugin/lto-plugin.c
@@ -152,6 +152,9 @@ static ld_plugin_add_symbols add_symbols;
static struct plugin_file_info *claimed_files = NULL;
static unsigned int num_claimed_files = 0;
+static struct plugin_file_info *offload_files = NULL;
+static unsigned int num_offload_files = 0;
+
static char **output_files = NULL;
static unsigned int num_output_files = 0;
@@ -313,12 +316,12 @@ translate (char *data, char *end, struct plugin_symtab
*out)
resolution. */
static void
-free_1 (void)
+free_1 (struct plugin_file_info *files, unsigned num_files)
{
unsigned int i;
- for (i = 0; i < num_claimed_files; i++)
+ for (i = 0; i < num_files; i++)
{
- struct plugin_file_info *info = &claimed_files[i];
+ struct plugin_file_info *info = &files[i];
struct plugin_symtab *symtab = &info->symtab;
unsigned int j;
for (j = 0; j < symtab->nsyms; j++)
@@ -346,6 +349,14 @@ free_2 (void)
free (info->name);
}
+ for (i = 0; i < num_offload_files; i++)
+ {
+ struct plugin_file_info *info = &offload_files[i];
+ struct plugin_symtab *symtab = &info->symtab;
+ free (symtab->aux);
+ free (info->name);
+ }
+
for (i = 0; i < num_output_files; i++)
free (output_files[i]);
free (output_files);
@@ -354,6 +365,10 @@ free_2 (void)
claimed_files = NULL;
num_claimed_files = 0;
+ free (offload_files);
+ offload_files = NULL;
+ num_offload_files = 0;
+
free (arguments_file_name);
arguments_file_name = NULL;
}
@@ -608,10 +623,11 @@ static enum ld_plugin_status
all_symbols_read_handler (void)
{
unsigned i;
- unsigned num_lto_args = num_claimed_files + lto_wrapper_num_args + 1;
+ unsigned num_lto_args
+ = num_claimed_files + num_offload_files + lto_wrapper_num_args + 1;
char **lto_argv;
const char **lto_arg_ptr;
- if (num_claimed_files == 0)
+ if (num_claimed_files + num_offload_files == 0)
return LDPS_OK;
if (nop)
@@ -626,7 +642,8 @@ all_symbols_read_handler (void)
write_resolution ();
- free_1 ();
+ free_1 (claimed_files, num_claimed_files);
+ free_1 (offload_files, num_offload_files);
for (i = 0; i < lto_wrapper_num_args; i++)
*lto_arg_ptr++ = lto_wrapper_argv[i];
@@ -638,6 +655,13 @@ all_symbols_read_handler (void)
*lto_arg_ptr++ = info->name;
}
+ for (i = 0; i < num_offload_files; i++)
+ {
+ struct plugin_file_info *info = &offload_files[i];
+
+ *lto_arg_ptr++ = info->name;
+ }
+
*lto_arg_ptr++ = NULL;
exec_lto_wrapper (lto_argv);
@@ -949,16 +973,29 @@ claim_file_handler (const struct ld_plugin_input_file
*file, int *claimed)
if (obj.found > 1)
resolve_conflicts (<o_file.symtab, <o_file.conflicts);
- status = add_symbols (file->handle, lto_file.symtab.nsyms,
- lto_file.symtab.syms);
- check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
+ if (obj.found > 0)
+ {
+ status = add_symbols (file->handle, lto_file.symtab.nsyms,
+ lto_file.symtab.syms);
+ check (status == LDPS_OK, LDPL_FATAL, "could not add symbols");
+
+ num_claimed_files++;
+ claimed_files =
+ xrealloc (claimed_files,
+ num_claimed_files * sizeof (struct plugin_file_info));
+ claimed_files[num_claimed_files - 1] = lto_file;
+ }
+
+ if (obj.found == 0 && obj.offload == 1)
+ {
+ num_offload_files++;
+ offload_files =
+ xrealloc (offload_files,
+ num_offload_files * sizeof (struct plugin_file_info));
+ offload_files[num_offload_files - 1] = lto_file;
+ }
*claimed = 1;
- num_claimed_files++;
- claimed_files =
- xrealloc (claimed_files,
- num_claimed_files * sizeof (struct plugin_file_info));
- claimed_files[num_claimed_files - 1] = lto_file;
goto cleanup;
-- Ilya