FreeBSD/contrib/binutils/bfd/elflink.c
/* Fix up the flags for a symbol.  This handles various cases which
   can only be fixed after all the input files are seen.  This is
   currently called by both adjust_dynamic_symbol and
   assign_sym_version, which is unnecessary but perhaps more robust in
   the face of future changes.  */
Fix up the flags for a symbol.  This handles various cases which
can only be fixed after all the input files are seen.  This is
currently called by both adjust_dynamic_symbol and
assign_sym_version, which is unnecessary but perhaps more robust in
the face of future changes.
Fix up the flags for a symbol . This handles various cases which can only be fixed after all the input files are seen . This is currently called by both adjust_dynamic_symbol and assign_sym_version which is unnecessary but perhaps more robust in the face of future changes .
bfd_boolean
_bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h,
			   struct elf_info_failed *eif)
{
  const struct elf_backend_data *bed = NULL;
  if (h->non_elf)
    {
      while (h->root.type == bfd_link_hash_indirect)
	h = (struct elf_link_hash_entry *) h->root.u.i.link;
      if (h->root.type != bfd_link_hash_defined
	  && h->root.type != bfd_link_hash_defweak)
	{
	  h->ref_regular = 1;
	  h->ref_regular_nonweak = 1;
	}
      else
	{
	  if (h->root.u.def.section->owner != NULL
	      && (bfd_get_flavour (h->root.u.def.section->owner)
		  == bfd_target_elf_flavour))
	    {
	      h->ref_regular = 1;
	      h->ref_regular_nonweak = 1;
	    }
	  else
	    h->def_regular = 1;
	}
      if (h->dynindx == -1
	  && (h->def_dynamic
	      || h->ref_dynamic))
	{
	  if (! bfd_elf_link_record_dynamic_symbol (eif->info, h))
	    {
	      eif->failed = TRUE;
	      return FALSE;
	    }
	}
    }
  else
    {
      if ((h->root.type == bfd_link_hash_defined
	   || h->root.type == bfd_link_hash_defweak)
	  && !h->def_regular
	  && (h->root.u.def.section->owner != NULL
	      ? (bfd_get_flavour (h->root.u.def.section->owner)
		 != bfd_target_elf_flavour)
	      : (bfd_is_abs_section (h->root.u.def.section)
		 && !h->def_dynamic)))
	h->def_regular = 1;
    }
  if (elf_hash_table (eif->info)->dynobj)
    {
      bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
      if (bed->elf_backend_fixup_symbol
	  && !(*bed->elf_backend_fixup_symbol) (eif->info, h))
	return FALSE;
    }
  if (h->root.type == bfd_link_hash_defined
      && !h->def_regular
      && h->ref_regular
      && !h->def_dynamic
      && (h->root.u.def.section->owner->flags & DYNAMIC) == 0)
    h->def_regular = 1;
  if (h->needs_plt
      && eif->info->shared
      && is_elf_hash_table (eif->info->hash)
      && (SYMBOLIC_BIND (eif->info, h)
	  || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
      && h->def_regular)
    {
      bfd_boolean force_local;
      force_local = (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
		     || ELF_ST_VISIBILITY (h->other) == STV_HIDDEN);
      (*bed->elf_backend_hide_symbol) (eif->info, h, force_local);
    }
  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
      && h->root.type == bfd_link_hash_undefweak)
    {
      const struct elf_backend_data *bed;
      bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
      (*bed->elf_backend_hide_symbol) (eif->info, h, TRUE);
    }
  if (h->u.weakdef != NULL)
    {
      struct elf_link_hash_entry *weakdef;
      weakdef = h->u.weakdef;
      if (h->root.type == bfd_link_hash_indirect)
	h = (struct elf_link_hash_entry *) h->root.u.i.link;
      BFD_ASSERT (h->root.type == bfd_link_hash_defined
		  || h->root.type == bfd_link_hash_defweak);
      BFD_ASSERT (weakdef->root.type == bfd_link_hash_defined
		  || weakdef->root.type == bfd_link_hash_defweak);
      BFD_ASSERT (weakdef->def_dynamic);
      if (weakdef->def_regular)
	h->u.weakdef = NULL;
      else
	(*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef,
						  h);
    }
  return TRUE;
}
bfd_boolean _bfd_elf_fix_symbol_flags ( struct elf_link_hash_entry * h , struct elf_info_failed * eif ) { const struct elf_backend_data * bed = NULL ; if ( h -> non_elf ) { while ( h -> root . type == bfd_link_hash_indirect ) h = ( struct elf_link_hash_entry * ) h -> root . u . i . link ; if ( h -> root . type != bfd_link_hash_defined && h -> root . type != bfd_link_hash_defweak ) { h -> ref_regular = 1 ; h -> ref_regular_nonweak = 1 ; } else { if ( h -> root . u . def . section -> owner != NULL && ( bfd_get_flavour ( h -> root . u . def . section -> owner ) == bfd_target_elf_flavour ) ) { h -> ref_regular = 1 ; h -> ref_regular_nonweak = 1 ; } else h -> def_regular = 1 ; } if ( h -> dynindx == -1 && ( h -> def_dynamic || h -> ref_dynamic ) ) { if ( ! bfd_elf_link_record_dynamic_symbol ( eif -> info , h ) ) { eif -> failed = TRUE ; return FALSE ; } } } else { if ( ( h -> root . type == bfd_link_hash_defined || h -> root . type == bfd_link_hash_defweak ) && ! h -> def_regular && ( h -> root . u . def . section -> owner != NULL ? ( bfd_get_flavour ( h -> root . u . def . section -> owner ) != bfd_target_elf_flavour ) : ( bfd_is_abs_section ( h -> root . u . def . section ) && ! h -> def_dynamic ) ) ) h -> def_regular = 1 ; } if ( elf_hash_table ( eif -> info ) -> dynobj ) { bed = get_elf_backend_data ( elf_hash_table ( eif -> info ) -> dynobj ) ; if ( bed -> elf_backend_fixup_symbol && ! ( * bed -> elf_backend_fixup_symbol ) ( eif -> info , h ) ) return FALSE ; } if ( h -> root . type == bfd_link_hash_defined && ! h -> def_regular && h -> ref_regular && ! h -> def_dynamic && ( h -> root . u . def . section -> owner -> flags & DYNAMIC ) == 0 ) h -> def_regular = 1 ; if ( h -> needs_plt && eif -> info -> shared && is_elf_hash_table ( eif -> info -> hash ) && ( SYMBOLIC_BIND ( eif -> info , h ) || ELF_ST_VISIBILITY ( h -> other ) != STV_DEFAULT ) && h -> def_regular ) { bfd_boolean force_local ; force_local = ( ELF_ST_VISIBILITY ( h -> other ) == STV_INTERNAL || ELF_ST_VISIBILITY ( h -> other ) == STV_HIDDEN ) ; ( * bed -> elf_backend_hide_symbol ) ( eif -> info , h , force_local ) ; } if ( ELF_ST_VISIBILITY ( h -> other ) != STV_DEFAULT && h -> root . type == bfd_link_hash_undefweak ) { const struct elf_backend_data * bed ; bed = get_elf_backend_data ( elf_hash_table ( eif -> info ) -> dynobj ) ; ( * bed -> elf_backend_hide_symbol ) ( eif -> info , h , TRUE ) ; } if ( h -> u . weakdef != NULL ) { struct elf_link_hash_entry * weakdef ; weakdef = h -> u . weakdef ; if ( h -> root . type == bfd_link_hash_indirect ) h = ( struct elf_link_hash_entry * ) h -> root . u . i . link ; BFD_ASSERT ( h -> root . type == bfd_link_hash_defined || h -> root . type == bfd_link_hash_defweak ) ; BFD_ASSERT ( weakdef -> root . type == bfd_link_hash_defined || weakdef -> root . type == bfd_link_hash_defweak ) ; BFD_ASSERT ( weakdef -> def_dynamic ) ; if ( weakdef -> def_regular ) h -> u . weakdef = NULL ; else ( * bed -> elf_backend_copy_indirect_symbol ) ( eif -> info , weakdef , h ) ; } return TRUE ; }
Fix up the flags for a symbol.
Fix up the flags for a symbol .
/* If this symbol was mentioned in a non-ELF file, try to set
     DEF_REGULAR and REF_REGULAR correctly.  This is the only way to
     permit a non-ELF file to correctly refer to a symbol defined in
     an ELF dynamic object.  */ /* Unfortunately, NON_ELF is only correct if the symbol
	 was first seen in a non-ELF file.  Fortunately, if the symbol
	 was first seen in an ELF file, we're probably OK unless the
	 symbol was defined in a non-ELF file.  Catch that case here.
	 FIXME: We're still in trouble if the symbol was first seen in
	 a dynamic object, and then later in a non-ELF regular object.  */ /* Backend specific symbol fixup.  */ /* If this is a final link, and the symbol was defined as a common
     symbol in a regular object file, and there was no definition in
     any dynamic object, then the linker will have allocated space for
     the symbol in a common section but the DEF_REGULAR
     flag will not have been set.  */ /* If -Bsymbolic was used (which means to bind references to global
     symbols to the definition within the shared object), and this
     symbol was defined in a regular object, then it actually doesn't
     need a PLT entry.  Likewise, if the symbol has non-default
     visibility.  If the symbol has hidden or internal visibility, we
     will force it local.  */ /* If a weak undefined symbol has non-default visibility, we also
     hide it from the dynamic linker.  */ /* If this is a weak defined symbol in a dynamic object, and we know
     the real definition in the dynamic object, copy interesting flags
     over to the real definition.  */ /* If the real definition is defined by a regular object file,
	 don't do anything special.  See the longer description in
	 _bfd_elf_adjust_dynamic_symbol, below.  */