From 25b88f335af1b8c7a4428710ffd9066338b167c0 Mon Sep 17 00:00:00 2001 From: Paul Pluzhnikov Date: Thu, 11 Jun 2009 00:41:03 +0000 Subject: [PATCH] 2009-06-10 Paul Pluzhnikov * bfd-in2.h: bfd_mmap prototype * bfdio.c (bfd_mmap): New function. * libbfd.h (bfd_iovec): Add bmmap. * cache.c (cache_bmap): New function. (cache_iovec): Initialize bmmap member. * opencls.c (opncls_bmmap): New function. (opncls_iovec): Initialize bmmap member. --- bfd/ChangeLog | 10 ++++++++++ bfd/bfd-in2.h | 1 + bfd/bfdio.c | 30 ++++++++++++++++++++++++++++++ bfd/cache.c | 34 +++++++++++++++++++++++++++++++++- bfd/libbfd.h | 3 +++ bfd/opncls.c | 13 ++++++++++++- 6 files changed, 89 insertions(+), 2 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 296493b19e4..545a5f7ebfb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2009-06-10 Paul Pluzhnikov + + * bfd-in2.h: bfd_mmap prototype + * bfdio.c (bfd_mmap): New function. + * libbfd.h (bfd_iovec): Add bmmap. + * cache.c (cache_bmap): New function. + (cache_iovec): Initialize bmmap member. + * opencls.c (opncls_bmmap): New function. + (opncls_iovec): Initialize bmmap member. + 2009-06-09 Tristan Gingold * mach-o.h (bfd_mach_o_symtab_command): Remove stabs_segment diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 004affe308d..6583aa61bbe 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -463,6 +463,7 @@ extern int bfd_seek (bfd *, file_ptr, int); extern file_ptr bfd_tell (bfd *); extern int bfd_flush (bfd *); extern int bfd_stat (bfd *, struct stat *); +extern void *bfd_mmap (bfd *, void *, bfd_size_type, int, int, file_ptr); /* Deprecated old routines. */ #if __GNUC__ diff --git a/bfd/bfdio.c b/bfd/bfdio.c index 16bbf03a697..9b853389cc0 100644 --- a/bfd/bfdio.c +++ b/bfd/bfdio.c @@ -158,6 +158,8 @@ DESCRIPTION . int (*bclose) (struct bfd *abfd); . int (*bflush) (struct bfd *abfd); . int (*bstat) (struct bfd *abfd, struct stat *sb); +. void* (*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len, +. int prot, int flags, file_ptr offset); .}; */ @@ -511,3 +513,31 @@ bfd_get_size (bfd *abfd) return buf.st_size; } + + +/* +FUNCTION + bfd_mmap + +SYNOPSIS + void *bfd_mmap (bfd *abfd, void *addr, bfd_size_type len, + int prot, int flags, file_ptr offset); + +DESCRIPTION + Return mmap()ed region of the file, if possible and implemented. + +*/ + +void * +bfd_mmap (bfd *abfd, void *addr, bfd_size_type len, + int prot, int flags, file_ptr offset) +{ + void *ret = (void *)-1; + if ((abfd->flags & BFD_IN_MEMORY) != 0) + return ret; + + if (abfd->iovec == NULL) + return ret; + + return abfd->iovec->bmmap (abfd, addr, len, prot, flags, offset); +} diff --git a/bfd/cache.c b/bfd/cache.c index 50674e88b0e..c6873a96de5 100644 --- a/bfd/cache.c +++ b/bfd/cache.c @@ -46,6 +46,10 @@ SUBSECTION #include "libbfd.h" #include "libiberty.h" +#ifdef HAVE_MMAP +#include +#endif + /* In some cases we can optimize cache operation when reopening files. For instance, a flush is entirely unnecessary if the file is already closed, so a flush would use CACHE_NO_OPEN. Similarly, a seek using @@ -388,10 +392,38 @@ cache_bstat (struct bfd *abfd, struct stat *sb) return sts; } +static void * +cache_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 *ret = (void *) -1; + + if ((abfd->flags & BFD_IN_MEMORY) != 0) + abort (); +#ifdef HAVE_MMAP + else + { + FILE *f = bfd_cache_lookup (abfd, CACHE_NO_SEEK_ERROR); + if (f == NULL) + return ret; + + ret = mmap (addr, len, prot, flags, fileno (f), offset); + if (ret == (void *) -1) + bfd_set_error (bfd_error_system_call); + } +#endif + + return ret; +} + static const struct bfd_iovec cache_iovec = { &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek, - &cache_bclose, &cache_bflush, &cache_bstat + &cache_bclose, &cache_bflush, &cache_bstat, &cache_bmmap }; /* diff --git a/bfd/libbfd.h b/bfd/libbfd.h index ea1a080a23b..7d72e3b9d01 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -773,6 +773,9 @@ 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. */ + void *(*bmmap) (struct bfd *abfd, void *addr, bfd_size_type len, + int prot, int flags, file_ptr offset); }; /* Extracted from bfdwin.c. */ struct _bfd_window_internal { diff --git a/bfd/opncls.c b/bfd/opncls.c index 7be82b21948..3add02f1867 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -505,9 +505,20 @@ opncls_bstat (struct bfd *abfd, struct stat *sb) return (vec->stat) (abfd, vec->stream, sb); } +static void * +opncls_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) +{ + return (void *) -1; +} + static const struct bfd_iovec opncls_iovec = { &opncls_bread, &opncls_bwrite, &opncls_btell, &opncls_bseek, - &opncls_bclose, &opncls_bflush, &opncls_bstat + &opncls_bclose, &opncls_bflush, &opncls_bstat, &opncls_bmmap }; bfd * -- 2.30.2