FreeBSD/contrib/binutils/bfd/elf.c
/* Get the list of DT_NEEDED entries from a BFD.  This is a hook for
   the ELF linker emulation code.  */
Get the list of DT_NEEDED entries from a BFD.  This is a hook for
the ELF linker emulation code.
Get the list of DT_NEEDED entries from a BFD . This is a hook for the ELF linker emulation code .
bfd_boolean
bfd_elf_get_bfd_needed_list (bfd *abfd,
			     struct bfd_link_needed_list **pneeded)
{
  asection *s;
  bfd_byte *dynbuf = NULL;
  int elfsec;
  unsigned long shlink;
  bfd_byte *extdyn, *extdynend;
  size_t extdynsize;
  void (*swap_dyn_in) (bfd *, const void *, Elf_Internal_Dyn *);
  *pneeded = NULL;
  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour
      || bfd_get_format (abfd) != bfd_object)
    return TRUE;
  s = bfd_get_section_by_name (abfd, ".dynamic");
  if (s == NULL || s->size == 0)
    return TRUE;
  if (!bfd_malloc_and_get_section (abfd, s, &dynbuf))
    goto error_return;
  elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
  if (elfsec == -1)
    goto error_return;
  shlink = elf_elfsections (abfd)[elfsec]->sh_link;
  extdynsize = get_elf_backend_data (abfd)->s->sizeof_dyn;
  swap_dyn_in = get_elf_backend_data (abfd)->s->swap_dyn_in;
  extdyn = dynbuf;
  extdynend = extdyn + s->size;
  for (; extdyn < extdynend; extdyn += extdynsize)
    {
      Elf_Internal_Dyn dyn;
      (*swap_dyn_in) (abfd, extdyn, &dyn);
      if (dyn.d_tag == DT_NULL)
	break;
      if (dyn.d_tag == DT_NEEDED)
	{
	  const char *string;
	  struct bfd_link_needed_list *l;
	  unsigned int tagv = dyn.d_un.d_val;
	  bfd_size_type amt;
	  string = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
	  if (string == NULL)
	    goto error_return;
	  amt = sizeof *l;
	  l = bfd_alloc (abfd, amt);
	  if (l == NULL)
	    goto error_return;
	  l->by = abfd;
	  l->name = string;
	  l->next = *pneeded;
	  *pneeded = l;
	}
    }
  free (dynbuf);
  return TRUE;
 error_return:
  if (dynbuf != NULL)
    free (dynbuf);
  return FALSE;
}
bfd_boolean bfd_elf_get_bfd_needed_list ( bfd * abfd , struct bfd_link_needed_list * * pneeded ) { asection * s ; bfd_byte * dynbuf = NULL ; int elfsec ; unsigned long shlink ; bfd_byte * extdyn , * extdynend ; size_t extdynsize ; void ( * swap_dyn_in ) ( bfd * , const void * , Elf_Internal_Dyn * ) ; * pneeded = NULL ; if ( bfd_get_flavour ( abfd ) != bfd_target_elf_flavour || bfd_get_format ( abfd ) != bfd_object ) return TRUE ; s = bfd_get_section_by_name ( abfd , " " ) ; if ( s == NULL || s -> size == 0 ) return TRUE ; if ( ! bfd_malloc_and_get_section ( abfd , s , & dynbuf ) ) goto error_return ; elfsec = _bfd_elf_section_from_bfd_section ( abfd , s ) ; if ( elfsec == -1 ) goto error_return ; shlink = elf_elfsections ( abfd ) [ elfsec ] -> sh_link ; extdynsize = get_elf_backend_data ( abfd ) -> s -> sizeof_dyn ; swap_dyn_in = get_elf_backend_data ( abfd ) -> s -> swap_dyn_in ; extdyn = dynbuf ; extdynend = extdyn + s -> size ; for ( ; extdyn < extdynend ; extdyn += extdynsize ) { Elf_Internal_Dyn dyn ; ( * swap_dyn_in ) ( abfd , extdyn , & dyn ) ; if ( dyn . d_tag == DT_NULL ) break ; if ( dyn . d_tag == DT_NEEDED ) { const char * string ; struct bfd_link_needed_list * l ; unsigned int tagv = dyn . d_un . d_val ; bfd_size_type amt ; string = bfd_elf_string_from_elf_section ( abfd , shlink , tagv ) ; if ( string == NULL ) goto error_return ; amt = sizeof * l ; l = bfd_alloc ( abfd , amt ) ; if ( l == NULL ) goto error_return ; l -> by = abfd ; l -> name = string ; l -> next = * pneeded ; * pneeded = l ; } } free ( dynbuf ) ; return TRUE ; error_return : if ( dynbuf != NULL ) free ( dynbuf ) ; return FALSE ; }
Get the list of DT_NEEDED entries from a BFD.
Get the list of DT_NEEDED entries from a BFD .