* linux-arm-low.c: Include <signal.h>.
[deliverable/binutils-gdb.git] / bfd / cache.c
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
 
This page took 0.023771 seconds and 4 git commands to generate.