2011-06-27 Tristan Gingold <gingold@adacore.com>
authorTristan Gingold <gingold@adacore.com>
Mon, 27 Jun 2011 08:41:00 +0000 (08:41 +0000)
committerTristan Gingold <gingold@adacore.com>
Mon, 27 Jun 2011 08:41:00 +0000 (08:41 +0000)
* cache.c: Include bfd_stdint.h.
(cache_bmmap): Change profile.  Return region start and size.
* bfdio.c (struct bfd_iovec): Change bmmap profile.
(bfd_mmap): Change profile and adjust.   Update comment.
(memory_bmmap): Change profile.
* opncls.c (opncls_bmmap): Change profile.
* vms-lib.c (vms_lib_bmmap): Likewise.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.

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

index 5028141af182383a0ae606d3f356ab1a541b9cf3..0f3e422bfd4b2d17d42e61ae948902d6496232ab 100644 (file)
@@ -1,3 +1,15 @@
+2011-06-27  Tristan Gingold  <gingold@adacore.com>
+
+       * cache.c: Include bfd_stdint.h.
+       (cache_bmmap): Change profile.  Return region start and size.
+       * bfdio.c (struct bfd_iovec): Change bmmap profile.
+       (bfd_mmap): Change profile and adjust.   Update comment.
+       (memory_bmmap): Change profile.
+       * opncls.c (opncls_bmmap): Change profile.
+       * vms-lib.c (vms_lib_bmmap): Likewise.
+       * libbfd.h: Regenerate.
+       * bfd-in2.h: Regenerate.
+
 2011-06-27  Tristan Gingold  <gingold@adacore.com>
 
        * vms-misc.c (vms_time_to_time_t): Adjust overflow detection.
index 3c071ba55be8a444ea9638de6834fce1cbd7a075..672c293e0be5fe0e7bf7007eaadda8bb94f9a3b5 100644 (file)
@@ -1143,7 +1143,8 @@ long bfd_get_mtime (bfd *abfd);
 file_ptr bfd_get_size (bfd *abfd);
 
 void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
-    int prot, int flags, file_ptr offset);
+    int prot, int flags, file_ptr offset,
+    void **map_addr, bfd_size_type *map_len);
 
 /* Extracted from bfdwin.c.  */
 /* Extracted from section.c.  */
index dab8e88fb23cf2db09a6c6e9f0438084a9c63e1e..841c781f4bd8e08f4abc842199bf1ad4dc147cd4 100644 (file)
@@ -158,9 +158,15 @@ DESCRIPTION
 .  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.  *}
+.  {* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual
+.     mmap parameter, except that LEN and OFFSET do not need to be page
+.     aligned.  Returns (void *)-1 on failure, mmapped address on success.
+.     Also write in MAP_ADDR the address of the page aligned buffer and in
+.     MAP_LEN the size mapped (a page multiple).  Use unmap with MAP_ADDR and
+.     MAP_LEN to unmap.  *}
 .  void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
-.                  int prot, int flags, file_ptr offset);
+.                  int prot, int flags, file_ptr offset,
+.                  void **map_addr, bfd_size_type *map_len);
 .};
 
 .extern const struct bfd_iovec _bfd_memory_iovec;
@@ -423,23 +429,28 @@ FUNCTION
 
 SYNOPSIS
        void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
-                       int prot, int flags, file_ptr offset);
+                       int prot, int flags, file_ptr offset,
+                       void **map_addr, bfd_size_type *map_len);
 
 DESCRIPTION
        Return mmap()ed region of the file, if possible and implemented.
+        LEN and OFFSET do not need to be page aligned.  The page aligned
+        address and length are written to MAP_ADDR and MAP_LEN.
 
 */
 
 void *
 bfd_mmap (bfd *abfd, void *addr, bfd_size_type len,
-         int prot, int flags, file_ptr offset)
+         int prot, int flags, file_ptr offset,
+          void **map_addr, bfd_size_type *map_len)
 {
   void *ret = (void *)-1;
 
   if (abfd->iovec == NULL)
     return ret;
 
-  return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset);
+  return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset,
+                             map_addr, map_len);
 }
 
 /* Memory file I/O operations.  */
@@ -586,7 +597,9 @@ memory_bstat (bfd *abfd, struct stat *statbuf)
 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)
+              int flags ATTRIBUTE_UNUSED, file_ptr offset ATTRIBUTE_UNUSED,
+              void **map_addr ATTRIBUTE_UNUSED,
+              bfd_size_type *map_len ATTRIBUTE_UNUSED)
 {
   return (void *)-1;
 }
index 2239c28aac44f357b83e685e91e0605b79e785de..5ddbbe470a04e66c49a1d5dc0c8547823bc6d255 100644 (file)
@@ -45,6 +45,7 @@ SUBSECTION
 #include "bfd.h"
 #include "libbfd.h"
 #include "libiberty.h"
+#include "bfd_stdint.h"
 
 #ifdef HAVE_MMAP
 #include <sys/mman.h>
@@ -398,7 +399,9 @@ cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
             bfd_size_type len ATTRIBUTE_UNUSED,
             int prot ATTRIBUTE_UNUSED,
             int flags ATTRIBUTE_UNUSED,
-            file_ptr offset ATTRIBUTE_UNUSED)
+            file_ptr offset ATTRIBUTE_UNUSED,
+             void **map_addr ATTRIBUTE_UNUSED,
+             bfd_size_type *map_len ATTRIBUTE_UNUSED)
 {
   void *ret = (void *) -1;
 
@@ -407,13 +410,35 @@ cache_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
 #ifdef HAVE_MMAP
   else
     {
-      FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
+      static uintptr_t pagesize_m1;
+      FILE *f;
+      file_ptr pg_offset;
+      bfd_size_type pg_len;
+
+      f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR);
       if (f == NULL)
        return ret;
 
-      ret = mmap (addr, len, prot, flags, fileno (f), offset);
+      if (pagesize_m1 == 0)
+        pagesize_m1 = getpagesize () - 1;
+
+      /* Handle archive members.  */
+      if (abfd->my_archive != NULL)
+        offset += abfd->origin;
+
+      /* Align.  */
+      pg_offset = offset & ~pagesize_m1;
+      pg_len = (len + (offset - pg_offset) + pagesize_m1) & ~pagesize_m1;
+
+      ret = mmap (addr, pg_len, prot, flags, fileno (f), pg_offset);
       if (ret == (void *) -1)
        bfd_set_error (bfd_error_system_call);
+      else
+        {
+          *map_addr = ret;
+          *map_len = pg_len;
+          ret += offset & pagesize_m1;
+        }
     }
 #endif
 
index bd77d8fe811f9f199a8e0d6c00f44f826620d76a..dd4cc944408b05c48747ccb5b43f96e78419673f 100644 (file)
@@ -850,9 +850,15 @@ 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.  */
+  /* Mmap a part of the files. ADDR, LEN, PROT, FLAGS and OFFSET are the usual
+     mmap parameter, except that LEN and OFFSET do not need to be page
+     aligned.  Returns (void *)-1 on failure, mmapped address on success.
+     Also write in MAP_ADDR the address of the page aligned buffer and in
+     MAP_LEN the size mapped (a page multiple).  Use unmap with MAP_ADDR and
+     MAP_LEN to unmap.  */
   void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len,
-                  int prot, int flags, file_ptr offset);
+                  int prot, int flags, file_ptr offset,
+                  void **map_addr, bfd_size_type *map_len);
 };
 extern const struct bfd_iovec _bfd_memory_iovec;
 /* Extracted from bfdwin.c.  */
index 40432000c0abc3cb3984cbc022206efd9f7ab236..9d33f3974fb0b3f214a14272463092f0a61e9860 100644 (file)
@@ -525,7 +525,9 @@ opncls_bmmap (struct bfd *abfd ATTRIBUTE_UNUSED,
              bfd_size_type len ATTRIBUTE_UNUSED,
              int prot ATTRIBUTE_UNUSED,
              int flags ATTRIBUTE_UNUSED,
-             file_ptr offset ATTRIBUTE_UNUSED)
+             file_ptr offset ATTRIBUTE_UNUSED,
+              void **map_addr ATTRIBUTE_UNUSED,
+              bfd_size_type *map_len ATTRIBUTE_UNUSED)
 {
   return (void *) -1;
 }
index 888982d89917ac5fff9b8960412d594095b58782..0584186014b20c7251c5cb3c863439271e216650 100644 (file)
@@ -1196,11 +1196,13 @@ vms_lib_bstat (struct bfd *abfd ATTRIBUTE_UNUSED,
 
 static void *
 vms_lib_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 *addr ATTRIBUTE_UNUSED,
+               bfd_size_type len ATTRIBUTE_UNUSED,
+               int prot ATTRIBUTE_UNUSED,
+               int flags ATTRIBUTE_UNUSED,
+               file_ptr offset ATTRIBUTE_UNUSED,
+               void **map_addr ATTRIBUTE_UNUSED,
+               bfd_size_type *map_len ATTRIBUTE_UNUSED)
 {
   return (void *) -1;
 }