static int try_claim (bfd *abfd) { int claimed = 0; struct ld_plugin_input_file file; 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); return claimed; }
static const bfd_target * plugin_object_p (bfd *ibfd) { int claimed; plugin_input_file_t *input; struct ld_plugin_input_file file; bfd *abfd; /* Don't try the dummy object file. */ if ((ibfd->flags & BFD_PLUGIN) != 0) return NULL; if (ibfd->plugin_format != bfd_plugin_unknown) { if (ibfd->plugin_format == bfd_plugin_yes) return ibfd->plugin_dummy_bfd->xvec; else return NULL; } /* We create a dummy BFD, initially empty, to house whatever symbols the plugin may want to add. */ abfd = plugin_get_ir_dummy_bfd (ibfd->filename, ibfd); input = bfd_alloc (abfd, sizeof (*input)); if (input == NULL) einfo (_("%P%F: plugin failed to allocate memory for input: %s\n"), bfd_get_error ()); if (!bfd_plugin_open_input (ibfd, &file)) return NULL; if (file.name == ibfd->filename) { /* We must copy filename attached to ibfd if it is not an archive member since it may be freed by bfd_close below. */ file.name = plugin_strdup (abfd, file.name); } file.handle = input; /* The plugin API expects that the file descriptor won't be closed and reused as done by the bfd file cache. So dup one. */ file.fd = dup (file.fd); if (file.fd < 0) return NULL; input->abfd = abfd; input->view_buffer.addr = NULL; input->view_buffer.filesize = 0; input->view_buffer.offset = 0; input->fd = file.fd; input->use_mmap = FALSE; input->offset = file.offset; input->filesize = file.filesize; input->name = plugin_strdup (abfd, ibfd->filename); claimed = 0; if (plugin_call_claim_file (&file, &claimed)) einfo (_("%P%F: %s: plugin reported error claiming file\n"), plugin_error_plugin ()); if (input->fd != -1 && !bfd_plugin_target_p (ibfd->xvec)) { /* FIXME: fd belongs to us, not the plugin. GCC plugin, which doesn't need fd after plugin_call_claim_file, doesn't use BFD plugin target vector. Since GCC plugin doesn't call release_input_file, we close it here. LLVM plugin, which needs fd after plugin_call_claim_file and calls release_input_file after it is done, uses BFD plugin target vector. This scheme doesn't work when a plugin needs fd and doesn't use BFD plugin target vector neither. */ close (input->fd); input->fd = -1; } if (claimed) { ibfd->plugin_format = bfd_plugin_yes; ibfd->plugin_dummy_bfd = abfd; bfd_make_readable (abfd); return abfd->xvec; } else { #if HAVE_MMAP if (input->use_mmap) { /* If plugin didn't claim the file, unmap the buffer. */ char *addr = input->view_buffer.addr; off_t size = input->view_buffer.filesize; # if HAVE_GETPAGESIZE off_t bias = input->view_buffer.offset % plugin_pagesize; size += bias; addr -= bias; # endif munmap (addr, size); } #endif /* If plugin didn't claim the file, we don't need the dummy bfd. Can't avoid speculatively creating it, alas. */ ibfd->plugin_format = bfd_plugin_no; bfd_close_all_done (abfd); return NULL; } }