This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[lto][patch] Split archives


With the attached patch the plugin now splits archives and writes them
to a temporary directory. The file with the resolution points to the
individual object files.

This is less efficient than adding support for archives in lto1, but easier.


2008-09-11  Rafael Avila de Espindola  <espindola@google.com>

	* lto-plugin.c: Include sys/stat.h, unistd.h anad fcntl.h
	(plugin_file_info): Remove file. Add name, fd and handle.
	(temp_obj_dir_name): New.
	(register_cleanup): New.
	(free_1): Close fd.
	(free_2): Free name.
	(all_symbols_read_handler): Update to work with new plugin_file_info.
	(cleanup_handler): New.
	(claim_file_handler): Split archives.
	(onload): Handle LDPT_REGISTER_CLEANUP_HOOK. Create temporary directory.
	* lto-symtab.c (cleanup_handler): New.
	(register_cleanup): New.
	(tv): Add LDPT_REGISTER_CLEANUP_HOOK entry.
	(main): Call cleanup_handler.

Cheers,
-- 
Rafael Avila de Espindola

Google | Gordon House | Barrow Street | Dublin 4 | Ireland
Registered in Dublin, Ireland | Registration Number: 368047
diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
index 0493b37..1db0363 100644
--- a/lto-plugin/lto-plugin.c
+++ b/lto-plugin/lto-plugin.c
@@ -33,6 +33,9 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 #include <stdio.h>
 #include <inttypes.h>
 #include <ar.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
 
 #ifdef HAVE_GELF_H
 # include <gelf.h>
@@ -62,16 +65,20 @@ struct plugin_symtab
 
 struct plugin_file_info
 {
+  char *name;
+  int fd;
+  void *handle;
   Elf *elf;
-  struct ld_plugin_input_file file;
   struct plugin_symtab symtab;
 };
 
 
+#define temp_obj_dir_name "tmp_objects"
 static ld_plugin_register_claim_file register_claim_file;
 static ld_plugin_add_symbols add_symbols;
 static ld_plugin_register_all_symbols_read register_all_symbols_read;
 static ld_plugin_get_symbols get_symbols;
+static ld_plugin_register_cleanup register_cleanup;
 
 static struct plugin_file_info *claimed_files = NULL;
 static unsigned int num_claimed_files = 0;
@@ -212,6 +219,8 @@ free_1 (void)
     {
       struct plugin_file_info *info = &claimed_files[i];
       struct plugin_symtab *symtab = &info->symtab;
+      int t = close (info->fd);
+      assert (t == 0);
       free (symtab->syms);
       symtab->syms = NULL;
       elf_end (info->elf);
@@ -230,6 +239,7 @@ free_2 (void)
       struct plugin_file_info *info = &claimed_files[i];
       struct plugin_symtab *symtab = &info->symtab;
       free (symtab->slots);
+      free (info->name);
     }
   free (claimed_files);
   claimed_files = NULL;
@@ -251,21 +261,19 @@ all_symbols_read_handler (void)
     {
       struct plugin_file_info *info = &claimed_files[i];
       struct plugin_symtab *symtab = &info->symtab;
-      struct ld_plugin_input_file *file = &info->file;
       struct ld_plugin_symbol *syms = calloc (symtab->nsyms,
 					      sizeof (struct ld_plugin_symbol));
 
       unsigned j;
       assert (syms);
-      get_symbols (file->handle, symtab->nsyms, syms);
+      get_symbols (info->handle, symtab->nsyms, syms);
 
       for (j = 0; j < info->symtab.nsyms; j++)
 	{
 	  uint32_t slot = symtab->slots[j];
 	  unsigned int resolution = syms[j].resolution;
-	  fprintf(f, "%s\n%" PRId64 " %" PRId64 " %d %s\n",
-		  file->name, (int64_t) file->offset, (int64_t) file->filesize,
-		  slot, lto_resolution_str[resolution]);
+	  fprintf(f, "%s\n%d %s\n",
+		  info->name, slot, lto_resolution_str[resolution]);
 	}
       free (syms);
     }
@@ -274,6 +282,16 @@ all_symbols_read_handler (void)
   return LDPS_OK;
 }
 
+/* Remove temporary files at the end of the link. */
+
+static enum ld_plugin_status
+cleanup_handler (void)
+{
+  int t = system ("rm -rf " temp_obj_dir_name);
+  assert (t == 0);
+  return LDPS_OK;
+}
+
 /* Callback used by gold to check if the plugin will claim FILE. Writes
    the result in CLAIMED. */
 
@@ -281,17 +299,50 @@ static enum ld_plugin_status
 claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
 {
   enum ld_plugin_status status;
-  Elf *elf = elf_begin (file->fd, ELF_C_READ, NULL);
+  Elf *elf;
   struct plugin_file_info lto_file;
   Elf_Data *symtab;
 
   if (file->offset != 0)
     {
-      elf_rand (elf, file->offset - sizeof (struct ar_hdr));
-      Elf *member = elf_begin (file->fd, ELF_C_READ, elf);
-      elf_end (elf);
-      elf = member;
+      int fd;
+      off_t size = file->filesize;
+      off_t offset;
+
+      static int objnum = 0;
+      const int name_size = 20;
+      char *objname = malloc (name_size);
+      int t = snprintf (objname, name_size, "%s/obj%d.o",
+			temp_obj_dir_name, objnum);
+      assert (t >= 0 && t < name_size);
+      objnum++;
+
+      fd = open(objname, O_RDWR | O_CREAT, 0666);
+      assert (fd > 0);
+      offset = lseek (file->fd, file->offset, SEEK_SET);
+      assert (offset == file->offset);
+      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);
+	  assert (written = r);
+	  size -= r;
+	}
+      lto_file.name = objname;
+      lto_file.fd = fd;
+      lto_file.handle = file->handle;
+    }
+  else
+    {
+      lto_file.name = strdup (file->name);
+      lto_file.fd = file->fd;
+      lto_file.handle = file->handle;
     }
+  lto_file.elf = elf_begin (lto_file.fd, ELF_C_READ, NULL);
+  elf = lto_file.elf;
 
   *claimed = 0;
 
@@ -303,8 +354,6 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed)
     return LDPS_OK;
 
   translate (symtab, &lto_file.symtab);
-  lto_file.file = *file;
-  lto_file.elf = elf;
 
   status = add_symbols (file->handle, lto_file.symtab.nsyms,
 			lto_file.symtab.syms);
@@ -327,6 +376,7 @@ onload (struct ld_plugin_tv *tv)
 {
   struct ld_plugin_tv *p;
   enum ld_plugin_status status;
+  int t;
 
   unsigned version = elf_version (EV_CURRENT);
   assert (version != EV_NONE);
@@ -348,21 +398,31 @@ onload (struct ld_plugin_tv *tv)
 	case LDPT_GET_SYMBOLS:
 	  get_symbols = p->tv_u.tv_get_symbols;
 	  break;
+	case LDPT_REGISTER_CLEANUP_HOOK:
+	  register_cleanup = p->tv_u.tv_register_cleanup;
+	  break;
 	default:
 	  break;
 	}
       p++;
     }
 
+  assert (register_cleanup);
   assert (register_claim_file);
   assert (add_symbols);
   status = register_claim_file (claim_file_handler);
   assert (status == LDPS_OK);
 
+  status = register_cleanup (cleanup_handler);
+  assert (status == LDPS_OK);
+
   if (register_all_symbols_read)
     {
       assert (get_symbols);
       status = register_all_symbols_read (all_symbols_read_handler);
       assert (status == LDPS_OK);
     }
+
+  t = mkdir (temp_obj_dir_name, 0777);
+  assert (t == 0);
 }
diff --git a/lto-plugin/lto-symtab.c b/lto-plugin/lto-symtab.c
index 0b2116d..4c3cfb1 100644
--- a/lto-plugin/lto-symtab.c
+++ b/lto-plugin/lto-symtab.c
@@ -39,6 +39,7 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 
 static ld_plugin_claim_file_handler claim_file_handler;
 static ld_plugin_all_symbols_read_handler all_symbols_read_handler;
+static ld_plugin_cleanup_handler cleanup_handler;
 static void *plugin_handle;
 
 struct file_handle {
@@ -83,6 +84,15 @@ register_claim_file(ld_plugin_claim_file_handler handler)
   return LDPS_OK;
 }
 
+/* Register HANDLER as the callback to removing temporary files. */
+
+static enum ld_plugin_status
+register_cleanup (ld_plugin_cleanup_handler handler)
+{
+  cleanup_handler = handler;
+  return LDPS_OK;
+}
+
 /* For a file identified by HANDLE, add NSYMS symbols from SYMS. */
 
 static enum ld_plugin_status
@@ -122,7 +132,9 @@ struct ld_plugin_tv tv[] = {
   {LDPT_GET_SYMBOLS,
    {.tv_get_symbols = get_symbols}
   },
-
+  {LDPT_REGISTER_CLEANUP_HOOK,
+   {.tv_register_cleanup = register_cleanup}
+  },
   {0, {0}}
 };
 
@@ -346,6 +358,8 @@ main(int argc, char *argv[])
 
   free_all ();
 
+  cleanup_handler ();
+
   unload_plugin ();
 
   return 0;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]