FreeBSD/contrib/binutils/bfd/elflink.c
/* Record an assignment to a symbol made by a linker script.  We need
   this in case some dynamic object refers to this symbol.  */
Record an assignment to a symbol made by a linker script.  We need
this in case some dynamic object refers to this symbol.
Record an assignment to a symbol made by a linker script . We need this in case some dynamic object refers to this symbol .
bfd_boolean
bfd_elf_record_link_assignment (bfd *output_bfd,
				struct bfd_link_info *info,
				const char *name,
				bfd_boolean provide,
				bfd_boolean hidden)
{
  struct elf_link_hash_entry *h;
  struct elf_link_hash_table *htab;
  if (!is_elf_hash_table (info->hash))
    return TRUE;
  htab = elf_hash_table (info);
  h = elf_link_hash_lookup (htab, name, !provide, TRUE, FALSE);
  if (h == NULL)
    return provide;
  if (h->root.type == bfd_link_hash_undefweak
      || h->root.type == bfd_link_hash_undefined)
    {
      h->root.type = bfd_link_hash_new;
      if (h->root.u.undef.next != NULL || htab->root.undefs_tail == &h->root)
	bfd_link_repair_undef_list (&htab->root);
    }
  else if (h->root.type == bfd_link_hash_new)
    {
      bfd_elf_link_mark_dynamic_symbol (info, h, NULL);
      h->non_elf = 0;
    }
  else if (h->root.type == bfd_link_hash_indirect)
    {
      const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
      struct elf_link_hash_entry *hv = h;
      do
	hv = (struct elf_link_hash_entry *) hv->root.u.i.link;
      while (hv->root.type == bfd_link_hash_indirect
	     || hv->root.type == bfd_link_hash_warning);
      h->root.type = bfd_link_hash_undefined;
      hv->root.type = bfd_link_hash_indirect;
      hv->root.u.i.link = (struct bfd_link_hash_entry *) h;
      (*bed->elf_backend_copy_indirect_symbol) (info, h, hv);
    }
  else if (h->root.type == bfd_link_hash_warning)
    {
      abort ();
    }
  if (provide
      && h->def_dynamic
      && !h->def_regular)
    h->root.type = bfd_link_hash_undefined;
  if (!provide
      && h->def_dynamic
      && !h->def_regular)
    h->verinfo.verdef = NULL;
  h->def_regular = 1;
  if (provide && hidden)
    {
      const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
      h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN;
      (*bed->elf_backend_hide_symbol) (info, h, TRUE);
    }
  if (!info->relocatable
      && h->dynindx != -1
      && (ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
	  || ELF_ST_VISIBILITY (h->other) == STV_INTERNAL))
    h->forced_local = 1;
  if ((h->def_dynamic
       || h->ref_dynamic
       || info->shared
       || (info->executable && elf_hash_table (info)->is_relocatable_executable))
      && h->dynindx == -1)
    {
      if (! bfd_elf_link_record_dynamic_symbol (info, h))
	return FALSE;
      if (h->u.weakdef != NULL
	  && h->u.weakdef->dynindx == -1)
	{
	  if (! bfd_elf_link_record_dynamic_symbol (info, h->u.weakdef))
	    return FALSE;
	}
    }
  return TRUE;
}
bfd_boolean bfd_elf_record_link_assignment ( bfd * output_bfd , struct bfd_link_info * info , const char * name , bfd_boolean provide , bfd_boolean hidden ) { struct elf_link_hash_entry * h ; struct elf_link_hash_table * htab ; if ( ! is_elf_hash_table ( info -> hash ) ) return TRUE ; htab = elf_hash_table ( info ) ; h = elf_link_hash_lookup ( htab , name , ! provide , TRUE , FALSE ) ; if ( h == NULL ) return provide ; if ( h -> root . type == bfd_link_hash_undefweak || h -> root . type == bfd_link_hash_undefined ) { h -> root . type = bfd_link_hash_new ; if ( h -> root . u . undef . next != NULL || htab -> root . undefs_tail == & h -> root ) bfd_link_repair_undef_list ( & htab -> root ) ; } else if ( h -> root . type == bfd_link_hash_new ) { bfd_elf_link_mark_dynamic_symbol ( info , h , NULL ) ; h -> non_elf = 0 ; } else if ( h -> root . type == bfd_link_hash_indirect ) { const struct elf_backend_data * bed = get_elf_backend_data ( output_bfd ) ; struct elf_link_hash_entry * hv = h ; do hv = ( struct elf_link_hash_entry * ) hv -> root . u . i . link ; while ( hv -> root . type == bfd_link_hash_indirect || hv -> root . type == bfd_link_hash_warning ) ; h -> root . type = bfd_link_hash_undefined ; hv -> root . type = bfd_link_hash_indirect ; hv -> root . u . i . link = ( struct bfd_link_hash_entry * ) h ; ( * bed -> elf_backend_copy_indirect_symbol ) ( info , h , hv ) ; } else if ( h -> root . type == bfd_link_hash_warning ) { abort ( ) ; } if ( provide && h -> def_dynamic && ! h -> def_regular ) h -> root . type = bfd_link_hash_undefined ; if ( ! provide && h -> def_dynamic && ! h -> def_regular ) h -> verinfo . verdef = NULL ; h -> def_regular = 1 ; if ( provide && hidden ) { const struct elf_backend_data * bed = get_elf_backend_data ( output_bfd ) ; h -> other = ( h -> other & ~ ELF_ST_VISIBILITY ( -1 ) ) | STV_HIDDEN ; ( * bed -> elf_backend_hide_symbol ) ( info , h , TRUE ) ; } if ( ! info -> relocatable && h -> dynindx != -1 && ( ELF_ST_VISIBILITY ( h -> other ) == STV_HIDDEN || ELF_ST_VISIBILITY ( h -> other ) == STV_INTERNAL ) ) h -> forced_local = 1 ; if ( ( h -> def_dynamic || h -> ref_dynamic || info -> shared || ( info -> executable && elf_hash_table ( info ) -> is_relocatable_executable ) ) && h -> dynindx == -1 ) { if ( ! bfd_elf_link_record_dynamic_symbol ( info , h ) ) return FALSE ; if ( h -> u . weakdef != NULL && h -> u . weakdef -> dynindx == -1 ) { if ( ! bfd_elf_link_record_dynamic_symbol ( info , h -> u . weakdef ) ) return FALSE ; } } return TRUE ; }
Record an assignment to a symbol made by a linker script.
Record an assignment to a symbol made by a linker script .
/* Since we're defining the symbol, don't let it seem to have not
     been defined.  record_dynamic_symbol and size_dynamic_sections
     may depend on this.  */ /* If this symbol is being provided by the linker script, and it is
     currently defined by a dynamic object, but not by a regular
     object, then mark it as undefined so that the generic linker will
     force the correct value.  */ /* If this symbol is not being provided by the linker script, and it is
     currently defined by a dynamic object, but not by a regular object,
     then clear out any version information because the symbol will not be
     associated with the dynamic object any more.  */ /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects
     and executables.  */ /* If this is a weak defined symbol, and we know a corresponding
	 real symbol from the same dynamic object, make sure the real
	 symbol is also made into a dynamic symbol.  */