Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
    }
}