aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/bfdio.c25
-rw-r--r--bfd/cache.c31
-rw-r--r--bfd/libbfd.h10
-rw-r--r--bfd/opncls.c4
-rw-r--r--bfd/vms-lib.c12
7 files changed, 79 insertions, 18 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 5028141..0f3e422 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,17 @@
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.
Add comment.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 3c071ba..672c293 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 dab8e88..841c781 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 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
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index bd77d8f..dd4cc94 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 4043200..9d33f39 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 888982d..0584186 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;
}