From 4c95ab762cbc17e3221e4cc38e728e665576793f Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Mon, 27 Jun 2011 08:41:00 +0000 Subject: [PATCH] 2011-06-27 Tristan Gingold * 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 | 12 ++++++++++++ bfd/bfd-in2.h | 3 ++- bfd/bfdio.c | 25 +++++++++++++++++++------ bfd/cache.c | 31 ++++++++++++++++++++++++++++--- bfd/libbfd.h | 10 ++++++++-- bfd/opncls.c | 4 +++- bfd/vms-lib.c | 12 +++++++----- 7 files changed, 79 insertions(+), 18 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5028141af1..0f3e422bfd 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2011-06-27 Tristan Gingold + + * 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 * vms-misc.c (vms_time_to_time_t): Adjust overflow detection. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 3c071ba55b..672c293e0b 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -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. */ diff --git a/bfd/bfdio.c b/bfd/bfdio.c index dab8e88fb2..841c781f4b 100644 --- a/bfd/bfdio.c +++ b/bfd/bfdio.c @@ -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; } diff --git a/bfd/cache.c b/bfd/cache.c index 2239c28aac..5ddbbe470a 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 @@ -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 diff --git a/bfd/libbfd.h b/bfd/libbfd.h index bd77d8fe81..dd4cc94440 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -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. */ diff --git a/bfd/opncls.c b/bfd/opncls.c index 40432000c0..9d33f3974f 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -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; } diff --git a/bfd/vms-lib.c b/bfd/vms-lib.c index 888982d899..0584186014 100644 --- a/bfd/vms-lib.c +++ b/bfd/vms-lib.c @@ -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; } -- 2.34.1