+int
+bfd_plugin_open_input (bfd *ibfd, struct ld_plugin_input_file *file)
+{
+ bfd *iobfd;
+
+ iobfd = ibfd;
+ 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;
+
+ /* 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)
+ {
+ struct stat stat_buf;
+
+ if (fstat (file->fd, &stat_buf))
+ {
+ close(file->fd);
+ return 0;
+ }
+
+ file->offset = 0;
+ file->filesize = stat_buf.st_size;
+ }
+ else
+ {
+ file->offset = ibfd->origin;
+ file->filesize = arelt_size (ibfd);
+ }
+ return 1;
+}
+
+static int
+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;
+ if (claim_file)
+ claim_file (&file, &claimed);
+ close (file.fd);
+ return claimed;
+}
+
+struct plugin_list_entry
+{
+ void * handle;
+ ld_plugin_claim_file_handler claim_file;
+ struct plugin_list_entry * next;
+};
+
+static struct plugin_list_entry * plugin_list = NULL;
+