2009-06-10 Paul Pluzhnikov <ppluzhnikov@google.com>
authorPaul Pluzhnikov <ppluzhnikov@google.com>
Thu, 11 Jun 2009 00:41:03 +0000 (00:41 +0000)
committerPaul Pluzhnikov <ppluzhnikov@google.com>
Thu, 11 Jun 2009 00:41:03 +0000 (00:41 +0000)
* 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.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/bfdio.c
bfd/cache.c
bfd/libbfd.h
bfd/opncls.c

index 296493b19e4a5a6f26a00bbaf66c5cf92c55b418..545a5f7ebfb46dacc791016d533ae00bbf1fe55a 100644 (file)
@@ -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
index 004affe308ddc57848174c3f6ea038b1a1dea64f..6583aa61bbea9d4a403f7e4157bd939ec66f1a32 100644 (file)
@@ -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__
index 16bbf03a6970b619ed3d57dcb008f120a98c399c..9b853389cc0960eb2cedfebff655797af98e1fd7 100644 (file)
@@ -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);
+}
index 50674e88b0ece0b58f580dc5d07b179b56e4b75e..c6873a96de5ce324a3d2f0b10b09ab77b0f3f829 100644 (file)
@@ -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
 };
 
 /*
index ea1a080a23b4398459a41a7a337fa334f39aa69e..7d72e3b9d016d89cd00fa8278a22fab1d9569fd4 100644 (file)
@@ -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 {
index 7be82b21948c8e2d39f6f014b354fe211cbbb2bc..3add02f1867c6de5cfdbcd021376d1db3630d16b 100644 (file)
@@ -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 *