OSDN Git Service

2009-11-04 Richard Guenther <rguenther@suse.de>
authorespindola <espindola@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 4 Nov 2009 17:24:37 +0000 (17:24 +0000)
committerespindola <espindola@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 4 Nov 2009 17:24:37 +0000 (17:24 +0000)
            Rafael Avila de Espindola  <espindola@google.com>

* gcc.c (process_command): Handle arguments name@offset.

2009-11-04  Richard Guenther  <rguenther@suse.de>
            Rafael Avila de Espindola  <espindola@google.com>

* lto-elf.c (lto_elf_build_section_table): Add the base offset.
(lto_elf_file_open): Handle offsets in arguments name@offest.

2009-11-04  Richard Guenther  <rguenther@suse.de>
            Rafael Avila de Espindola  <espindola@google.com>

* lto-plugin.c (plugin_file_info): Remove temp field.
(cleanup_handler): Don't delete temporary objects.
(claim_file_handler): Don't create temporary objects.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@153903 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gcc.c
gcc/lto/ChangeLog
gcc/lto/lto-elf.c
lto-plugin/ChangeLog
lto-plugin/lto-plugin.c

index c3b8d86..619e450 100644 (file)
@@ -1,3 +1,8 @@
+2009-11-04  Richard Guenther  <rguenther@suse.de>
+            Rafael Avila de Espindola  <espindola@google.com>
+       * gcc.c (process_command): Handle arguments name@offset.
 2009-11-04  Harsha Jagasia  <harsha.jagasia@amd.com>
            Dwarakanath Rajagopal  <dwarak.rajagopal@amd.com>
        
index 0f74dd0..6bc8e15 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -4568,20 +4568,32 @@ process_command (int argc, const char **argv)
        }
       else
        {
+          const char *p = strchr (argv[i], '@');
+          char *fname;
 #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
+            {
+              fname = (char *)xmalloc (p - argv[i] + 1);
+              memcpy (fname, argv[i], p - argv[i]);
+              fname[p - argv[i]] = '\0';
+            }
+
+          if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
+            {
+              perror_with_name (fname);
+              error_count++;
+            }
+          else
+            {
+              infiles[n_infiles].language = spec_lang;
+              infiles[n_infiles++].name = argv[i];
+            }
 
-         if (strcmp (argv[i], "-") != 0 && access (argv[i], F_OK) < 0)
-           {
-             perror_with_name (argv[i]);
-             error_count++;
-           }
-         else
-           {
-             infiles[n_infiles].language = spec_lang;
-             infiles[n_infiles++].name = argv[i];
-           }
+          free (fname);
        }
     }
 
index 0d464ec..3334de7 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-04  Richard Guenther  <rguenther@suse.de>
+            Rafael Avila de Espindola  <espindola@google.com>
+
+       * lto-elf.c (lto_elf_build_section_table): Add the base offset.
+       (lto_elf_file_open): Handle offsets in arguments name@offest.
+
 2009-10-30  Richard Guenther  <rguenther@suse.de>
 
        PR lto/41858
index 190430b..ee587f7 100644 (file)
@@ -167,9 +167,11 @@ lto_elf_build_section_table (lto_file *lto_file)
   lto_elf_file *elf_file = (lto_elf_file *)lto_file;
   htab_t section_hash_table;
   Elf_Scn *section;
+  size_t base_offset;
 
   section_hash_table = htab_create (37, hash_name, eq_name, free);
 
+  base_offset = elf_getbase (elf_file->elf);
   for (section = elf_getscn (elf_file->elf, 0);
        section;
        section = elf_nextscn (elf_file->elf, section)) 
@@ -206,7 +208,7 @@ lto_elf_build_section_table (lto_file *lto_file)
 
          new_slot->name = new_name;
          /* The offset into the file for this section.  */
-         new_slot->start = shdr->sh_offset;
+         new_slot->start = base_offset + shdr->sh_offset;
          new_slot->len = shdr->sh_size;
          *slot = new_slot;
        }
@@ -530,7 +532,6 @@ init_ehdr (lto_elf_file *elf_file)
     }
 }
 
-
 /* Open ELF file FILENAME.  If WRITABLE is true, the file is opened for write
    and, if necessary, created.  Otherwise, the file is opened for reading.
    Returns the opened file.  */
@@ -540,18 +541,42 @@ lto_elf_file_open (const char *filename, bool writable)
 {
   lto_elf_file *elf_file;
   lto_file *result;
+  off_t offset;
+  const char *offset_p;
+  char *fname;
+
+  offset_p = strchr (filename, '@');
+  if (!offset_p)
+    {
+      fname = xstrdup (filename);
+      offset = 0;
+    }
+  else
+    {
+      int64_t t;
+      fname = (char *) xmalloc (offset_p - filename + 1);
+      memcpy (fname, filename, offset_p - filename);
+      fname[offset_p - filename] = '\0';
+      offset_p++;
+      sscanf(offset_p, "%" PRId64 , &t);
+      offset = t;
+      /* 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 */
+      offset -= 60;
+    }
 
   /* Set up.  */
   elf_file = XCNEW (lto_elf_file);
   result = (lto_file *) elf_file;
-  lto_file_init (result, filename);
+  lto_file_init (result, fname);
   elf_file->fd = -1;
 
   /* Open the file.  */
-  elf_file->fd = open (filename, writable ? O_WRONLY|O_CREAT : O_RDONLY, 0666);
+  elf_file->fd = open (fname, writable ? O_WRONLY|O_CREAT : O_RDONLY, 0666);
   if (elf_file->fd == -1)
     {
-      error ("could not open file %s", filename);
+      error ("could not open file %s", fname);
       goto fail;
     }
 
@@ -571,6 +596,26 @@ lto_elf_file_open (const char *filename, bool writable)
       goto fail;
     }
 
+  if (offset != 0)
+    {
+      Elf *e;
+      off_t t = elf_rand (elf_file->elf, offset);
+      if (t != offset)
+        {
+          error ("could not seek in archive");
+          goto fail;
+        }
+
+      e = elf_begin (elf_file->fd, ELF_C_READ, elf_file->elf);
+      if (e == NULL)
+        {
+          error("could not find archive member");
+          goto fail;
+        }
+      elf_end (elf_file->elf);
+      elf_file->elf = e;
+    }
+
   if (writable)
     {
       init_ehdr (elf_file);
index 3667979..f241a66 100644 (file)
@@ -1,3 +1,10 @@
+2009-11-04  Richard Guenther  <rguenther@suse.de>
+            Rafael Avila de Espindola  <espindola@google.com>
+
+       * lto-plugin.c (plugin_file_info): Remove temp field.
+       (cleanup_handler): Don't delete temporary objects.
+       (claim_file_handler): Don't create temporary objects.
+
 2009-11-04  Rafael Avila de Espindola  <espindola@google.com>
 
        * lto-plugin.c (cleanup_handler): Don't cleanup if debugging.
index 0be0b90..3cf4e7c 100644 (file)
@@ -37,7 +37,6 @@ along with this program; see the file COPYING3.  If not see
 #include <stdlib.h>
 #include <stdio.h>
 #include <inttypes.h>
-#include <ar.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <fcntl.h>
@@ -70,7 +69,6 @@ struct plugin_file_info
   char *name;
   void *handle;
   struct plugin_symtab symtab;
-  unsigned char temp;
 };
 
 
@@ -513,20 +511,9 @@ static enum ld_plugin_status
 cleanup_handler (void)
 {
   int t;
-  unsigned i;
   char *arguments;
   struct stat buf;
 
-  for (i = 0; i < num_claimed_files; i++)
-    {
-      struct plugin_file_info *info = &claimed_files[i];
-      if (info->temp)
-       {
-         t = unlink (info->name);
-         check (t == 0, LDPL_FATAL, "could not unlink temporary file");
-       }
-    }
-
   if (debug)
     return LDPS_OK;
 
@@ -558,49 +545,39 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
   Elf *elf;
   struct plugin_file_info lto_file;
   Elf_Data *symtab;
-  int lto_file_fd;
 
   if (file->offset != 0)
     {
-      /* FIXME lto: lto1 should know how to handle archives. */
-      int fd;
-      off_t size = file->filesize;
-      off_t offset;
-
-      static int objnum = 0;
       char *objname;
-      int t = asprintf (&objname, "%s/obj%d.o",
-                       temp_obj_dir_name, objnum);
+      Elf *archive;
+      off_t offset;
+      /* We pass the offset of the actual file, not the archive header. */
+      int t = asprintf (&objname, "%s@%" PRId64, file->name,
+                        (int64_t) file->offset);
       check (t >= 0, LDPL_FATAL, "asprintf failed");
-      objnum++;
-
-      fd = open (objname, O_RDWR | O_CREAT, 0666);
-      check (fd > 0, LDPL_FATAL, "could not open/create temporary file");
-      offset = lseek (file->fd, file->offset, SEEK_SET);
-      check (offset == file->offset, LDPL_FATAL, "could not seek");
-      while (size > 0)
-       {
-         ssize_t r, written;
-         char buf[1000];
-         off_t s = sizeof (buf) < size ? sizeof (buf) : size;
-         r = read (file->fd, buf, s);
-         written = write (fd, buf, r);
-         check (written == r, LDPL_FATAL, "could not write to temporary file");
-         size -= r;
-       }
       lto_file.name = objname;
-      lto_file_fd = fd;
-      lto_file.handle = file->handle;
-      lto_file.temp = 1;
+
+      archive = elf_begin (file->fd, ELF_C_READ, NULL);
+      check (elf_kind (archive) == ELF_K_AR, LDPL_FATAL,
+             "Not an archive and offset not 0");
+
+      /* 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 */
+
+      offset = file->offset - 60;
+      check (offset == elf_rand (archive, offset), LDPL_FATAL,
+             "could not seek in archive");
+      elf = elf_begin (file->fd, ELF_C_READ, archive);
+      check (elf != NULL, LDPL_FATAL, "could not find archive member");
+      elf_end (archive);
     }
   else
     {
       lto_file.name = strdup (file->name);
-      lto_file_fd = file->fd;
-      lto_file.handle = file->handle;
-      lto_file.temp = 0;
+      elf = elf_begin (file->fd, ELF_C_READ, NULL);
     }
-  elf = elf_begin (lto_file_fd, ELF_C_READ, NULL);
+  lto_file.handle = file->handle;
 
   *claimed = 0;
 
@@ -627,20 +604,12 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
   goto cleanup;
 
  err:
-  if (file->offset != 0)
-    {
-      int t = unlink (lto_file.name);
-      check (t == 0, LDPL_FATAL, "could not unlink file");
-    }
   free (lto_file.name);
 
  cleanup:
   if (elf)
     elf_end (elf);
 
-  if (file->offset != 0)
-    close (lto_file_fd);
-
   return LDPS_OK;
 }