X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Flto%2Flto.c;h=de53a09f87dac70b2a9b2090afea2db09f76783a;hb=22c1d3019e6a942f8f11eb6cb3ec036343e8b6e3;hp=9cb7d65a60bc8eccb8ab3d392a10c8ebd5eee114;hpb=b7fedf62194c73508da653990c3d0a792a814271;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 9cb7d65a60b..de53a09f87d 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -1,5 +1,5 @@ /* 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. @@ -50,6 +50,14 @@ along with GCC; see the file COPYING3. If not see #include #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); @@ -249,6 +257,28 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data, 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. */ @@ -280,15 +310,12 @@ lto_resolution_read (FILE *resolution, lto_file *file) 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"); } @@ -325,7 +352,7 @@ lto_resolution_read (FILE *resolution, lto_file *file) 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); } @@ -402,7 +429,7 @@ lto_read_section_data (struct lto_file_decl_data *file_data, 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; } @@ -1050,6 +1077,8 @@ lto_wpa_write_files (void) 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 @@ -1069,6 +1098,8 @@ lto_execute_ltrans (char *const *files) 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); @@ -1107,13 +1138,26 @@ lto_execute_ltrans (char *const *files) ++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"; @@ -1171,6 +1215,11 @@ lto_execute_ltrans (char *const *files) 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) @@ -1357,7 +1406,7 @@ static void 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)));