aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog30
-rw-r--r--bfd/bfdio.c266
-rw-r--r--bfd/coff-alpha.c4
-rw-r--r--bfd/elfcode.h2
-rw-r--r--bfd/libbfd.h1
-rw-r--r--bfd/opncls.c18
-rw-r--r--bfd/peicode.h2
-rw-r--r--bfd/xcofflink.c2
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 <gingold@adacore.com>
+
+ * 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 <dan@codesourcery.com>
Joseph Myers <joseph@codesourcery.com>
Andrew Stubbs <ams@codesourcery.com>
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))