/* Top-level LTO routines.
- Copyright 2009 Free Software Foundation, Inc.
+ Copyright 2009, 2010 Free Software Foundation, Inc.
Contributed by CodeSourcery, Inc.
This file is part of GCC.
#include <sys/mman.h>
#endif
+/* Handle opening elf files on hosts, such as Windows, that may use
+ text file handling that will break binary access. */
+
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
+
+
DEF_VEC_P(bitmap);
DEF_VEC_ALLOC_P(bitmap,heap);
lto_data_in_delete (data_in);
}
+/* strtoll is not portable. */
+int64_t
+lto_parse_hex (const char *p) {
+ uint64_t ret = 0;
+ for (; *p != '\0'; ++p)
+ {
+ char c = *p;
+ unsigned char part;
+ ret <<= 4;
+ if (c >= '0' && c <= '9')
+ part = c - '0';
+ else if (c >= 'a' && c <= 'f')
+ part = c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ part = c - 'A' + 10;
+ else
+ internal_error ("could not parse hex number");
+ ret |= part;
+ }
+ return ret;
+}
+
/* Read resolution for file named FILE_NAME. The resolution is read from
RESOLUTION. An array with the symbol resolution is returned. The array
size is written to SIZE. */
if (file->offset != 0)
{
int t;
- char offset_p[21];
- long long offset;
- t = fscanf (resolution, "@%20s", offset_p);
+ char offset_p[17];
+ int64_t offset;
+ t = fscanf (resolution, "@0x%16s", offset_p);
if (t != 1)
internal_error ("could not parse file offset");
- errno = 0;
- offset = strtoll(offset_p, NULL, 10);
- if (errno != 0)
- internal_error ("could not parse file offset");
+ offset = lto_parse_hex (offset_p);
if (offset != file->offset)
internal_error ("unexpected offset");
}
internal_error ("Invalid resolution in the resolution file.");
VEC_safe_grow_cleared (ld_plugin_symbol_resolution_t, heap, ret,
- index + 1);
+ max_index + 1);
VEC_replace (ld_plugin_symbol_resolution_t, ret, index, r);
}
if (fd == -1)
{
fd_name = xstrdup (file_data->file_name);
- fd = open (file_data->file_name, O_RDONLY);
+ fd = open (file_data->file_name, O_RDONLY|O_BINARY);
if (fd == -1)
return NULL;
}
return output_files;
}
+/* Template of LTRANS dumpbase suffix. */
+#define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
/* Perform local transformations (LTRANS) on the files in the NULL-terminated
FILES array. These should have been written previously by
int err;
int status;
FILE *ltrans_output_list_stream = NULL;
+ bool seen_dumpbase = false;
+ char *dumpbase_suffix = NULL;
timevar_push (TV_WHOPR_WPA_LTRANS_EXEC);
++j;
obstack_init (&env_obstack);
obstack_grow (&env_obstack, &collect_gcc_options[i], j - i);
- obstack_1grow (&env_obstack, 0);
+ if (seen_dumpbase)
+ obstack_grow (&env_obstack, DUMPBASE_SUFFIX,
+ sizeof (DUMPBASE_SUFFIX));
+ else
+ obstack_1grow (&env_obstack, 0);
option = XOBFINISH (&env_obstack, char *);
+ if (seen_dumpbase)
+ {
+ dumpbase_suffix = option + 7 + j - i;
+ seen_dumpbase = false;
+ }
/* LTRANS does not need -fwpa nor -fltrans-*. */
if (strncmp (option, "-fwpa", 5) != 0
&& strncmp (option, "-fltrans-", 9) != 0)
- *argv_ptr++ = option;
+ {
+ if (strncmp (option, "-dumpbase", 9) == 0)
+ seen_dumpbase = true;
+ *argv_ptr++ = option;
+ }
}
*argv_ptr++ = "-fltrans";
argv_ptr[2] = files[i];
argv_ptr[3] = NULL;
+ /* Append a sequence number to -dumpbase for LTRANS. */
+ if (dumpbase_suffix)
+ snprintf (dumpbase_suffix, sizeof (DUMPBASE_SUFFIX) - 7,
+ "%lu", (unsigned long) i);
+
/* Execute the driver. */
pex = pex_init (0, "lto1", NULL);
if (pex == NULL)
lto_fixup_field_decl (tree t, void *data)
{
lto_fixup_decl_common (t, data);
- gcc_assert (no_fixup_p (DECL_FIELD_OFFSET (t)));
+ LTO_FIXUP_SUBTREE (DECL_FIELD_OFFSET (t));
LTO_FIXUP_SUBTREE (DECL_BIT_FIELD_TYPE (t));
LTO_FIXUP_SUBTREE (DECL_QUALIFIER (t));
gcc_assert (no_fixup_p (DECL_FIELD_BIT_OFFSET (t)));