From 65077aa81507c722eb00b1ed594d2ee11c491cc6 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 26 May 2010 07:37:36 +0000 Subject: [PATCH] 2010-05-25 Tristan Gingold * bfdio.c: Declare and define _bfd_memory_iovec. (bfd_bread): Move code for BFD_IN_MEMORY... (bfd_bwrite): ... Ditto ... (bfd_tell): ... Ditto ... (bfd_flush): ... Ditto ... (bfd_stat): ... Ditto ... (bfd_seek): ... Ditto ... (bfd_get_size): ... Ditto ... (bfd_mmap): ... Ditto ... (memory_bread): ... to these new functions. (memory_bwrite): Ditto. (memory_btell): Ditto. (memory_bseek): Ditto. (memory_bflush): Ditto. (memory_bstat): Ditto. (memory_bmmap): Ditto. (memory_bclose): New function. * peicode.h (pe_ILF_build_a_bfd): Use BFD_IN_MEMORY. * xcofflink.c (bfd_xcoff_link_generate_rtinit): Ditto. * opncls.c (bfd_close): Do not handle BFD_IN_MEMORY case. (bfd_make_writable): Use _bfd_memory_iovec. * elfcode.h (bfd_from_remote_memory): Use _bfd_memory_iovec. * coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Use _bfd_memory_iovec. (alpha_ecoff_openr_next_archived_file): Use proxy_origin instead of origin. * libbfd.h: Regenerate. --- bfd/ChangeLog | 30 +++++++ bfd/bfdio.c | 266 ++++++++++++++++++++++++++++++++----------------------- bfd/coff-alpha.c | 4 +- bfd/elfcode.h | 2 + bfd/libbfd.h | 1 + bfd/opncls.c | 18 +--- bfd/peicode.h | 2 + bfd/xcofflink.c | 2 + 8 files changed, 200 insertions(+), 125 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 76924de..2f4d9e7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,33 @@ +2010-05-26 Tristan Gingold + + * bfdio.c: Declare and define _bfd_memory_iovec. + (bfd_bread): Move code for BFD_IN_MEMORY... + (bfd_bwrite): ... Ditto ... + (bfd_tell): ... Ditto ... + (bfd_flush): ... Ditto ... + (bfd_stat): ... Ditto ... + (bfd_seek): ... Ditto ... + (bfd_get_size): ... Ditto ... + (bfd_mmap): ... Ditto ... + (memory_bread): ... to these new functions. + (memory_bwrite): Ditto. + (memory_btell): Ditto. + (memory_bseek): Ditto. + (memory_bflush): Ditto. + (memory_bstat): Ditto. + (memory_bmmap): Ditto. + (memory_bclose): New function. + * peicode.h (pe_ILF_build_a_bfd): Use BFD_IN_MEMORY. + * xcofflink.c (bfd_xcoff_link_generate_rtinit): Ditto. + * opncls.c (bfd_close): Do not handle BFD_IN_MEMORY case. + (bfd_make_writable): Use _bfd_memory_iovec. + * elfcode.h (bfd_from_remote_memory): Use _bfd_memory_iovec. + * coff-alpha.c (alpha_ecoff_get_elt_at_filepos): Use + _bfd_memory_iovec. + (alpha_ecoff_openr_next_archived_file): Use proxy_origin + instead of origin. + * libbfd.h: Regenerate. + 2010-05-25 Daniel Jacobowitz Joseph Myers Andrew Stubbs diff --git a/bfd/bfdio.c b/bfd/bfdio.c index e428b16..4c13a76 100644 --- a/bfd/bfdio.c +++ b/bfd/bfdio.c @@ -163,6 +163,8 @@ DESCRIPTION . int prot, int flags, file_ptr offset); .}; +.extern const struct bfd_iovec _bfd_memory_iovec; + */ @@ -182,26 +184,6 @@ bfd_bread (void *ptr, bfd_size_type size, bfd *abfd) size = maxbytes; } - if ((abfd->flags & BFD_IN_MEMORY) != 0) - { - struct bfd_in_memory *bim; - bfd_size_type get; - - bim = (struct bfd_in_memory *) 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; - } - if (abfd->iovec) nread = abfd->iovec->bread (abfd, ptr, size); else @@ -217,37 +199,6 @@ bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd) { size_t nwrote; - if ((abfd->flags & BFD_IN_MEMORY) != 0) - { - struct bfd_in_memory *bim = (struct bfd_in_memory *) 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_byte *) bfd_realloc_or_free (bim->buffer, - newsize); - if (bim->buffer == NULL) - { - bim->size = 0; - return 0; - } - if (newsize > bim->size) - memset (bim->buffer + bim->size, 0, newsize - bim->size); - } - } - memcpy (bim->buffer + abfd->where, ptr, (size_t) size); - abfd->where += size; - return size; - } - if (abfd->iovec) nwrote = abfd->iovec->bwrite (abfd, ptr, size); else @@ -270,9 +221,6 @@ bfd_tell (bfd *abfd) { file_ptr ptr; - if ((abfd->flags & BFD_IN_MEMORY) != 0) - return abfd->where; - if (abfd->iovec) { ptr = abfd->iovec->btell (abfd); @@ -290,9 +238,6 @@ bfd_tell (bfd *abfd) int bfd_flush (bfd *abfd) { - if ((abfd->flags & BFD_IN_MEMORY) != 0) - return 0; - if (abfd->iovec) return abfd->iovec->bflush (abfd); return 0; @@ -305,9 +250,6 @@ bfd_stat (bfd *abfd, struct stat *statbuf) { int result; - if ((abfd->flags & BFD_IN_MEMORY) != 0) - abort (); - if (abfd->iovec) result = abfd->iovec->bstat (abfd, statbuf); else @@ -335,50 +277,6 @@ bfd_seek (bfd *abfd, file_ptr position, int direction) if (direction == SEEK_CUR && position == 0) return 0; - if ((abfd->flags & BFD_IN_MEMORY) != 0) - { - struct bfd_in_memory *bim; - - bim = (struct bfd_in_memory *) 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_byte *) bfd_realloc_or_free (bim->buffer, - newsize); - if (bim->buffer == NULL) - { - bim->size = 0; - return -1; - } - memset (bim->buffer + oldsize, 0, newsize - oldsize); - } - } - 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 (direction == SEEK_SET && (bfd_vma) position == abfd->where) @@ -505,9 +403,6 @@ 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 == NULL) return 0; @@ -536,11 +431,164 @@ bfd_mmap (bfd *abfd, void *addr, bfd_size_type len, int prot, int flags, file_ptr offset) { void *ret = (void *)-1; - if ((abfd->flags & BFD_IN_MEMORY) != 0) - return ret; if (abfd->iovec == NULL) return ret; return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset); } + +/* Memory file I/O operations. */ + +static file_ptr +memory_bread (bfd *abfd, void *ptr, file_ptr size) +{ + struct bfd_in_memory *bim; + bfd_size_type get; + + bim = (struct bfd_in_memory *) 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); + return get; +} + +static file_ptr +memory_bwrite (bfd *abfd, const void *ptr, file_ptr size) +{ + struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream; + + 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_byte *) bfd_realloc_or_free (bim->buffer, newsize); + if (bim->buffer == NULL) + { + bim->size = 0; + return 0; + } + if (newsize > bim->size) + memset (bim->buffer + bim->size, 0, newsize - bim->size); + } + } + memcpy (bim->buffer + abfd->where, ptr, (size_t) size); + return size; +} + +static file_ptr +memory_btell (bfd *abfd) +{ + return abfd->where; +} + +static int +memory_bseek (bfd *abfd, file_ptr position, int direction) +{ + file_ptr nwhere; + struct bfd_in_memory *bim; + + bim = (struct bfd_in_memory *) abfd->iostream; + + if (direction == SEEK_SET) + nwhere = position; + else + nwhere = abfd->where + position; + + if (nwhere < 0) + { + abfd->where = 0; + errno = EINVAL; + return -1; + } + + if ((bfd_size_type)nwhere > 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 = nwhere; + /* Round up to cut down on memory fragmentation */ + newsize = (bim->size + 127) & ~(bfd_size_type) 127; + if (newsize > oldsize) + { + bim->buffer = (bfd_byte *) bfd_realloc_or_free (bim->buffer, newsize); + if (bim->buffer == NULL) + { + errno = EINVAL; + bim->size = 0; + return -1; + } + memset (bim->buffer + oldsize, 0, newsize - oldsize); + } + } + else + { + abfd->where = bim->size; + errno = EINVAL; + bfd_set_error (bfd_error_file_truncated); + return -1; + } + } + return 0; +} + +static int +memory_bclose (struct bfd *abfd) +{ + struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream; + + if (bim->buffer != NULL) + free (bim->buffer); + free (bim); + abfd->iostream = NULL; + + return TRUE; +} + +static int +memory_bflush (bfd *abfd ATTRIBUTE_UNUSED) +{ + return 0; +} + +static int +memory_bstat (bfd *abfd, struct stat *statbuf) +{ + struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream; + + memset (statbuf, 0, sizeof (statbuf)); + statbuf->st_size = bim->size; + + return 0; +} + +static void * +memory_bmmap (bfd *abfd ATTRIBUTE_UNUSED, void *addr ATTRIBUTE_UNUSED, + bfd_size_type len ATTRIBUTE_UNUSED, int prot ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, file_ptr offset ATTRIBUTE_UNUSED) +{ + return (void *)-1; +} + +const struct bfd_iovec _bfd_memory_iovec = +{ + &memory_bread, &memory_bwrite, &memory_btell, &memory_bseek, + &memory_bclose, &memory_bflush, &memory_bstat, &memory_bmmap +}; diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c index 49af03a..12b49ac 100644 --- a/bfd/coff-alpha.c +++ b/bfd/coff-alpha.c @@ -2226,6 +2226,8 @@ alpha_ecoff_get_elt_at_filepos (archive, filepos) nbfd->flags |= BFD_IN_MEMORY; nbfd->iostream = (PTR) bim; + nbfd->iovec = &_bfd_memory_iovec; + nbfd->origin = 0; BFD_ASSERT (! nbfd->cacheable); return nbfd; @@ -2264,7 +2266,7 @@ alpha_ecoff_openr_next_archived_file (archive, last_file) /* Pad to an even boundary... Note that last_file->origin can be odd in the case of BSD-4.4-style element with a long odd size. */ - filestart = last_file->origin + size; + filestart = last_file->proxy_origin + size; filestart += filestart % 2; } diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 07ad3c9..cd06455 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -1841,6 +1841,8 @@ NAME(_bfd_elf,bfd_from_remote_memory) bim->buffer = contents; nbfd->iostream = bim; nbfd->flags = BFD_IN_MEMORY; + nbfd->iovec = &_bfd_memory_iovec; + nbfd->origin = 0; nbfd->direction = read_direction; nbfd->mtime = time (NULL); nbfd->mtime_set = TRUE; diff --git a/bfd/libbfd.h b/bfd/libbfd.h index b3f97f3..e12bbb4 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -845,6 +845,7 @@ struct bfd_iovec void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len, int prot, int flags, file_ptr offset); }; +extern const struct bfd_iovec _bfd_memory_iovec; /* Extracted from bfdwin.c. */ struct _bfd_window_internal { struct _bfd_window_internal *next; diff --git a/bfd/opncls.c b/bfd/opncls.c index 8b3d2e1..79c3274 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -696,20 +696,7 @@ bfd_close (bfd *abfd) if (! BFD_SEND (abfd, _close_and_cleanup, (abfd))) return FALSE; - if ((abfd->flags & BFD_IN_MEMORY) != 0) - { - /* FIXME: cagney/2004-02-15: Need to implement a BFD_IN_MEMORY io - vector. - Until that's done, at least don't leak memory. */ - struct bfd_in_memory *bim = (struct bfd_in_memory *) abfd->iostream; - - if (bim->buffer != NULL) - free (bim->buffer); - free (bim); - ret = TRUE; - } - else - ret = abfd->iovec->bclose (abfd); + ret = abfd->iovec->bclose (abfd); if (ret) _maybe_make_executable (abfd); @@ -823,6 +810,8 @@ bfd_make_writable (bfd *abfd) bim->buffer = 0; abfd->flags |= BFD_IN_MEMORY; + abfd->iovec = &_bfd_memory_iovec; + abfd->origin = 0; abfd->direction = write_direction; abfd->where = 0; @@ -861,7 +850,6 @@ bfd_make_readable (bfd *abfd) if (! BFD_SEND (abfd, _close_and_cleanup, (abfd))) return FALSE; - abfd->arch_info = &bfd_default_arch_struct; abfd->where = 0; diff --git a/bfd/peicode.h b/bfd/peicode.h index 8f25ef9..bca644d 100644 --- a/bfd/peicode.h +++ b/bfd/peicode.h @@ -1002,7 +1002,9 @@ pe_ILF_build_a_bfd (bfd * abfd, abfd->iostream = (void *) vars.bim; abfd->flags |= BFD_IN_MEMORY /* | HAS_LOCALS */; + abfd->iovec = &_bfd_memory_iovec; abfd->where = 0; + abfd->origin = 0; obj_sym_filepos (abfd) = 0; /* Now create a symbol describing the imported value. */ diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index 8198e93..30923cf 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -3976,7 +3976,9 @@ bfd_xcoff_link_generate_rtinit (bfd *abfd, abfd->format = bfd_object; abfd->iostream = (void *) bim; abfd->flags = BFD_IN_MEMORY; + abfd->iovec = &_bfd_memory_iovec; abfd->direction = write_direction; + abfd->origin = 0; abfd->where = 0; if (! bfd_xcoff_generate_rtinit (abfd, init, fini, rtld)) -- 2.7.4