diff options
Diffstat (limited to 'bfd/cache.c')
-rw-r--r-- | bfd/cache.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/bfd/cache.c b/bfd/cache.c index 2239c28..5ddbbe4 100644 --- a/bfd/cache.c +++ b/bfd/cache.c @@ -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 |