void plugin_maybe_claim (struct ld_plugin_input_file *file, lang_input_statement_type *entry) { int claimed = 0; /* We create a dummy BFD, initially empty, to house whatever symbols the plugin may want to add. */ file->handle = plugin_get_ir_dummy_bfd (entry->the_bfd->filename, entry->the_bfd); if (plugin_call_claim_file (file, &claimed)) einfo (_("%P%F: %s: plugin reported error claiming file\n"), plugin_error_plugin ()); /* fd belongs to us, not the plugin; but we don't need it. */ close (file->fd); if (claimed) { /* Discard the real file's BFD and substitute the dummy one. */ /* BFD archive handling caches elements so we can't call bfd_close for archives. */ if (entry->the_bfd->my_archive == NULL) bfd_close (entry->the_bfd); entry->the_bfd = file->handle; entry->flags.claimed = TRUE; bfd_make_readable (entry->the_bfd); } else { /* If plugin didn't claim the file, we don't need the dummy bfd. Can't avoid speculatively creating it, alas. */ bfd_close_all_done (file->handle); entry->flags.claimed = FALSE; } }
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; } }
static const bfd_target * plugin_object_p (bfd *ibfd) { int claimed; plugin_input_file_t *input; off_t offset, filesize; struct ld_plugin_input_file file; bfd *abfd; bfd_boolean inarchive; const char *name; int fd; /* Don't try the dummy object file. */ if ((ibfd->flags & BFD_PLUGIN) != 0) return NULL; if (ibfd->plugin_format != bfd_plugin_uknown) { if (ibfd->plugin_format == bfd_plugin_yes) return ibfd->plugin_dummy_bfd->xvec; else return NULL; } inarchive = bfd_my_archive (ibfd) != NULL; name = inarchive ? bfd_my_archive (ibfd)->filename : ibfd->filename; fd = open (name, O_RDONLY | O_BINARY); if (fd < 0) 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 (inarchive) { /* Offset and filesize must refer to the individual archive member, not the whole file, and must exclude the header. Fortunately for us, that is how the data is stored in the origin field of the bfd and in the arelt_data. */ offset = ibfd->origin; filesize = arelt_size (ibfd); } else { offset = 0; filesize = lseek (fd, 0, SEEK_END); /* We must copy filename attached to ibfd if it is not an archive member since it may be freed by bfd_close below. */ name = plugin_strdup (abfd, name); } file.name = name; file.offset = offset; file.filesize = filesize; file.fd = fd; file.handle = input; input->abfd = abfd; input->view_buffer.addr = NULL; input->view_buffer.filesize = 0; input->view_buffer.offset = 0; input->fd = fd; input->use_mmap = FALSE; input->offset = offset; input->filesize = 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 (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; } }