This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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]

[rfa] Add bfd-in-memory io vector


Hello,

This adds a bfd-in-memory IO vector to BFD. Note that it doesn't completly consolidate code using "struct bfd_in_memory" as some of it is pretty evil (grep for remaining references to BFD_IN_MEMORY). I'll do another pass at eliminating more of the BFD_IN_MEMORY references in a follow-up patch.

I've tested this on i386 GNU/Linux with no regressions. However, given my experience with the previous IOVEC change, I'm not sure how significant that result is :-/

Anyway, Ok?
Andrew
2004-04-30  Andrew Cagney  <cagney@redhat.com>

	* libbfd-in.h (_bfd_in_memory): Declare.
	* libbfd.h: Re-generate.
	* opncls.c (bim_bread, bim_bwrite, bim_btell, bim_bflush, bim_bstat) 
	(bim_bseek, bim_bclose, bim_iovec, _bfd_in_memory): Implement BFD
	in memory.
	(bfd_close): Delete bfd-in-memory code.
	(bfd_make_writable): Use _bfd_in_memory.
	* bfdio.c (bfd_bread, bfd_bwrite, bfd_tell, bfd_flush, bfd_stat) 
	(bfd_seek, bfd_get_size): Delete bfd-in-memory code.
	* elfcode.h (bfd_from_remote_memory): Use _bfd_in_memory.
	* xcofflink.c (bfd_xcoff_link_generate_rtinit): Ditto.
	* coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Ditto.

Index: bfdio.c
===================================================================
RCS file: /cvs/src/src/bfd/bfdio.c,v
retrieving revision 1.6
diff -p -u -r1.6 bfdio.c
--- bfdio.c	21 Apr 2004 17:05:11 -0000	1.6
+++ bfdio.c	30 Apr 2004 21:38:39 -0000
@@ -97,7 +97,6 @@ DESCRIPTION
 
 */
 
-
 /* Return value is amount read.  */
 
 bfd_size_type
@@ -105,26 +104,6 @@ bfd_bread (void *ptr, bfd_size_type size
 {
   size_t nread;
 
-  if ((abfd->flags & BFD_IN_MEMORY) != 0)
-    {
-      struct bfd_in_memory *bim;
-      bfd_size_type get;
-
-      bim = abfd->iostream;
-      get = size;
-      if (abfd->where + get > bim->size)
-	{
-	  if (bim->size < (bfd_size_type) abfd->where)
-	    get = 0;
-	  else
-	    get = bim->size - abfd->where;
-	  bfd_set_error (bfd_error_file_truncated);
-	}
-      memcpy (ptr, bim->buffer + abfd->where, (size_t) get);
-      abfd->where += get;
-      return get;
-    }
-
   nread = abfd->iovec->bread (abfd, ptr, size);
   if (nread != (size_t) -1)
     abfd->where += nread;
@@ -137,33 +116,6 @@ bfd_bwrite (const void *ptr, bfd_size_ty
 {
   size_t nwrote;
 
-  if ((abfd->flags & BFD_IN_MEMORY) != 0)
-    {
-      struct bfd_in_memory *bim = abfd->iostream;
-      size = (size_t) size;
-      if (abfd->where + size > bim->size)
-	{
-	  bfd_size_type newsize, oldsize;
-
-	  oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
-	  bim->size = abfd->where + size;
-	  /* Round up to cut down on memory fragmentation */
-	  newsize = (bim->size + 127) & ~(bfd_size_type) 127;
-	  if (newsize > oldsize)
-	    {
-	      bim->buffer = bfd_realloc (bim->buffer, newsize);
-	      if (bim->buffer == 0)
-		{
-		  bim->size = 0;
-		  return 0;
-		}
-	    }
-	}
-      memcpy (bim->buffer + abfd->where, ptr, (size_t) size);
-      abfd->where += size;
-      return size;
-    }
-
   nwrote = abfd->iovec->bwrite (abfd, ptr, size);
   if (nwrote != (size_t) -1)
     abfd->where += nwrote;
@@ -182,9 +134,6 @@ bfd_tell (bfd *abfd)
 {
   file_ptr ptr;
 
-  if ((abfd->flags & BFD_IN_MEMORY) != 0)
-    return abfd->where;
-
   ptr = abfd->iovec->btell (abfd);
 
   if (abfd->my_archive)
@@ -196,8 +145,6 @@ bfd_tell (bfd *abfd)
 int
 bfd_flush (bfd *abfd)
 {
-  if ((abfd->flags & BFD_IN_MEMORY) != 0)
-    return 0;
   return abfd->iovec->bflush (abfd);
 }
 
@@ -208,9 +155,6 @@ bfd_stat (bfd *abfd, struct stat *statbu
 {
   int result;
 
-  if ((abfd->flags & BFD_IN_MEMORY) != 0)
-    abort ();
-
   result = abfd->iovec->bstat (abfd, statbuf);
   if (result < 0)
     bfd_set_error (bfd_error_system_call);
@@ -234,47 +178,6 @@ bfd_seek (bfd *abfd, file_ptr position, 
   if (direction == SEEK_CUR && position == 0)
     return 0;
 
-  if ((abfd->flags & BFD_IN_MEMORY) != 0)
-    {
-      struct bfd_in_memory *bim;
-
-      bim = abfd->iostream;
-
-      if (direction == SEEK_SET)
-	abfd->where = position;
-      else
-	abfd->where += position;
-
-      if (abfd->where > bim->size)
-	{
-	  if ((abfd->direction == write_direction) ||
-	      (abfd->direction == both_direction))
-	    {
-	      bfd_size_type newsize, oldsize;
-	      oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
-	      bim->size = abfd->where;
-	      /* Round up to cut down on memory fragmentation */
-	      newsize = (bim->size + 127) & ~(bfd_size_type) 127;
-	      if (newsize > oldsize)
-	        {
-		  bim->buffer = bfd_realloc (bim->buffer, newsize);
-		  if (bim->buffer == 0)
-		    {
-		      bim->size = 0;
-		      return -1;
-		    }
-	        }
-	    }
-	  else
-	    {
-	      abfd->where = bim->size;
-	      bfd_set_error (bfd_error_file_truncated);
-	      return -1;
-	    }
-	}
-      return 0;
-    }
-
   if (abfd->format != bfd_archive && abfd->my_archive == 0)
     {
 #if 0
@@ -407,9 +310,6 @@ long
 bfd_get_size (bfd *abfd)
 {
   struct stat buf;
-
-  if ((abfd->flags & BFD_IN_MEMORY) != 0)
-    return ((struct bfd_in_memory *) abfd->iostream)->size;
 
   if (abfd->iovec->bstat (abfd, &buf) != 0)
     return 0;
Index: coff-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-alpha.c,v
retrieving revision 1.20
diff -p -u -r1.20 coff-alpha.c
--- coff-alpha.c	30 Apr 2004 14:23:39 -0000	1.20
+++ coff-alpha.c	30 Apr 2004 21:38:39 -0000
@@ -2086,7 +2086,6 @@ alpha_ecoff_get_elt_at_filepos (archive,
   bfd_byte ab[8];
   bfd_size_type size;
   bfd_byte *buf, *p;
-  struct bfd_in_memory *bim;
 
   nbfd = _bfd_get_elt_at_filepos (archive, filepos);
   if (nbfd == NULL)
@@ -2181,19 +2180,11 @@ alpha_ecoff_get_elt_at_filepos (archive,
     }
 
   /* Now the uncompressed file contents are in buf.  */
-  bim = ((struct bfd_in_memory *)
-	 bfd_alloc (nbfd, (bfd_size_type) sizeof (struct bfd_in_memory)));
-  if (bim == NULL)
+  if (!_bfd_in_memory (nbfd, nbfd->flags, buf, size))
     goto error_return;
-  bim->size = size;
-  bim->buffer = buf;
 
   nbfd->mtime_set = TRUE;
   nbfd->mtime = strtol (hdr->ar_date, (char **) NULL, 10);
-
-  nbfd->flags |= BFD_IN_MEMORY;
-  nbfd->iostream = (PTR) bim;
-  BFD_ASSERT (! nbfd->cacheable);
 
   return nbfd;
 
Index: elfcode.h
===================================================================
RCS file: /cvs/src/src/bfd/elfcode.h,v
retrieving revision 1.55
diff -p -u -r1.55 elfcode.h
--- elfcode.h	22 Apr 2004 14:45:31 -0000	1.55
+++ elfcode.h	30 Apr 2004 21:38:40 -0000
@@ -1690,28 +1690,22 @@ NAME(_bfd_elf,bfd_from_remote_memory)
   memcpy (contents, &x_ehdr, sizeof x_ehdr);
 
   /* Now we have a memory image of the ELF file contents.  Make a BFD.  */
-  bim = bfd_malloc (sizeof (struct bfd_in_memory));
-  if (bim == NULL)
+  nbfd = _bfd_new_bfd ();
+  if (nbfd == NULL)
     {
       free (contents);
       bfd_set_error (bfd_error_no_memory);
       return NULL;
     }
-  nbfd = _bfd_new_bfd ();
-  if (nbfd == NULL)
+  if (!_bfd_in_memory (nbfd, 0, contents, contents_size))
     {
-      free (bim);
       free (contents);
+      bfd_close (nbfd);
       bfd_set_error (bfd_error_no_memory);
       return NULL;
     }
   nbfd->filename = "<in-memory>";
   nbfd->xvec = templ->xvec;
-  bim->size = contents_size;
-  bim->buffer = contents;
-  nbfd->iostream = bim;
-  nbfd->flags = BFD_IN_MEMORY;
-  nbfd->direction = read_direction;
   nbfd->mtime = time (NULL);
   nbfd->mtime_set = TRUE;
 
Index: libbfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd-in.h,v
retrieving revision 1.33
diff -p -u -r1.33 libbfd-in.h
--- libbfd-in.h	30 Apr 2004 14:23:39 -0000	1.33
+++ libbfd-in.h	30 Apr 2004 21:38:40 -0000
@@ -50,6 +50,9 @@ struct bfd_in_memory
   bfd_byte *buffer;
 };
 
+int _bfd_in_memory (struct bfd *abfd, flagword flags, void *buffer,
+		    bfd_size_type size);
+
 /* tdata for an archive.  For an input archive, cache
    needs to be free()'d.  For an output archive, symdefs do.  */
 
Index: opncls.c
===================================================================
RCS file: /cvs/src/src/bfd/opncls.c,v
retrieving revision 1.23
diff -p -u -r1.23 opncls.c
--- opncls.c	23 Apr 2004 00:22:57 -0000	1.23
+++ opncls.c	30 Apr 2004 21:38:40 -0000
@@ -1,7 +1,7 @@
 /* opncls.c -- open and close a BFD.
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2000,
-   2001, 2002, 2003
-   Free Software Foundation, Inc.
+
+   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+   2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    Written by Cygnus Support.
 
@@ -501,6 +501,185 @@ bfd_openr_iovec (const char *filename, c
   return nbfd;
 }
 
+
+
+/* BFD in memory.  */
+
+static file_ptr
+bim_btell (struct bfd *abfd)
+{
+  return abfd->where;
+}
+
+static int
+bim_bseek (struct bfd *abfd, file_ptr offset, int whence)
+{
+  struct bfd_in_memory *bim;
+
+  bim = abfd->iostream;
+      
+  if (whence == SEEK_SET)
+    abfd->where = offset;
+  else
+    abfd->where += offset;
+  
+  if (abfd->where > bim->size)
+    {
+      if ((abfd->direction == write_direction) ||
+	  (abfd->direction == both_direction))
+	{
+	  bfd_size_type newsize, oldsize;
+	  oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
+	  bim->size = abfd->where;
+	  /* Round up to cut down on memory fragmentation */
+	  newsize = (bim->size + 127) & ~(bfd_size_type) 127;
+	  if (newsize > oldsize)
+	    {
+	      bim->buffer = bfd_realloc (bim->buffer, newsize);
+	      if (bim->buffer == 0)
+		{
+		  bim->size = 0;
+		  return -1;
+		}
+	    }
+	}
+      else
+	{
+	  abfd->where = bim->size;
+	  bfd_set_error (bfd_error_file_truncated);
+	  return -1;
+	}
+    }
+  return 0;
+}
+
+static file_ptr
+bim_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
+{
+  struct bfd_in_memory *bim;
+  bfd_size_type get;
+  
+  bim = abfd->iostream;
+  get = nbytes;
+  if (abfd->where + get > bim->size)
+    {
+      if (bim->size < (bfd_size_type) abfd->where)
+	get = 0;
+      else
+	get = bim->size - abfd->where;
+    }
+  memcpy (buf, bim->buffer + abfd->where, (size_t) get);
+  abfd->where += get;
+  return get;
+}
+
+static file_ptr
+bim_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes)
+{
+  struct bfd_in_memory *bim = abfd->iostream;
+  size_t size;
+
+  size = (size_t) nbytes;
+  if (abfd->where + size > bim->size)
+    {
+      bfd_size_type newsize, oldsize;
+      
+      oldsize = (bim->size + 127) & ~(bfd_size_type) 127;
+      bim->size = abfd->where + size;
+      /* Round up to cut down on memory fragmentation */
+      newsize = (bim->size + 127) & ~(bfd_size_type) 127;
+      if (newsize > oldsize)
+	{
+	  bim->buffer = bfd_realloc (bim->buffer, newsize);
+	  if (bim->buffer == 0)
+	    {
+	      bim->size = 0;
+	      return 0;
+	    }
+	}
+    }
+  memcpy (bim->buffer + abfd->where, where, size);
+  abfd->where += size;
+  return size;
+}
+
+static int
+bim_bclose (struct bfd *abfd ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+static int
+bim_bflush (struct bfd *abfd ATTRIBUTE_UNUSED)
+{
+  return 0;
+}
+
+static int
+bim_bstat (struct bfd *abfd, struct stat *sb)
+{
+  struct bfd_in_memory *bim = abfd->iostream;
+
+  /* Assume we just "made" the BFD, and fake it.  */
+  memset (sb, 0, sizeof (*sb));
+  time (&sb->st_mtime);
+  sb->st_uid = getuid ();
+  sb->st_gid = getgid ();
+  sb->st_mode = 0644;
+  sb->st_size = bim->size;
+  return 0;
+}
+
+static const struct bfd_iovec bim_iovec = {
+  &bim_bread, &bim_bwrite, &bim_btell, &bim_bseek,
+  &bim_bclose, &bim_bflush, &bim_bstat
+};
+
+/*
+INTERNAL_FUNCTION
+	_bfd_in_memory
+
+SYNOPSIS
+        bfd_boolean _bfd_in_memory (bfd *abfd, flagword flags,
+	                            void *buffer, bfd_size_type size);
+
+DESCRIPTION
+
+        Convert @var{abfd} into a memory <<bfd> containing @var{size}
+        bytes of data at @var{buffer}.  If @var{buffer} is NULL, make
+        the @var{abfd} writeable.
+
+*/
+
+int
+_bfd_in_memory (struct bfd *abfd, flagword flags, void *buffer,
+		bfd_size_type size)
+{
+   struct bfd_in_memory *bim;
+
+   bim = ((struct bfd_in_memory *)
+	  bfd_alloc (abfd, (bfd_size_type) sizeof (struct bfd_in_memory)));
+   if (bim == NULL)
+     {
+       bfd_set_error (bfd_error_no_memory);
+       return FALSE;
+     }
+
+   bim->size = size;
+   bim->buffer = buffer;
+   abfd->iostream = bim;
+   abfd->iovec = &bim_iovec;
+   abfd->flags = flags | BFD_IN_MEMORY;
+   abfd->where = 0;
+   if (buffer != 0)
+     abfd->direction = read_direction;
+   else
+     abfd->direction = write_direction;
+   BFD_ASSERT (! abfd->cacheable);
+   return TRUE;
+}
+
+
 /* bfd_openw -- open for writing.
    Returns a pointer to a freshly-allocated BFD on success, or NULL.
 
@@ -593,12 +772,7 @@ bfd_close (bfd *abfd)
   if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
     return FALSE;
 
-  /* FIXME: cagney/2004-02-15: Need to implement a BFD_IN_MEMORY io
-     vector.  */
-  if (!(abfd->flags & BFD_IN_MEMORY))
-    ret = abfd->iovec->bclose (abfd);
-  else
-    ret = 0;
+  ret = abfd->iovec->bclose (abfd);
 
   /* If the file was open for writing and is now executable,
      make it so.  */
@@ -735,15 +909,9 @@ bfd_make_writable (bfd *abfd)
       return FALSE;
     }
 
-  bim = bfd_malloc (sizeof (struct bfd_in_memory));
-  abfd->iostream = bim;
-  /* bfd_bwrite will grow these as needed.  */
-  bim->size = 0;
-  bim->buffer = 0;
-
-  abfd->flags |= BFD_IN_MEMORY;
-  abfd->direction = write_direction;
-  abfd->where = 0;
+  /* bfd_bwrite will grow this as needed.  */
+  if (!_bfd_in_memory (abfd, abfd->flags, NULL, 0))
+    return FALSE;
 
   return TRUE;
 }
Index: xcofflink.c
===================================================================
RCS file: /cvs/src/src/bfd/xcofflink.c,v
retrieving revision 1.33
diff -p -u -r1.33 xcofflink.c
--- xcofflink.c	2 Dec 2003 22:59:59 -0000	1.33
+++ xcofflink.c	30 Apr 2004 21:38:41 -0000
@@ -3230,22 +3230,11 @@ bfd_xcoff_link_generate_rtinit (abfd, in
      const char *fini;
      bfd_boolean rtld;
 {
-  struct bfd_in_memory *bim;
-
-  bim = ((struct bfd_in_memory *)
-	 bfd_malloc ((bfd_size_type) sizeof (struct bfd_in_memory)));
-  if (bim == NULL)
+  if (!_bfd_in_memory (abfd, 0, NULL, 0))
     return FALSE;
 
-  bim->size = 0;
-  bim->buffer = 0;
-
   abfd->link_next = 0;
   abfd->format = bfd_object;
-  abfd->iostream = (PTR) bim;
-  abfd->flags = BFD_IN_MEMORY;
-  abfd->direction = write_direction;
-  abfd->where = 0;
 
   if (! bfd_xcoff_generate_rtinit (abfd, init, fini, rtld))
     return FALSE;

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