aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog10
-rw-r--r--bfd/bfd-in2.h1
-rw-r--r--bfd/bfdio.c30
-rw-r--r--bfd/cache.c34
-rw-r--r--bfd/libbfd.h3
-rw-r--r--bfd/opncls.c13
6 files changed, 89 insertions, 2 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 296493b..545a5f7 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,13 @@
+2009-06-10 Paul Pluzhnikov <ppluzhnikov@google.com>
+
+ * bfd-in2.h: bfd_mmap prototype
+ * bfdio.c (bfd_mmap): New function.
+ * libbfd.h (bfd_iovec): Add bmmap.
+ * cache.c (cache_bmap): New function.
+ (cache_iovec): Initialize bmmap member.
+ * opencls.c (opncls_bmmap): New function.
+ (opncls_iovec): Initialize bmmap member.
+
2009-06-09 Tristan Gingold <gingold@adacore.com>
* mach-o.h (bfd_mach_o_symtab_command): Remove stabs_segment
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 004affe..6583aa6 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -463,6 +463,7 @@ extern int bfd_seek (bfd *, file_ptr, int);
extern file_ptr bfd_tell (bfd *);
extern int bfd_flush (bfd *);
extern int bfd_stat (bfd *, struct stat *);
+extern void *bfd_mmap (bfd *, void *, bfd_size_type, int, int, file_ptr);
/* Deprecated old routines. */
#if __GNUC__
diff --git a/bfd/bfdio.c b/bfd/bfdio.c
index 16bbf03..9b85338 100644
--- a/bfd/bfdio.c
+++ b/bfd/bfdio.c
@@ -158,6 +158,8 @@ DESCRIPTION
. int (*bclose) (struct bfd *abfd);
. int (*bflush) (struct bfd *abfd);
. int (*bstat) (struct bfd *abfd, struct stat *sb);
+. void* (*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
+. int prot, int flags, file_ptr offset);
.};
*/
@@ -511,3 +513,31 @@ bfd_get_size (bfd *abfd)
return buf.st_size;
}
+
+
+/*
+FUNCTION
+ bfd_mmap
+
+SYNOPSIS
+ void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
+ int prot, int flags, file_ptr offset);
+
+DESCRIPTION
+ Return mmap()ed region of the file, if possible and implemented.
+
+*/
+
+void *
+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);
+}
diff --git a/bfd/cache.c b/bfd/cache.c
index 50674e8..c6873a9 100644
--- a/bfd/cache.c
+++ b/bfd/cache.c
@@ -46,6 +46,10 @@ SUBSECTION
#include "libbfd.h"
#include "libiberty.h"
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
+
/* In some cases we can optimize cache operation when reopening files.
For instance, a flush is entirely unnecessary if the file is already
closed, so a flush would use CACHE_NO_OPEN. Similarly, a seek using
@@ -388,10 +392,38 @@ cache_bstat (struct bfd *abfd, struct stat *sb)
return sts;
}
+static void *
+cache_bmmap (struct 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)
+{
+ void *ret = (void *) -1;
+
+ if ((abfd->flags & BFD_IN_MEMORY) != 0)
+ abort ();
+#ifdef HAVE_MMAP
+ else
+ {
+ FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
+ if (f == NULL)
+ return ret;
+
+ ret = mmap (addr, len, prot, flags, fileno (f), offset);
+ if (ret == (void *) -1)
+ bfd_set_error (bfd_error_system_call);
+ }
+#endif
+
+ return ret;
+}
+
static const struct bfd_iovec cache_iovec =
{
&cache_bread, &cache_bwrite, &cache_btell, &cache_bseek,
- &cache_bclose, &cache_bflush, &cache_bstat
+ &cache_bclose, &cache_bflush, &cache_bstat, &cache_bmmap
};
/*
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index ea1a080..7d72e3b 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -773,6 +773,9 @@ struct bfd_iovec
int (*bclose) (struct bfd *abfd);
int (*bflush) (struct bfd *abfd);
int (*bstat) (struct bfd *abfd, struct stat *sb);
+ /* Just like mmap: (void*)-1 on failure, mmapped address on success. */
+ void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
+ int prot, int flags, file_ptr offset);
};
/* Extracted from bfdwin.c. */
struct _bfd_window_internal {
diff --git a/bfd/opncls.c b/bfd/opncls.c
index 7be82b2..3add02f 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -505,9 +505,20 @@ opncls_bstat (struct bfd *abfd, struct stat *sb)
return (vec->stat) (abfd, vec->stream, sb);
}
+static void *
+opncls_bmmap (struct 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;
+}
+
static const struct bfd_iovec opncls_iovec = {
&opncls_bread, &opncls_bwrite, &opncls_btell, &opncls_bseek,
- &opncls_bclose, &opncls_bflush, &opncls_bstat
+ &opncls_bclose, &opncls_bflush, &opncls_bstat, &opncls_bmmap
};
bfd *