From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31372 invoked by alias); 1 May 2004 18:10:35 -0000 Mailing-List: contact binutils-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sources.redhat.com Received: (qmail 31365 invoked from network); 1 May 2004 18:10:34 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sources.redhat.com with SMTP; 1 May 2004 18:10:34 -0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.10/8.12.10) with ESMTP id i41IAYKI007720 for ; Sat, 1 May 2004 14:10:34 -0400 Received: from localhost.redhat.com (porkchop.devel.redhat.com [172.16.58.2]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id i41IAXv29132; Sat, 1 May 2004 14:10:33 -0400 Received: from gnu.org (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id D41872B9D; Sat, 1 May 2004 14:10:31 -0400 (EDT) Message-ID: <4093E817.9060704@gnu.org> Date: Sat, 01 May 2004 18:10:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-GB; rv:1.4.1) Gecko/20040217 MIME-Version: 1.0 To: binutils@sources.redhat.com Subject: Re: [rfa] Add bfd-in-memory io vector References: <4092CA10.6090205@gnu.org> In-Reply-To: <4092CA10.6090205@gnu.org> Content-Type: multipart/mixed; boundary="------------090203080106050405020306" X-SW-Source: 2004-05/txt/msg00023.txt.bz2 This is a multi-part message in MIME format. --------------090203080106050405020306 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 712 > 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 :-/ Here's a revised patch. An audit of remaining BFD_IN_MEMORY references turned up a likely bug in peicode.h. This revision includes what I think is the necessary change. The testing comment still applies though. Ok? Andrew --------------090203080106050405020306 Content-Type: text/plain; name="diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diffs" Content-length: 16162 * libbfd-in.h (_bfd_in_memory): Declare. * libbfd.h: Re-generate. * peicode.h (pe_ILF_build_a_bfd): Call _bfd_in_memory, set vars.bim to value returned. (ILF_DATA_SIZE): Do not include "bim" in size. * 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 1 May 2004 18:00:59 -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 1 May 2004 18:01:00 -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 1 May 2004 18:01:00 -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 = ""; 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 1 May 2004 18:01:00 -0000 @@ -50,6 +50,9 @@ struct bfd_in_memory bfd_byte *buffer; }; +struct bfd_in_memory *_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 1 May 2004 18:01:00 -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,187 @@ 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 + struct bfd_in_memory *_bfd_in_memory (bfd *abfd, flagword flags, + void *buffer, + bfd_size_type size); + +DESCRIPTION + + Convert @var{abfd} into a memory < containing @var{size} + bytes of data at @var{buffer}. If @var{buffer} is NULL, make + the @var{abfd} writeable. Return a pointer to the <>, or NULL if there is an error. + +*/ + +struct bfd_in_memory * +_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 NULL; + } + + 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 bim; +} + + /* bfd_openw -- open for writing. Returns a pointer to a freshly-allocated BFD on success, or NULL. @@ -593,12 +774,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 +911,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: peicode.h =================================================================== RCS file: /cvs/src/src/bfd/peicode.h,v retrieving revision 1.40 diff -p -u -r1.40 peicode.h --- peicode.h 16 Dec 2003 11:10:42 -0000 1.40 +++ peicode.h 1 May 2004 18:01:01 -0000 @@ -448,8 +448,7 @@ pe_bfd_copy_private_bfd_data (ibfd, obfd #define SIZEOF_ILF_SECTIONS (NUM_ILF_SECTIONS * sizeof (struct coff_section_tdata)) #define ILF_DATA_SIZE \ - sizeof (* vars.bim) \ - + SIZEOF_ILF_SYMS \ + SIZEOF_ILF_SYMS \ + SIZEOF_ILF_SYM_TABLE \ + SIZEOF_ILF_NATIVE_SYMS \ + SIZEOF_ILF_SYM_PTR_TABLE \ @@ -771,6 +770,7 @@ pe_ILF_build_a_bfd (bfd * abfd asection_ptr id4, id5, id6 = NULL, text = NULL; coff_symbol_type ** imp_sym; unsigned int imp_index; + struct bfd_in_memory bim; /* Decode and verify the types field of the ILF structure. */ import_type = types & 0x3; @@ -820,10 +820,8 @@ pe_ILF_build_a_bfd (bfd * abfd return FALSE; /* Create a bfd_in_memory structure. */ - vars.bim = (struct bfd_in_memory *) ptr; - vars.bim->buffer = ptr; - vars.bim->size = ILF_DATA_SIZE; - ptr += sizeof (* vars.bim); + bim.buffer = ptr; + bim.size = ILF_DATA_SIZE; /* Initialise the pointers to regions of the memory and the other contents of the pe_ILF_vars structure as well. */ @@ -1046,9 +1044,10 @@ pe_ILF_build_a_bfd (bfd * abfd /* Switch from file contents to memory contents. */ bfd_cache_close (abfd); - abfd->iostream = (PTR) vars.bim; - abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */; - abfd->where = 0; + vars.bim = _bfd_in_memory (abfd, abfd->flags, vars.bim->buffer, + vars.bim->size); + if (vars.bim == NULL) + return FALSE; obj_sym_filepos (abfd) = 0; /* Now create a symbol describing the imported value. */ 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 1 May 2004 18:01:02 -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; --------------090203080106050405020306--