diff options
-rw-r--r-- | bfd/Makefile.am | 4 | ||||
-rw-r--r-- | bfd/Makefile.in | 11 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 3 | ||||
-rw-r--r-- | bfd/bfd.c | 4 | ||||
-rw-r--r-- | bfd/cache.c | 2 | ||||
-rw-r--r-- | bfd/config.in | 12 | ||||
-rwxr-xr-x | bfd/configure | 74 | ||||
-rw-r--r-- | bfd/configure.ac | 24 | ||||
-rw-r--r-- | bfd/doc/Makefile.am | 5 | ||||
-rw-r--r-- | bfd/doc/Makefile.in | 5 | ||||
-rw-r--r-- | bfd/libbfd.h | 5 | ||||
-rw-r--r-- | bfd/mmap.c | 227 | ||||
-rw-r--r-- | bfd/opncls.c | 4 |
13 files changed, 363 insertions, 17 deletions
diff --git a/bfd/Makefile.am b/bfd/Makefile.am index 6720f86..afbc958 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -80,7 +80,7 @@ BFD64_LIBS = archive64.lo BFD32_LIBS_CFILES = \ archive.c archures.c bfd.c bfdio.c bfdwin.c \ cache.c coff-bfd.c compress.c corefile.c format.c hash.c \ - init.c libbfd.c linker.c merge.c opncls.c reloc.c \ + init.c libbfd.c linker.c mmap.c merge.c opncls.c reloc.c \ section.c simple.c stab-syms.c stabs.c syms.c targets.c \ binary.c ihex.c srec.c tekhex.c verilog.c @@ -1002,7 +1002,7 @@ BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c section.c archures.c \ archive.c corefile.c targets.c format.c compress.c BFD64_H_FILES = archive64.c LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c bfdio.c bfdwin.c \ - cache.c reloc.c archures.c elf.c + cache.c reloc.c archures.c elf.c mmap.c LIBCOFF_H_FILES = libcoff-in.h coffcode.h # Could really use a "copy-if-change"... diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 7283ed9..02c37d5 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -146,9 +146,9 @@ LTLIBRARIES = $(bfdlib_LTLIBRARIES) $(noinst_LTLIBRARIES) am__DEPENDENCIES_1 = am__objects_1 = archive.lo archures.lo bfd.lo bfdio.lo bfdwin.lo \ cache.lo coff-bfd.lo compress.lo corefile.lo format.lo hash.lo \ - init.lo libbfd.lo linker.lo merge.lo opncls.lo reloc.lo \ - section.lo simple.lo stab-syms.lo stabs.lo syms.lo targets.lo \ - binary.lo ihex.lo srec.lo tekhex.lo verilog.lo + init.lo libbfd.lo linker.lo mmap.lo merge.lo opncls.lo \ + reloc.lo section.lo simple.lo stab-syms.lo stabs.lo syms.lo \ + targets.lo binary.lo ihex.lo srec.lo tekhex.lo verilog.lo am_libbfd_la_OBJECTS = $(am__objects_1) libbfd_la_OBJECTS = $(am_libbfd_la_OBJECTS) libbfd_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ @@ -412,7 +412,7 @@ BFD64_LIBS = archive64.lo BFD32_LIBS_CFILES = \ archive.c archures.c bfd.c bfdio.c bfdwin.c \ cache.c coff-bfd.c compress.c corefile.c format.c hash.c \ - init.c libbfd.c linker.c merge.c opncls.c reloc.c \ + init.c libbfd.c linker.c mmap.c merge.c opncls.c reloc.c \ section.c simple.c stab-syms.c stabs.c syms.c targets.c \ binary.c ihex.c srec.c tekhex.c verilog.c @@ -1175,7 +1175,7 @@ BFD_H_FILES = bfd-in.h init.c opncls.c libbfd.c section.c archures.c \ BFD64_H_FILES = archive64.c LIBBFD_H_FILES = libbfd-in.h init.c libbfd.c bfdio.c bfdwin.c \ - cache.c reloc.c archures.c elf.c + cache.c reloc.c archures.c elf.c mmap.c LIBCOFF_H_FILES = libcoff-in.h coffcode.h MOSTLYCLEANFILES = ofiles stamp-ofiles @@ -1579,6 +1579,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mach-o.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/merge.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mipsbsd.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmo.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netbsd-core.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/newsos3.Plo@am__quote@ diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 3f2d93b..72462af 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -6783,6 +6783,9 @@ struct bfd /* Pointer to structure which contains architecture information. */ const struct bfd_arch_info *arch_info; + /* Used by mmap_iovec. */ + int mmap_fd; + file_ptr mmap_size; /* Stuff only useful for archives. */ void *arelt_data; struct bfd *my_archive; /* The containing archive BFD. */ @@ -283,6 +283,10 @@ CODE_FRAGMENT . {* Pointer to structure which contains architecture information. *} . const struct bfd_arch_info *arch_info; . +. {* Used by mmap_iovec. *} +. int mmap_fd; +. file_ptr mmap_size; + . {* Stuff only useful for archives. *} . void *arelt_data; . struct bfd *my_archive; {* The containing archive BFD. *} diff --git a/bfd/cache.c b/bfd/cache.c index 8efbcb9..7918b67 100644 --- a/bfd/cache.c +++ b/bfd/cache.c @@ -656,7 +656,7 @@ bfd_open_file (bfd *abfd) bfd_set_error (bfd_error_system_call); else { - if (! bfd_cache_init (abfd)) + if (! bfd_mmap_init (abfd)) return NULL; } diff --git a/bfd/config.in b/bfd/config.in index 341afae..572b5f7 100644 --- a/bfd/config.in +++ b/bfd/config.in @@ -91,6 +91,9 @@ /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the `fallocate' function. */ +#undef HAVE_FALLOCATE + /* Define to 1 if you have the `fcntl' function. */ #undef HAVE_FCNTL @@ -160,9 +163,18 @@ /* Define to 1 if you have the `mprotect' function. */ #undef HAVE_MPROTECT +/* Define to 1 if you have the mremap function with MREMAP_MAYMOVE support */ +#undef HAVE_MREMAP + +/* Define to 1 if you have the msync function with MS_SYNC support */ +#undef HAVE_MSYNC + /* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */ #undef HAVE_NDIR_H +/* Define to 1 if you have the `posix_fallocate' function. */ +#undef HAVE_POSIX_FALLOCATE + /* Define if <sys/procfs.h> has prpsinfo32_t. */ #undef HAVE_PRPSINFO32_T diff --git a/bfd/configure b/bfd/configure index bc49dc4..a401e66 100755 --- a/bfd/configure +++ b/bfd/configure @@ -13689,7 +13689,7 @@ _ACEOF fi done -for ac_func in strtoull getrlimit +for ac_func in strtoull getrlimit posix_fallocate fallocate do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -16027,6 +16027,78 @@ $as_echo "#define USE_MMAP 1" >>confdefs.h ;; esac +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking mremap with MREMAP_MAYMOVE" >&5 +$as_echo_n "checking mremap with MREMAP_MAYMOVE... " >&6; } +if test "${bfd_cv_mremap_maymove+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#include <sys/mman.h> +void f() { mremap (0, 0, 0, MREMAP_MAYMOVE); } + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + bfd_cv_mremap_maymove=yes +else + bfd_cv_mremap_maymove=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_mremap_maymove" >&5 +$as_echo "$bfd_cv_mremap_maymove" >&6; } +if test "$bfd_cv_mremap_maymove" = "yes"; then + +$as_echo "#define HAVE_MREMAP 1" >>confdefs.h + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking msync with MS_SYNC" >&5 +$as_echo_n "checking msync with MS_SYNC... " >&6; } +if test "${bfd_cv_msync_ms_sync+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#include <sys/mman.h> +void f() { msync (0, 0, MS_SYNC); } + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + bfd_cv_msync_ms_sync=yes +else + bfd_cv_msync_ms_sync=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $bfd_cv_msync_ms_sync" >&5 +$as_echo "$bfd_cv_msync_ms_sync" >&6; } +if test "$bfd_cv_msync_ms_sync" = "yes"; then + +$as_echo "#define HAVE_MSYNC 1" >>confdefs.h + +fi + rm -f doc/config.status ac_config_files="$ac_config_files Makefile doc/Makefile bfd-in3.h:bfd-in2.h po/Makefile.in:po/Make-in" diff --git a/bfd/configure.ac b/bfd/configure.ac index 669cff7..3f3d504 100644 --- a/bfd/configure.ac +++ b/bfd/configure.ac @@ -204,7 +204,7 @@ AC_HEADER_DIRENT ACX_HEADER_STRING AC_CHECK_FUNCS(fcntl getpagesize setitimer sysconf fdopen getuid getgid fileno) -AC_CHECK_FUNCS(strtoull getrlimit) +AC_CHECK_FUNCS(strtoull getrlimit posix_fallocate fallocate) AC_CHECK_DECLS(basename) AC_CHECK_DECLS(ftello) @@ -1182,6 +1182,28 @@ case ${want_mmap}+${ac_cv_func_mmap_fixed_mapped} in true+yes ) AC_DEFINE(USE_MMAP, 1, [Use mmap if it's available?]) ;; esac +AC_CACHE_CHECK([mremap with MREMAP_MAYMOVE], [bfd_cv_mremap_maymove], +[AC_LINK_IFELSE([ +AC_LANG_PROGRAM([[ +#include <sys/mman.h> +void f() { mremap (0, 0, 0, MREMAP_MAYMOVE); } +]])], [bfd_cv_mremap_maymove=yes], [bfd_cv_mremap_maymove=no])]) +if test "$bfd_cv_mremap_maymove" = "yes"; then + AC_DEFINE(HAVE_MREMAP, 1, + [Define to 1 if you have the mremap function with MREMAP_MAYMOVE support]) +fi + +AC_CACHE_CHECK([msync with MS_SYNC], [bfd_cv_msync_ms_sync], +[AC_LINK_IFELSE([ +AC_LANG_PROGRAM([[ +#include <sys/mman.h> +void f() { msync (0, 0, MS_SYNC); } +]])], [bfd_cv_msync_ms_sync=yes], [bfd_cv_msync_ms_sync=no])]) +if test "$bfd_cv_msync_ms_sync" = "yes"; then + AC_DEFINE(HAVE_MSYNC, 1, + [Define to 1 if you have the msync function with MS_SYNC support]) +fi + rm -f doc/config.status AC_CONFIG_FILES([Makefile doc/Makefile bfd-in3.h:bfd-in2.h po/Makefile.in:po/Make-in]) diff --git a/bfd/doc/Makefile.am b/bfd/doc/Makefile.am index c44c803..10fcb7d 100644 --- a/bfd/doc/Makefile.am +++ b/bfd/doc/Makefile.am @@ -50,7 +50,7 @@ SRCDOC = $(srcdir)/../aoutx.h $(srcdir)/../archive.c \ $(srcdir)/../reloc.c $(srcdir)/../section.c \ $(srcdir)/../syms.c $(srcdir)/../targets.c \ $(srcdir)/../hash.c $(srcdir)/../linker.c \ - $(srcdir)/../mmo.c + $(srcdir)/../mmo.c $(srcdir)/../mmap.c SRCPROT = $(srcdir)/../archive.c $(srcdir)/../archures.c \ $(srcdir)/../bfd.c $(srcdir)/../coffcode.h $(srcdir)/../corefile.c \ @@ -64,7 +64,7 @@ SRCIPROT = $(srcdir)/../cache.c $(srcdir)/../libbfd.c \ $(srcdir)/../bfdio.c $(srcdir)/../bfdwin.c \ $(srcdir)/../reloc.c $(srcdir)/../cpu-h8300.c \ $(srcdir)/../cpu-i960.c $(srcdir)/../archures.c \ - $(srcdir)/../init.c + $(srcdir)/../init.c $(srcdir)/../mmap.c TEXIDIR = $(srcdir)/../../texinfo/fsf @@ -260,6 +260,7 @@ LIBBFD_H_DEP = \ $(srcdir)/../reloc.c \ $(srcdir)/../archures.c \ $(srcdir)/../elf.c \ + $(srcdir)/../mmap.c \ $(srcdir)/header.sed \ $(srcdir)/proto.str \ $(MKDOC) diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in index be737f6..9a19c6f 100644 --- a/bfd/doc/Makefile.in +++ b/bfd/doc/Makefile.in @@ -353,7 +353,7 @@ SRCDOC = $(srcdir)/../aoutx.h $(srcdir)/../archive.c \ $(srcdir)/../reloc.c $(srcdir)/../section.c \ $(srcdir)/../syms.c $(srcdir)/../targets.c \ $(srcdir)/../hash.c $(srcdir)/../linker.c \ - $(srcdir)/../mmo.c + $(srcdir)/../mmo.c $(srcdir)/../mmap.c SRCPROT = $(srcdir)/../archive.c $(srcdir)/../archures.c \ $(srcdir)/../bfd.c $(srcdir)/../coffcode.h $(srcdir)/../corefile.c \ @@ -367,7 +367,7 @@ SRCIPROT = $(srcdir)/../cache.c $(srcdir)/../libbfd.c \ $(srcdir)/../bfdio.c $(srcdir)/../bfdwin.c \ $(srcdir)/../reloc.c $(srcdir)/../cpu-h8300.c \ $(srcdir)/../cpu-i960.c $(srcdir)/../archures.c \ - $(srcdir)/../init.c + $(srcdir)/../init.c $(srcdir)/../mmap.c TEXIDIR = $(srcdir)/../../texinfo/fsf info_TEXINFOS = bfd.texinfo @@ -386,6 +386,7 @@ LIBBFD_H_DEP = \ $(srcdir)/../reloc.c \ $(srcdir)/../archures.c \ $(srcdir)/../elf.c \ + $(srcdir)/../mmap.c \ $(srcdir)/header.sed \ $(srcdir)/proto.str \ $(MKDOC) diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 2b1777e..616671d 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1,6 +1,6 @@ /* DO NOT EDIT! -*- buffer-read-only: t -*- This file is automatically generated from "libbfd-in.h", "init.c", "libbfd.c", "bfdio.c", - "bfdwin.c", "cache.c", "reloc.c", "archures.c" and "elf.c". + "bfdwin.c", "cache.c", "reloc.c", "archures.c", "elf.c" and "mmap.c". Run "make headers" in your build bfd/ to regenerate. */ /* libbfd.h -- Declarations used by bfd library *implementation*. @@ -3171,6 +3171,9 @@ void *bfd_arch_default_fill (bfd_size_type count, bfd_boolean code); /* Extracted from elf.c. */ +/* Extracted from mmap.c. */ +bfd_boolean bfd_mmap_init (bfd *abfd); + #ifdef __cplusplus } #endif diff --git a/bfd/mmap.c b/bfd/mmap.c new file mode 100644 index 0000000..a28dd6a --- /dev/null +++ b/bfd/mmap.c @@ -0,0 +1,227 @@ +/* BFD library -- mmap of file descriptors. + Copyright (C) 2016 Free Software Foundation, Inc. + This file is part of BFD, the Binary File Descriptor library. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, + MA 02110-1301, USA. */ + +#include "sysdep.h" + +#ifdef HAVE_MMAP +#include "bfd.h" +#include "libbfd.h" +#include "libiberty.h" +#include "bfd_stdint.h" + +#include <sys/mman.h> + +static file_ptr +mmap_btell (struct bfd *abfd) +{ + return abfd->where; +} + +/* Copied and modified from gold_fallocate in gold. */ + +static int +mmap_fallocate (int fd, file_ptr offset, file_ptr len) +{ +#ifdef HAVE_FALLOCATE + if (fallocate (fd, 0, offset, len) == 0) + return 0; +#endif +#ifdef HAVE_POSIX_FALLOCATE + return posix_fallocate (fd, offset, len); +#endif + if (ftruncate (fd, offset + len) < 0) + return errno; + return 0; +} + +static int +mmap_resize (bfd *abfd, file_ptr size) +{ + if (mmap_fallocate (abfd->mmap_fd, 0, size) != 0) + { +syscall_error: + bfd_set_error (bfd_error_system_call); + abfd->mmap_size = 0; + return -1; + } + if (abfd->mmap_size != 0) + { +#ifdef HAVE_MREMAP + abfd->iostream = mremap (abfd->iostream, abfd->mmap_size, + size, MREMAP_MAYMOVE); + if (abfd->iostream == MAP_FAILED) + goto syscall_error; + else + goto success; +#else + if (munmap (abfd->iostream, abfd->mmap_size) != 0) + goto syscall_error; +#endif + } + abfd->iostream = mmap (NULL, size, PROT_READ | PROT_WRITE, + MAP_SHARED, abfd->mmap_fd, 0); + if (abfd->iostream == MAP_FAILED) + goto syscall_error; + +success: + abfd->mmap_size = size; + return 0; +} + +static int +mmap_bseek (bfd *abfd, file_ptr position, int direction) +{ + file_ptr nwhere; + + if (direction == SEEK_SET) + nwhere = position; + else + nwhere = abfd->where + position; + + if (nwhere < 0) + { + abfd->where = 0; + errno = EINVAL; + return -1; + } + else if (nwhere >= abfd->mmap_size && mmap_resize (abfd, nwhere) != 0) + return -1; + + return 0; +} + +static file_ptr +mmap_bread (struct bfd *abfd, void *buf, file_ptr size) +{ + memcpy (buf, abfd->iostream + abfd->where, size); + return size; +} + +static file_ptr +mmap_bwrite (bfd *abfd, const void *ptr, file_ptr size) +{ + file_ptr filesize = abfd->where + size; + + if (filesize > abfd->mmap_size && mmap_resize (abfd, filesize) != 0) + { + bfd_set_error (bfd_error_system_call); + return 0; + } + + memcpy (abfd->iostream + abfd->where, ptr, size); + return size; +} + +static int +mmap_bclose (struct bfd *abfd) +{ + int status = munmap (abfd->iostream, abfd->mmap_size); + if (status == 0) + status = close (abfd->mmap_fd); + if (status != 0) + bfd_set_error (bfd_error_system_call); + + abfd->iostream = MAP_FAILED; + abfd->mmap_size = 0; + abfd->mmap_fd = -1; + + return status; +} + +static int +mmap_bflush (struct bfd *abfd ATTRIBUTE_UNUSED) +{ +#ifdef HAVE_MSYNC + int status = msync (abfd->iostream, abfd->mmap_size, MS_SYNC); + if (status != 0) + bfd_set_error (bfd_error_system_call); + return status; +#else + return 0; +#endif +} + +static int +mmap_bstat (struct bfd *abfd ATTRIBUTE_UNUSED, struct stat *sb) +{ + int status; + status = fstat (abfd->mmap_fd, sb); + if (status < 0) + bfd_set_error (bfd_error_system_call); + return status; +} + +static void * +mmap_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 **map_addr ATTRIBUTE_UNUSED, + bfd_size_type *map_len ATTRIBUTE_UNUSED) +{ + /* Unsupported. */ + abort (); + return 0; +} + +static const struct bfd_iovec mmap_iovec = +{ + &mmap_bread, &mmap_bwrite, &mmap_btell, &mmap_bseek, + &mmap_bclose, &mmap_bflush, &mmap_bstat, &mmap_bmmap +}; +#endif + +/* +INTERNAL_FUNCTION + bfd_mmap_init + +SYNOPSIS + bfd_boolean bfd_mmap_init (bfd *abfd); + +DESCRIPTION + Use mmap on BFD. Fallback to bfd_cache_init. +*/ + +bfd_boolean +bfd_mmap_init (bfd *abfd) +{ +#ifdef HAVE_MMAP + /* Only suport write before writing starts. */ + if (abfd->direction == write_direction + && !abfd->output_has_begun) + { + if (abfd->mmap_size != 0 || abfd->iostream == NULL) + abort (); + + abfd->mmap_fd = dup (fileno (abfd->iostream)); + if (abfd->mmap_fd < 0) + { + bfd_set_error (bfd_error_system_call); + return FALSE; + } + + abfd->iovec = &mmap_iovec; + return TRUE; + } +#endif + + return bfd_cache_init (abfd); +} diff --git a/bfd/opncls.c b/bfd/opncls.c index b86bbab..b1da1cd 100644 --- a/bfd/opncls.c +++ b/bfd/opncls.c @@ -242,7 +242,7 @@ bfd_fopen (const char *filename, const char *target, const char *mode, int fd) else nbfd->direction = write_direction; - if (! bfd_cache_init (nbfd)) + if (! bfd_mmap_init (nbfd)) { _bfd_delete_bfd (nbfd); return NULL; @@ -400,7 +400,7 @@ bfd_openstreamr (const char *filename, const char *target, void *streamarg) nbfd->filename = xstrdup (filename); nbfd->direction = read_direction; - if (! bfd_cache_init (nbfd)) + if (! bfd_mmap_init (nbfd)) { _bfd_delete_bfd (nbfd); return NULL; |