Compare commits

...

1 Commits

Author SHA1 Message Date
H.J. Lu
727aa8de05 Add mmap.c 2016-07-13 13:31:17 -07:00
13 changed files with 363 additions and 17 deletions

View File

@@ -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"...

View File

@@ -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@

View File

@@ -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. */

View File

@@ -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. *}

View File

@@ -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;
}

View File

@@ -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

74
bfd/configure vendored
View File

@@ -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"

View File

@@ -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])

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

227
bfd/mmap.c Normal file
View File

@@ -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);
}

View File

@@ -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;