summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-04-12 10:18:24 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-04-12 15:31:25 -0700
commit750c0a6c1fc889f71120578432bf9a83475caa33 (patch)
tree07384d81abd407356eb1cee5396c3587bee766f5
parent2c3e9fe24f79bb7cc618fc881272a47b828b07bb (diff)
downloadbinutils-gdb-750c0a6c1fc889f71120578432bf9a83475caa33.tar.gz
Add mmap.c
Add mmap_size and mmap_fd to bfd. Add bfd_cache_snip.
-rw-r--r--bfd/Makefile.am2
-rw-r--r--bfd/Makefile.in9
-rw-r--r--bfd/bfd-in.h5
-rw-r--r--bfd/bfd-in2.h23
-rw-r--r--bfd/bfd.c18
-rw-r--r--bfd/cache.c19
-rw-r--r--bfd/config.in9
-rwxr-xr-xbfd/configure38
-rw-r--r--bfd/configure.ac13
-rw-r--r--bfd/libbfd.h2
-rw-r--r--bfd/mmap.c288
-rw-r--r--bfd/opncls.c14
-rw-r--r--ld/ldlang.c6
-rw-r--r--ld/plugin.c6
14 files changed, 419 insertions, 33 deletions
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 03b644261ad..a97317f70c1 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
diff --git a/bfd/Makefile.in b/bfd/Makefile.in
index aac3eb2b9dc..a3e5086dd55 100644
--- a/bfd/Makefile.in
+++ b/bfd/Makefile.in
@@ -123,9 +123,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) \
@@ -383,7 +383,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
@@ -1540,6 +1540,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)/newsos3.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nlm.Plo@am__quote@
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 1f8a72c40eb..bbc8ad79083 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -506,7 +506,7 @@ extern void warn_deprecated (const char *, const char *, int, const char *);
#define bfd_is_thin_archive(abfd) ((abfd)->is_thin_archive)
#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types)
-#define bfd_usrdata(abfd) ((abfd)->usrdata)
+#define bfd_usrdata(abfd) ((abfd)->u.usrdata)
#define bfd_get_start_address(abfd) ((abfd)->start_address)
#define bfd_get_symcount(abfd) ((abfd)->symcount)
@@ -523,6 +523,9 @@ extern bfd_boolean bfd_cache_close
extern bfd_boolean bfd_cache_close_all (void);
+extern bfd_boolean bfd_mmap_resize (bfd *, file_ptr);
+extern bfd_boolean bfd_mmap_close (bfd *);
+
extern bfd_boolean bfd_record_phdr
(bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma,
bfd_boolean, bfd_boolean, unsigned int, struct bfd_section **);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 679595e0c5a..422fc2d6ce9 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -513,7 +513,7 @@ extern void warn_deprecated (const char *, const char *, int, const char *);
#define bfd_is_thin_archive(abfd) ((abfd)->is_thin_archive)
#define bfd_valid_reloc_types(abfd) ((abfd)->xvec->valid_reloc_types)
-#define bfd_usrdata(abfd) ((abfd)->usrdata)
+#define bfd_usrdata(abfd) ((abfd)->u.usrdata)
#define bfd_get_start_address(abfd) ((abfd)->start_address)
#define bfd_get_symcount(abfd) ((abfd)->symcount)
@@ -530,6 +530,9 @@ extern bfd_boolean bfd_cache_close
extern bfd_boolean bfd_cache_close_all (void);
+extern bfd_boolean bfd_mmap_resize (bfd *, file_ptr);
+extern bfd_boolean bfd_mmap_close (bfd *);
+
extern bfd_boolean bfd_record_phdr
(bfd *, unsigned long, bfd_boolean, flagword, bfd_boolean, bfd_vma,
bfd_boolean, bfd_boolean, unsigned int, struct bfd_section **);
@@ -6456,9 +6459,13 @@ struct bfd
/* Set if this is a plugin output file. */
unsigned int lto_output : 1;
- /* Set to dummy BFD created when claimed by a compiler plug-in
- library. */
- bfd *plugin_dummy_bfd;
+ union {
+ /* For input BFDs, set to dummy BFD created when claimed by a
+ compiler plug-in library. */
+ bfd *plugin_dummy_bfd;
+ /* For output BFD, used by mmap.c for mapped size. */
+ file_ptr mmap_size;
+ } io;
/* Currently my_archive is tested before adding origin to
anything. I believe that this can become always an add of
@@ -6563,8 +6570,12 @@ struct bfd
}
tdata;
- /* Used by the application to hold private data. */
- void *usrdata;
+ union {
+ /* For input BFDs, used by the application to hold private data. */
+ void *usrdata;
+ /* For output BFD, used by mmap.c for file descriptor. */
+ int mmap_fd;
+ } u;
/* Where all the allocated stuff under this BFD goes. This is a
struct objalloc *, but we use void * to avoid requiring the inclusion
diff --git a/bfd/bfd.c b/bfd/bfd.c
index ba78cf34a93..a191bc1cb13 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -218,9 +218,13 @@ CODE_FRAGMENT
. {* Set if this is a plugin output file. *}
. unsigned int lto_output : 1;
.
-. {* Set to dummy BFD created when claimed by a compiler plug-in
-. library. *}
-. bfd *plugin_dummy_bfd;
+. union {
+. {* For input BFDs, set to dummy BFD created when claimed by a
+. compiler plug-in library. *}
+. bfd *plugin_dummy_bfd;
+. {* For output BFD, used by mmap.c for mapped size. *}
+. file_ptr mmap_size;
+. } io;
.
. {* Currently my_archive is tested before adding origin to
. anything. I believe that this can become always an add of
@@ -325,8 +329,12 @@ CODE_FRAGMENT
. }
. tdata;
.
-. {* Used by the application to hold private data. *}
-. void *usrdata;
+. union {
+. {* For input BFDs, used by the application to hold private data. *}
+. void *usrdata;
+. {* For output BFD, used by mmap.c for file descriptor. *}
+. int mmap_fd;
+. } u;
.
. {* Where all the allocated stuff under this BFD goes. This is a
. struct objalloc *, but we use void * to avoid requiring the inclusion
diff --git a/bfd/cache.c b/bfd/cache.c
index 94a82daff00..7a20b8f4f45 100644
--- a/bfd/cache.c
+++ b/bfd/cache.c
@@ -126,10 +126,19 @@ insert (bfd *abfd)
bfd_last_cache = abfd;
}
-/* Remove a BFD from the cache. */
+/*
+INTERNAL_FUNCTION
+ bfd_cache_snip
-static void
-snip (bfd *abfd)
+SYNOPSIS
+ void bfd_cache_snip (bfd *abfd);
+
+DESCRIPTION
+ Remove a BFD from the cache.
+*/
+
+void
+bfd_cache_snip (bfd *abfd)
{
abfd->lru_prev->lru_next = abfd->lru_next;
abfd->lru_next->lru_prev = abfd->lru_prev;
@@ -156,7 +165,7 @@ bfd_cache_delete (bfd *abfd)
bfd_set_error (bfd_error_system_call);
}
- snip (abfd);
+ bfd_cache_snip (abfd);
abfd->iostream = NULL;
--open_files;
@@ -231,7 +240,7 @@ bfd_cache_lookup_worker (bfd *abfd, enum cache_flag flag)
/* Move the file to the start of the cache. */
if (abfd != bfd_last_cache)
{
- snip (abfd);
+ bfd_cache_snip (abfd);
insert (abfd);
}
return (FILE *) abfd->iostream;
diff --git a/bfd/config.in b/bfd/config.in
index 1ee10817527..52706ff94dd 100644
--- a/bfd/config.in
+++ b/bfd/config.in
@@ -83,6 +83,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
@@ -152,9 +155,15 @@
/* 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 <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 be53faf8ef3..edfa3639ceb 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -13664,7 +13664,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"
@@ -15958,6 +15958,42 @@ $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
+
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 8ac36de4c2f..11032aaed79 100644
--- a/bfd/configure.ac
+++ b/bfd/configure.ac
@@ -215,7 +215,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)
@@ -1170,6 +1170,17 @@ 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
+
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/libbfd.h b/bfd/libbfd.h
index 14600aa1aa0..071254ba1e2 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -901,6 +901,8 @@ struct _bfd_window_internal {
unsigned mapped : 1; /* 1 = mmap, 0 = malloc */
};
/* Extracted from cache.c. */
+void bfd_cache_snip (bfd *abfd);
+
bfd_boolean bfd_cache_init (bfd *abfd);
bfd_boolean bfd_cache_close (bfd *abfd);
diff --git a/bfd/mmap.c b/bfd/mmap.c
new file mode 100644
index 00000000000..0ea9ae883ed
--- /dev/null
+++ b/bfd/mmap.c
@@ -0,0 +1,288 @@
+/* BFD library -- mmap of file descriptors.
+
+ Copyright (C) 2015 Free Software Foundation, Inc.
+
+ Hacked by Steve Chamberlain of Cygnus Support (steve@cygnus.com).
+
+ 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->u.mmap_fd, 0, size) != 0)
+ {
+syscall_error:
+ bfd_set_error (bfd_error_system_call);
+ abfd->io.mmap_size = 0;
+ return -1;
+ }
+ if (abfd->io.mmap_size != 0)
+ {
+#ifdef HAVE_MREMAP
+ abfd->iostream = mremap (abfd->iostream, abfd->io.mmap_size,
+ size, MREMAP_MAYMOVE);
+ if (abfd->iostream == MAP_FAILED)
+ goto syscall_error;
+ else
+ goto success;
+#else
+ if (munmap (abfd->iostream, abfd->io.mmap_size) != 0)
+ goto syscall_error;
+#endif
+ }
+ abfd->iostream = mmap (NULL, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED, abfd->u.mmap_fd, 0);
+ if (abfd->iostream == MAP_FAILED)
+ goto syscall_error;
+
+success:
+ abfd->io.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->io.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->io.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->io.mmap_size);
+ if (status == 0)
+ status = close (abfd->u.mmap_fd);
+ if (status != 0)
+ bfd_set_error (bfd_error_system_call);
+
+ abfd->iostream = MAP_FAILED;
+ abfd->io.mmap_size = 0;
+ abfd->u.mmap_fd = -1;
+
+ return status;
+}
+
+static int
+mmap_bflush (struct bfd *abfd)
+{
+ int status = msync (abfd->iostream, abfd->io.mmap_size, MS_SYNC);
+ if (status != 0)
+ bfd_set_error (bfd_error_system_call);
+ return status;
+}
+
+static int
+mmap_bstat (struct bfd *abfd ATTRIBUTE_UNUSED, struct stat *sb)
+{
+ int status;
+ status = fstat (abfd->u.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
+};
+
+static bfd_boolean
+mmap_init (bfd *abfd, file_ptr size)
+{
+ if (abfd->u.mmap_fd != -1
+ || abfd->io.mmap_size != 0
+ || abfd->iostream == NULL)
+ abort ();
+
+ /* Only suport write before writing starts. */
+ if (abfd->direction != write_direction || abfd->output_has_begun)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return FALSE;
+ }
+
+ abfd->u.mmap_fd = dup (fileno (abfd->iostream));
+ if (abfd->u.mmap_fd < 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
+ }
+
+ if (mmap_resize (abfd, size) != 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ close (abfd->u.mmap_fd);
+ abfd->u.mmap_fd = -1;
+ return FALSE;
+ }
+
+ abfd->iovec = &mmap_iovec;
+ bfd_cache_snip (abfd);
+ return TRUE;
+}
+#endif
+
+/*
+INTERNAL_FUNCTION
+ bfd_mmap_resize
+
+SYNOPSIS
+ bfd_boolean bfd_mmap_resize (bfd *abfd, file_ptr size);
+
+DESCRIPTION
+ Resize a BFD opened to write with mmap.
+*/
+
+bfd_boolean
+bfd_mmap_resize (bfd *abfd ATTRIBUTE_UNUSED,
+ file_ptr size ATTRIBUTE_UNUSED)
+{
+#ifdef HAVE_MMAP
+ if (abfd->u.mmap_fd == -1
+ || abfd->io.mmap_size == 0
+ || abfd->iostream == MAP_FAILED)
+ return mmap_init (abfd, size);
+
+ if (size > abfd->io.mmap_size && mmap_resize (abfd, size) != 0)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return FALSE;
+ }
+#endif
+
+ return TRUE;
+}
+
+/*
+INTERNAL_FUNCTION
+ bfd_mmape_close
+
+SYNOPSIS
+ bfd_boolean bfd_mmap_close (bfd *abfd);
+
+DESCRIPTION
+ Ummap the BFD @var{abfd} and close the attached file.
+
+RETURNS
+ <<FALSE>> is returned if closing the file fails, <<TRUE>> is
+ returned if all is well.
+*/
+
+bfd_boolean
+bfd_mmap_close (bfd *abfd ATTRIBUTE_UNUSED)
+{
+#ifdef HAVE_MMAP
+ if (abfd->iovec != &mmap_iovec)
+ return TRUE;
+
+ if (abfd->iostream == MAP_FAILED)
+ /* Previously closed. */
+ return TRUE;
+
+ return mmap_bclose (abfd) == 0 ? TRUE : FALSE;
+#else
+ return TRUE;
+#endif
+}
diff --git a/bfd/opncls.c b/bfd/opncls.c
index f0f2e64b319..ed1e0db6367 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -145,7 +145,10 @@ _bfd_free_cached_info (bfd *abfd)
abfd->section_last = NULL;
abfd->outsymbols = NULL;
abfd->tdata.any = NULL;
- abfd->usrdata = NULL;
+ if (abfd->direction == write_direction)
+ bfd_usrdata (abfd) = (void *) -1;
+ else
+ bfd_usrdata (abfd) = NULL;
abfd->memory = NULL;
}
@@ -240,7 +243,10 @@ bfd_fopen (const char *filename, const char *target, const char *mode, int fd)
else if (mode[0] == 'r')
nbfd->direction = read_direction;
else
- nbfd->direction = write_direction;
+ {
+ nbfd->direction = write_direction;
+ bfd_usrdata (nbfd) = (void *) -1;
+ }
if (! bfd_cache_init (nbfd))
{
@@ -660,6 +666,7 @@ bfd_openw (const char *filename, const char *target)
rather make a copy - the original might go away. */
nbfd->filename = xstrdup (filename);
nbfd->direction = write_direction;
+ bfd_usrdata (nbfd) = (void *) -1;
if (bfd_open_file (nbfd) == NULL)
{
@@ -859,6 +866,7 @@ bfd_make_writable (bfd *abfd)
abfd->iovec = &_bfd_memory_iovec;
abfd->origin = 0;
abfd->direction = write_direction;
+ bfd_usrdata (abfd) = (void *) -1;
abfd->where = 0;
return TRUE;
@@ -905,7 +913,7 @@ bfd_make_readable (bfd *abfd)
abfd->opened_once = FALSE;
abfd->output_has_begun = FALSE;
abfd->section_count = 0;
- abfd->usrdata = NULL;
+ bfd_usrdata (abfd) = NULL;
abfd->cacheable = FALSE;
abfd->flags |= BFD_IN_MEMORY;
abfd->mtime_set = FALSE;
diff --git a/ld/ldlang.c b/ld/ldlang.c
index b0741691042..c3a5c0140e4 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -871,10 +871,10 @@ walk_wild_file (lang_wild_statement_type *s,
archive which is included, BFD will call ldlang_add_file,
which will set the usrdata field of the member to the
lang_input_statement. */
- if (member->usrdata != NULL)
+ if (bfd_usrdata (member) != NULL)
{
walk_wild_section (s,
- (lang_input_statement_type *) member->usrdata,
+ (lang_input_statement_type *) bfd_usrdata (member),
callback, data);
}
@@ -6208,7 +6208,7 @@ ldlang_add_file (lang_input_statement_type *entry)
*link_info.input_bfds_tail = entry->the_bfd;
link_info.input_bfds_tail = &entry->the_bfd->link.next;
- entry->the_bfd->usrdata = entry;
+ bfd_usrdata (entry->the_bfd) = entry;
bfd_set_gp_size (entry->the_bfd, g_switch_value);
/* Look through the sections and check for any which should not be
diff --git a/ld/plugin.c b/ld/plugin.c
index 81bf14348c3..07b237dcffa 100644
--- a/ld/plugin.c
+++ b/ld/plugin.c
@@ -1066,7 +1066,7 @@ plugin_object_p (bfd *ibfd)
if (ibfd->plugin_format != bfd_plugin_uknown)
{
if (ibfd->plugin_format == bfd_plugin_yes)
- return ibfd->plugin_dummy_bfd->xvec;
+ return ibfd->io.plugin_dummy_bfd->xvec;
else
return NULL;
}
@@ -1145,7 +1145,7 @@ plugin_object_p (bfd *ibfd)
if (claimed)
{
ibfd->plugin_format = bfd_plugin_yes;
- ibfd->plugin_dummy_bfd = abfd;
+ ibfd->io.plugin_dummy_bfd = abfd;
bfd_make_readable (abfd);
return abfd->xvec;
}
@@ -1179,7 +1179,7 @@ plugin_maybe_claim (lang_input_statement_type *entry)
{
if (plugin_object_p (entry->the_bfd))
{
- bfd *abfd = entry->the_bfd->plugin_dummy_bfd;
+ bfd *abfd = entry->the_bfd->io.plugin_dummy_bfd;
/* Discard the real file's BFD and substitute the dummy one. */