FreeBSD/contrib/binutils/bfd/elflink.c
/* This function assumes that the relocations are in sorted order,
   which is true for all known assemblers.  */
This function assumes that the relocations are in sorted order,
which is true for all known assemblers.
This function assumes that the relocations are in sorted order which is true for all known assemblers .
bfd_boolean
bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info)
{
  struct elf_reloc_cookie cookie;
  asection *stab, *eh;
  Elf_Internal_Shdr *symtab_hdr;
  const struct elf_backend_data *bed;
  bfd *abfd;
  unsigned int count;
  bfd_boolean ret = FALSE;
  if (info->traditional_format
      || !is_elf_hash_table (info->hash))
    return FALSE;
  for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
    {
      if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
	continue;
      bed = get_elf_backend_data (abfd);
      if ((abfd->flags & DYNAMIC) != 0)
	continue;
      eh = NULL;
      if (!info->relocatable)
	{
	  eh = bfd_get_section_by_name (abfd, ".eh_frame");
	  if (eh != NULL
	      && (eh->size == 0
		  || bfd_is_abs_section (eh->output_section)))
	    eh = NULL;
	}
      stab = bfd_get_section_by_name (abfd, ".stab");
      if (stab != NULL
	  && (stab->size == 0
	      || bfd_is_abs_section (stab->output_section)
	      || stab->sec_info_type != ELF_INFO_TYPE_STABS))
	stab = NULL;
      if (stab == NULL
	  && eh == NULL
	  && bed->elf_backend_discard_info == NULL)
	continue;
      symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
      cookie.abfd = abfd;
      cookie.sym_hashes = elf_sym_hashes (abfd);
      cookie.bad_symtab = elf_bad_symtab (abfd);
      if (cookie.bad_symtab)
	{
	  cookie.locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym;
	  cookie.extsymoff = 0;
	}
      else
	{
	  cookie.locsymcount = symtab_hdr->sh_info;
	  cookie.extsymoff = symtab_hdr->sh_info;
	}
      if (bed->s->arch_size == 32)
	cookie.r_sym_shift = 8;
      else
	cookie.r_sym_shift = 32;
      cookie.locsyms = (Elf_Internal_Sym *) symtab_hdr->contents;
      if (cookie.locsyms == NULL && cookie.locsymcount != 0)
	{
	  cookie.locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr,
						 cookie.locsymcount, 0,
						 NULL, NULL, NULL);
	  if (cookie.locsyms == NULL)
	    {
	      info->callbacks->einfo (_("%P%X: can not read symbols: %E\n"));
	      return FALSE;
	    }
	}
      if (stab != NULL)
	{
	  cookie.rels = NULL;
	  count = stab->reloc_count;
	  if (count != 0)
	    cookie.rels = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL,
						     info->keep_memory);
	  if (cookie.rels != NULL)
	    {
	      cookie.rel = cookie.rels;
	      cookie.relend = cookie.rels;
	      cookie.relend += count * bed->s->int_rels_per_ext_rel;
	      if (_bfd_discard_section_stabs (abfd, stab,
					      elf_section_data (stab)->sec_info,
					      bfd_elf_reloc_symbol_deleted_p,
					      &cookie))
		ret = TRUE;
	      if (elf_section_data (stab)->relocs != cookie.rels)
		free (cookie.rels);
	    }
	}
      if (eh != NULL)
	{
	  cookie.rels = NULL;
	  count = eh->reloc_count;
	  if (count != 0)
	    cookie.rels = _bfd_elf_link_read_relocs (abfd, eh, NULL, NULL,
						     info->keep_memory);
	  cookie.rel = cookie.rels;
	  cookie.relend = cookie.rels;
	  if (cookie.rels != NULL)
	    cookie.relend += count * bed->s->int_rels_per_ext_rel;
	  if (_bfd_elf_discard_section_eh_frame (abfd, info, eh,
						 bfd_elf_reloc_symbol_deleted_p,
						 &cookie))
	    ret = TRUE;
	  if (cookie.rels != NULL
	      && elf_section_data (eh)->relocs != cookie.rels)
	    free (cookie.rels);
	}
      if (bed->elf_backend_discard_info != NULL
	  && (*bed->elf_backend_discard_info) (abfd, &cookie, info))
	ret = TRUE;
      if (cookie.locsyms != NULL
	  && symtab_hdr->contents != (unsigned char *) cookie.locsyms)
	{
	  if (! info->keep_memory)
	    free (cookie.locsyms);
	  else
	    symtab_hdr->contents = (unsigned char *) cookie.locsyms;
	}
    }
  if (info->eh_frame_hdr
      && !info->relocatable
      && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info))
    ret = TRUE;
  return ret;
}
bfd_boolean bfd_elf_discard_info ( bfd * output_bfd , struct bfd_link_info * info ) { struct elf_reloc_cookie cookie ; asection * stab , * eh ; Elf_Internal_Shdr * symtab_hdr ; const struct elf_backend_data * bed ; bfd * abfd ; unsigned int count ; bfd_boolean ret = FALSE ; if ( info -> traditional_format || ! is_elf_hash_table ( info -> hash ) ) return FALSE ; for ( abfd = info -> input_bfds ; abfd != NULL ; abfd = abfd -> link_next ) { if ( bfd_get_flavour ( abfd ) != bfd_target_elf_flavour ) continue ; bed = get_elf_backend_data ( abfd ) ; if ( ( abfd -> flags & DYNAMIC ) != 0 ) continue ; eh = NULL ; if ( ! info -> relocatable ) { eh = bfd_get_section_by_name ( abfd , " " ) ; if ( eh != NULL && ( eh -> size == 0 || bfd_is_abs_section ( eh -> output_section ) ) ) eh = NULL ; } stab = bfd_get_section_by_name ( abfd , " " ) ; if ( stab != NULL && ( stab -> size == 0 || bfd_is_abs_section ( stab -> output_section ) || stab -> sec_info_type != ELF_INFO_TYPE_STABS ) ) stab = NULL ; if ( stab == NULL && eh == NULL && bed -> elf_backend_discard_info == NULL ) continue ; symtab_hdr = & elf_tdata ( abfd ) -> symtab_hdr ; cookie . abfd = abfd ; cookie . sym_hashes = elf_sym_hashes ( abfd ) ; cookie . bad_symtab = elf_bad_symtab ( abfd ) ; if ( cookie . bad_symtab ) { cookie . locsymcount = symtab_hdr -> sh_size / bed -> s -> sizeof_sym ; cookie . extsymoff = 0 ; } else { cookie . locsymcount = symtab_hdr -> sh_info ; cookie . extsymoff = symtab_hdr -> sh_info ; } if ( bed -> s -> arch_size == 32 ) cookie . r_sym_shift = 8 ; else cookie . r_sym_shift = 32 ; cookie . locsyms = ( Elf_Internal_Sym * ) symtab_hdr -> contents ; if ( cookie . locsyms == NULL && cookie . locsymcount != 0 ) { cookie . locsyms = bfd_elf_get_elf_syms ( abfd , symtab_hdr , cookie . locsymcount , 0 , NULL , NULL , NULL ) ; if ( cookie . locsyms == NULL ) { info -> callbacks -> einfo ( _ ( " \n " ) ) ; return FALSE ; } } if ( stab != NULL ) { cookie . rels = NULL ; count = stab -> reloc_count ; if ( count != 0 ) cookie . rels = _bfd_elf_link_read_relocs ( abfd , stab , NULL , NULL , info -> keep_memory ) ; if ( cookie . rels != NULL ) { cookie . rel = cookie . rels ; cookie . relend = cookie . rels ; cookie . relend += count * bed -> s -> int_rels_per_ext_rel ; if ( _bfd_discard_section_stabs ( abfd , stab , elf_section_data ( stab ) -> sec_info , bfd_elf_reloc_symbol_deleted_p , & cookie ) ) ret = TRUE ; if ( elf_section_data ( stab ) -> relocs != cookie . rels ) free ( cookie . rels ) ; } } if ( eh != NULL ) { cookie . rels = NULL ; count = eh -> reloc_count ; if ( count != 0 ) cookie . rels = _bfd_elf_link_read_relocs ( abfd , eh , NULL , NULL , info -> keep_memory ) ; cookie . rel = cookie . rels ; cookie . relend = cookie . rels ; if ( cookie . rels != NULL ) cookie . relend += count * bed -> s -> int_rels_per_ext_rel ; if ( _bfd_elf_discard_section_eh_frame ( abfd , info , eh , bfd_elf_reloc_symbol_deleted_p , & cookie ) ) ret = TRUE ; if ( cookie . rels != NULL && elf_section_data ( eh ) -> relocs != cookie . rels ) free ( cookie . rels ) ; } if ( bed -> elf_backend_discard_info != NULL && ( * bed -> elf_backend_discard_info ) ( abfd , & cookie , info ) ) ret = TRUE ; if ( cookie . locsyms != NULL && symtab_hdr -> contents != ( unsigned char * ) cookie . locsyms ) { if ( ! info -> keep_memory ) free ( cookie . locsyms ) ; else symtab_hdr -> contents = ( unsigned char * ) cookie . locsyms ; } } if ( info -> eh_frame_hdr && ! info -> relocatable && _bfd_elf_discard_section_eh_frame_hdr ( output_bfd , info ) ) ret = TRUE ; return ret ; }
This function assumes that the relocations are in sorted order,
which is true for all known assemblers.
This function assumes that the relocations are in sorted order which is true for all known assemblers .