diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 77b133784a0..1952f78c3b9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2010-02-11 Richard Guenther + + PR driver/43021 + * gcc.c (process_command): Handle LTO file@offset case more + appropriately. + 2010-02-11 Jakub Jelinek * reload1.c (eliminate_regs_1): If insn is DEBUG_INSN, avoid any diff --git a/gcc/gcc.c b/gcc/gcc.c index 2e219d614e9..31e4ab37513 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -4575,20 +4575,35 @@ process_command (int argc, const char **argv) } else { - const char *p = strchr (argv[i], '@'); + const char *p = strrchr (argv[i], '@'); char *fname; + long offset; + int consumed; #ifdef HAVE_TARGET_OBJECT_SUFFIX argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK)); #endif - if (!p) - fname = xstrdup (argv[i]); - else - { + /* For LTO static archive support we handle input file + specifications that are composed of a filename and + an offset like FNAME@OFFSET. */ + if (p + && p != argv[i] + && sscanf (p, "@%li%n", &offset, &consumed) >= 1 + && strlen (p) == (unsigned int)consumed) + { fname = (char *)xmalloc (p - argv[i] + 1); memcpy (fname, argv[i], p - argv[i]); fname[p - argv[i]] = '\0'; - } - + /* Only accept non-stdin and existing FNAME parts, otherwise + try with the full name. */ + if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0) + { + free (fname); + fname = xstrdup (argv[i]); + } + } + else + fname = xstrdup (argv[i]); + if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0) { perror_with_name (fname); diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index a726d32f5bb..58e51231bf1 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,9 @@ +2010-02-11 Richard Guenther + + PR driver/43021 + * lto-elf.c (lto_elf_file_open): Handle file@offset case more + appropriately. + 2010-01-11 Andy Hutchinson * lto.c (O_BINARY): Define. diff --git a/gcc/lto/lto-elf.c b/gcc/lto/lto-elf.c index b70648d4680..356e5139536 100644 --- a/gcc/lto/lto-elf.c +++ b/gcc/lto/lto-elf.c @@ -550,35 +550,33 @@ lto_elf_file_open (const char *filename, bool writable) lto_elf_file *elf_file; lto_file *result = NULL; off_t offset; + long loffset; off_t header_offset; const char *offset_p; char *fname; + int consumed; - offset_p = strchr (filename, '@'); - if (!offset_p) + offset_p = strrchr (filename, '@'); + if (offset_p + && offset_p != filename + && sscanf (offset_p, "@%li%n", &loffset, &consumed) >= 1 + && strlen (offset_p) == (unsigned int)consumed) { - fname = xstrdup (filename); - offset = 0; - header_offset = 0; - } - else - { - /* The file started with '@' is a file containing command line - options. Stop if it doesn't exist. */ - if (offset_p == filename) - fatal_error ("command line option file '%s' does not exist", - filename); - fname = (char *) xmalloc (offset_p - filename + 1); memcpy (fname, filename, offset_p - filename); fname[offset_p - filename] = '\0'; - offset_p += 3; /* skip the @0x */ - offset = lto_parse_hex (offset_p); + offset = (off_t)loffset; /* elf_rand expects the offset to point to the ar header, not the object itself. Subtract the size of the ar header (60 bytes). We don't uses sizeof (struct ar_hd) to avoid including ar.h */ header_offset = offset - 60; } + else + { + fname = xstrdup (filename); + offset = 0; + header_offset = 0; + } /* Set up. */ elf_file = XCNEW (lto_elf_file);