aboutsummaryrefslogtreecommitdiff
path: root/bfd/plugin.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2018-06-05 21:04:00 +0930
committerAlan Modra <amodra@gmail.com>2018-06-05 22:39:11 +0930
commit27b0767593284f97384b3597ebd211164f8c8b47 (patch)
tree1f82c304a2abc2acca2d865190b382e0963cd84a /bfd/plugin.c
parent8347745522002d5c0093bac584a2eaf9386ad219 (diff)
downloadbinutils-27b0767593284f97384b3597ebd211164f8c8b47.zip
binutils-27b0767593284f97384b3597ebd211164f8c8b47.tar.gz
binutils-27b0767593284f97384b3597ebd211164f8c8b47.tar.bz2
PR23254, ld.bfd mishandles file pointers while scanning archive
Best practice is to not mix lseek/read with fseek/fread on the same underlying file descriptor, as not all stdio implementations will cope. Since the plugin uses lseek/read while bfd uses fseek/fread this patch reopens the file for exclusive use by the plugin rather than trying to restore the file descriptor. That allows the plugin to read the file after plugin_call_claim_file too. bfd/ PR 23254 * plugin.c (bfd_plugin_open_input): Allow for possibility of nested archives. Open file again for plugin. (try_claim): Don't save and restore file position. Close file if not claimed. * sysdep.h (O_BINARY): Define. ld/ PR 23254 * plugin.c (plugin_call_claim_file): Revert 2016-07-19 patch. (plugin_object_p): Don't dup file descriptor.
Diffstat (limited to 'bfd/plugin.c')
-rw-r--r--bfd/plugin.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/bfd/plugin.c b/bfd/plugin.c
index 16a706a..7c5bba2 100644
--- a/bfd/plugin.c
+++ b/bfd/plugin.c
@@ -166,14 +166,22 @@ bfd_plugin_open_input (bfd *ibfd, struct ld_plugin_input_file *file)
bfd *iobfd;
iobfd = ibfd;
- if (ibfd->my_archive && !bfd_is_thin_archive (ibfd->my_archive))
- iobfd = ibfd->my_archive;
+ while (iobfd->my_archive
+ && !bfd_is_thin_archive (iobfd->my_archive))
+ iobfd = iobfd->my_archive;
file->name = iobfd->filename;
if (!iobfd->iostream && !bfd_open_file (iobfd))
return 0;
- file->fd = fileno ((FILE *) iobfd->iostream);
+ /* The plugin API expects that the file descriptor won't be closed
+ and reused as done by the bfd file cache. So open it again.
+ dup isn't good enough. plugin IO uses lseek/read while BFD uses
+ fseek/fread. It isn't wise to mix the unistd and stdio calls on
+ the same underlying file descriptor. */
+ file->fd = open (file->name, O_RDONLY | O_BINARY);
+ if (file->fd < 0)
+ return 0;
if (iobfd == ibfd)
{
@@ -197,12 +205,12 @@ try_claim (bfd *abfd)
int claimed = 0;
struct ld_plugin_input_file file;
+ file.handle = abfd;
if (!bfd_plugin_open_input (abfd, &file))
return 0;
- file.handle = abfd;
- off_t cur_offset = lseek (file.fd, 0, SEEK_CUR);
claim_file (&file, &claimed);
- lseek (file.fd, cur_offset, SEEK_SET);
+ if (!claimed)
+ close (file.fd);
return claimed;
}