示例#1
0
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;
    }
}
示例#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;
    }
}
示例#3
0
文件: plugin.c 项目: msmania/gdb
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;
    }
}