Example #1
0
int
bfd_plugin_open_input (bfd *ibfd, struct ld_plugin_input_file *file)
{
  bfd *iobfd;

  iobfd = ibfd;
  if (ibfd->my_archive && !bfd_is_thin_archive (ibfd->my_archive))
    iobfd = ibfd->my_archive;
  file->name = iobfd->filename;

  if (!iobfd->iostream && !bfd_open_file (iobfd))
    return 0;

  file->fd = fileno ((FILE *) iobfd->iostream);

  if (iobfd == ibfd)
    {
      struct stat stat_buf;
      if (fstat (file->fd, &stat_buf))
        return 0;
      file->offset = 0;
      file->filesize = stat_buf.st_size;
    }
  else
    {
      file->offset = ibfd->origin;
      file->filesize = arelt_size (ibfd);
    }
  return 1;
}
Example #2
0
bfd_size_type
bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
{
  size_t nread;

  /* If this is an archive element, don't read past the end of
     this element.  */
  if (abfd->arelt_data != NULL)
    {
      bfd_size_type maxbytes = arelt_size (abfd);

      if (abfd->where + size > maxbytes)
        {
          if (abfd->where >= maxbytes)
            return 0;
          size = maxbytes - abfd->where;
        }
    }

  if (abfd->iovec)
    nread = abfd->iovec->bread (abfd, ptr, size);
  else
    nread = 0;
  if (nread != (size_t) -1)
    abfd->where += nread;

  return nread;
}
static const bfd_target *
bfd_plugin_object_p (bfd *abfd)
{
  int claimed = 0;
  int t = load_plugin ();
  struct ld_plugin_input_file file;
  if (!t)
    return NULL;

  file.name = abfd->filename;

  if (abfd->iostream)
    {
      file.fd = fileno ((FILE *) abfd->iostream);
      file.offset = 0;
      file.filesize = 0; /*FIXME*/
    }
  else
    {
      bfd *archive = abfd->my_archive;
      BFD_ASSERT (archive);
      file.fd = fileno ((FILE *) archive->iostream);
      file.offset = abfd->origin;
      file.filesize = arelt_size (abfd);

    }
  file.handle = abfd;
  claim_file (&file, &claimed);
  if (!claimed)
    return NULL;

  return abfd->xvec;
}
Example #4
0
ufile_ptr
bfd_get_file_size (bfd *abfd)
{
  if (abfd->my_archive != NULL
      && !bfd_is_thin_archive (abfd->my_archive))
    return arelt_size (abfd);

  return bfd_get_size (abfd);
}
Example #5
0
static const bfd_target *
bfd_plugin_object_p (bfd *abfd)
{
  int claimed = 0;
  struct ld_plugin_input_file file;
  bfd *iobfd;
  static int have_loaded = 0;
  static int have_plugin = 0;

  if (!have_loaded)
    {
      have_loaded = 1;
      have_plugin = load_plugin ();
    }
  if (!have_plugin)
    return NULL;

  file.name = abfd->filename;

  if (abfd->my_archive)
    {
      iobfd = abfd->my_archive;
      file.offset = abfd->origin;
      file.filesize = arelt_size (abfd);
    }
  else
    {
      iobfd = abfd;
      file.offset = 0;
      file.filesize = 0;
    }

  if (!iobfd->iostream && !bfd_open_file (iobfd))
    return NULL;

  file.fd = fileno ((FILE *) iobfd->iostream);

  if (!abfd->my_archive)
    {
      struct stat stat_buf;
      if (fstat (file.fd, &stat_buf))
        return NULL;
      file.filesize = stat_buf.st_size;
    }

  file.handle = abfd;
  off_t cur_offset = lseek(file.fd, 0, SEEK_CUR);
  claim_file (&file, &claimed);
  lseek(file.fd, cur_offset, SEEK_SET);
  if (!claimed)
    return NULL;

  return abfd->xvec;
}
Example #6
0
static int
try_claim (bfd *abfd)
{
  int claimed = 0;
  struct ld_plugin_input_file file;
  bfd *iobfd;

  file.name = abfd->filename;

  if (abfd->my_archive)
    {
      iobfd = abfd->my_archive;
      file.offset = abfd->origin;
      file.filesize = arelt_size (abfd);
    }
  else
    {
      iobfd = abfd;
      file.offset = 0;
      file.filesize = 0;
    }

  if (!iobfd->iostream && !bfd_open_file (iobfd))
    return 0;

  file.fd = fileno ((FILE *) iobfd->iostream);

  if (!abfd->my_archive)
    {
      struct stat stat_buf;
      if (fstat (file.fd, &stat_buf))
        return 0;
      file.filesize = stat_buf.st_size;
    }

  file.handle = abfd;
  off_t cur_offset = lseek(file.fd, 0, SEEK_CUR);
  claim_file (&file, &claimed);
  lseek(file.fd, cur_offset, SEEK_SET);
  if (!claimed)
    return 0;

  return 1;
}
Example #7
0
bfd_size_type
bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
{
  file_ptr nread;
  bfd *element_bfd = abfd;
  ufile_ptr offset = 0;

  while (abfd->my_archive != NULL
	 && !bfd_is_thin_archive (abfd->my_archive))
    {
      offset += abfd->origin;
      abfd = abfd->my_archive;
    }

  /* If this is an archive element, don't read past the end of
     this element.  */
  if (element_bfd->arelt_data != NULL)
    {
      bfd_size_type maxbytes = arelt_size (element_bfd);

      if (abfd->where < offset || abfd->where - offset >= maxbytes)
	{
	  bfd_set_error (bfd_error_invalid_operation);
	  return -1;
	}
      if (abfd->where - offset + size > maxbytes)
	size = maxbytes - (abfd->where - offset);
    }

  if (abfd->iovec == NULL)
    {
      bfd_set_error (bfd_error_invalid_operation);
      return -1;
    }

  nread = abfd->iovec->bread (abfd, ptr, size);
  if (nread != -1)
    abfd->where += nread;

  return nread;
}
Example #8
0
bfd_boolean
bfd_elf64_archive_write_armap (bfd *arch,
			       unsigned int elength,
			       struct orl *map,
			       unsigned int symbol_count,
			       int stridx)
{
  unsigned int ranlibsize = (symbol_count * 8) + 8;
  unsigned int stringsize = stridx;
  unsigned int mapsize = stringsize + ranlibsize;
  file_ptr archive_member_file_ptr;
  bfd *current = arch->archive_head;
  unsigned int count;
  struct ar_hdr hdr;
  int padding;
  bfd_byte buf[8];

  padding = BFD_ALIGN (mapsize, 8) - mapsize;
  mapsize += padding;

  /* work out where the first object file will go in the archive */
  archive_member_file_ptr = (mapsize
			     + elength
			     + sizeof (struct ar_hdr)
			     + SARMAG);

  memset (&hdr, ' ', sizeof (struct ar_hdr));
  memcpy (hdr.ar_name, "/SYM64/", strlen ("/SYM64/"));
  if (!_bfd_ar_sizepad (hdr.ar_size, sizeof (hdr.ar_size), mapsize))
    return FALSE;
  _bfd_ar_spacepad (hdr.ar_date, sizeof (hdr.ar_date), "%ld",
                    time (NULL));
  /* This, at least, is what Intel coff sets the values to.: */
  _bfd_ar_spacepad (hdr.ar_uid, sizeof (hdr.ar_uid), "%ld", 0);
  _bfd_ar_spacepad (hdr.ar_gid, sizeof (hdr.ar_gid), "%ld", 0);
  _bfd_ar_spacepad (hdr.ar_mode, sizeof (hdr.ar_mode), "%-7lo", 0);
  memcpy (hdr.ar_fmag, ARFMAG, 2);

  /* Write the ar header for this item and the number of symbols */

  if (bfd_bwrite (&hdr, sizeof (struct ar_hdr), arch)
      != sizeof (struct ar_hdr))
    return FALSE;

  bfd_putb64 ((bfd_vma) symbol_count, buf);
  if (bfd_bwrite (buf, 8, arch) != 8)
    return FALSE;

  /* Two passes, first write the file offsets for each symbol -
     remembering that each offset is on a two byte boundary.  */

  /* Write out the file offset for the file associated with each
     symbol, and remember to keep the offsets padded out.  */
  count = 0;
  for (current = arch->archive_head;
       current != NULL && count < symbol_count;
       current = current->archive_next)
    {
      /* For each symbol which is used defined in this object, write out
	 the object file's address in the archive.  */

      for (;
	   count < symbol_count && map[count].u.abfd == current;
	   count++)
	{
	  bfd_putb64 ((bfd_vma) archive_member_file_ptr, buf);
	  if (bfd_bwrite (buf, 8, arch) != 8)
	    return FALSE;
	}

      /* Add size of this archive entry */
      archive_member_file_ptr += sizeof (struct ar_hdr);
      if (! bfd_is_thin_archive (arch))
	archive_member_file_ptr += arelt_size (current);
      /* remember about the even alignment */
      archive_member_file_ptr += archive_member_file_ptr % 2;
    }

  /* now write the strings themselves */
  for (count = 0; count < symbol_count; count++)
    {
      size_t len = strlen (*map[count].name) + 1;

      if (bfd_bwrite (*map[count].name, len, arch) != len)
	return FALSE;
    }

  /* The spec says that this should be padded to an 8 byte boundary.
     However, the Irix 6.2 tools do not appear to do this.  */
  while (padding != 0)
    {
      if (bfd_bwrite ("", 1, arch) != 1)
	return FALSE;
      --padding;
    }

  return TRUE;
}
Example #9
0
File: plugin.c Project: 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;
    }
}