aboutsummaryrefslogtreecommitdiff
path: root/bfd/opncls.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2017-08-31 08:46:47 +0930
committerAlan Modra <amodra@gmail.com>2017-08-31 10:30:07 +0930
commite234de6be5cc96286e0efb90e8d9fce51239e901 (patch)
tree51026a979501f87cc616f77feb578ce31ad2124b /bfd/opncls.c
parente69f32654ac724c46c0f4f645c8a49189c7b43e4 (diff)
downloadfsf-binutils-gdb-e234de6be5cc96286e0efb90e8d9fce51239e901.zip
fsf-binutils-gdb-e234de6be5cc96286e0efb90e8d9fce51239e901.tar.gz
fsf-binutils-gdb-e234de6be5cc96286e0efb90e8d9fce51239e901.tar.bz2
bfd_close_all_done calling _close_and_cleanup
elf64_vms_close_and_cleanup calls bfd_get_size, which calls iovec->bstat. cache_bstat ends up adding the bfd to the cache lru list, negating the bfd_cache_close call in bfd_close_all_done. So there is a dangling pointer into the freed and then reused bfd. Thus, bfd_cache_close must be called after _close_and_cleanup, or better, via iovec->bclose. PR binutils/22032 * opncls.c (bfd_close_all_done): Don't call bfd_cache_close before _close_and_cleanup. Call iovec->bclose after. (bfd_close): Remove code common to, and call, bfd_close_all_done.
Diffstat (limited to 'bfd/opncls.c')
-rw-r--r--bfd/opncls.c18
1 files changed, 3 insertions, 15 deletions
diff --git a/bfd/opncls.c b/bfd/opncls.c
index b99ae72..fa54986 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -726,25 +726,13 @@ RETURNS
bfd_boolean
bfd_close (bfd *abfd)
{
- bfd_boolean ret;
-
if (bfd_write_p (abfd))
{
if (! BFD_SEND_FMT (abfd, _bfd_write_contents, (abfd)))
return FALSE;
}
- if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
- return FALSE;
-
- ret = abfd->iovec->bclose (abfd) == 0;
-
- if (ret)
- _maybe_make_executable (abfd);
-
- _bfd_delete_bfd (abfd);
-
- return ret;
+ return bfd_close_all_done (abfd);
}
/*
@@ -774,11 +762,11 @@ bfd_close_all_done (bfd *abfd)
{
bfd_boolean ret;
- ret = bfd_cache_close (abfd);
-
if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
return FALSE;
+ ret = abfd->iovec->bclose (abfd) == 0;
+
if (ret)
_maybe_make_executable (abfd);