FreeBSD/contrib/binutils/bfd/elflink.c
/* Make the backend pick a good value for a dynamic symbol.  This is
   called via elf_link_hash_traverse, and also calls itself
   recursively.  */
Make the backend pick a good value for a dynamic symbol.  This is
called via elf_link_hash_traverse, and also calls itself
recursively.
Make the backend pick a good value for a dynamic symbol . This is called via elf_link_hash_traverse and also calls itself recursively .
bfd_boolean
_bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data)
{
  struct elf_info_failed *eif = data;
  bfd *dynobj;
  const struct elf_backend_data *bed;
  if (! is_elf_hash_table (eif->info->hash))
    return FALSE;
  if (h->root.type == bfd_link_hash_warning)
    {
      h->got = elf_hash_table (eif->info)->init_got_offset;
      h->plt = elf_hash_table (eif->info)->init_plt_offset;
      h = (struct elf_link_hash_entry *) h->root.u.i.link;
    }
  if (h->root.type == bfd_link_hash_indirect)
    return TRUE;
  if (! _bfd_elf_fix_symbol_flags (h, eif))
    return FALSE;
  if (!h->needs_plt
      && (h->def_regular
	  || !h->def_dynamic
	  || (!h->ref_regular
	      && (h->u.weakdef == NULL || h->u.weakdef->dynindx == -1))))
    {
      h->plt = elf_hash_table (eif->info)->init_plt_offset;
      return TRUE;
    }
  if (h->dynamic_adjusted)
    return TRUE;
  h->dynamic_adjusted = 1;
  if (h->u.weakdef != NULL)
    {
      h->u.weakdef->ref_regular = 1;
      if (! _bfd_elf_adjust_dynamic_symbol (h->u.weakdef, eif))
	return FALSE;
    }
  if (h->size == 0
      && h->type == STT_NOTYPE
      && !h->needs_plt)
    (*_bfd_error_handler)
      (_("warning: type and size of dynamic symbol `%s' are not defined"),
       h->root.root.string);
  dynobj = elf_hash_table (eif->info)->dynobj;
  bed = get_elf_backend_data (dynobj);
  if (! (*bed->elf_backend_adjust_dynamic_symbol) (eif->info, h))
    {
      eif->failed = TRUE;
      return FALSE;
    }
  return TRUE;
}
bfd_boolean _bfd_elf_adjust_dynamic_symbol ( struct elf_link_hash_entry * h , void * data ) { struct elf_info_failed * eif = data ; bfd * dynobj ; const struct elf_backend_data * bed ; if ( ! is_elf_hash_table ( eif -> info -> hash ) ) return FALSE ; if ( h -> root . type == bfd_link_hash_warning ) { h -> got = elf_hash_table ( eif -> info ) -> init_got_offset ; h -> plt = elf_hash_table ( eif -> info ) -> init_plt_offset ; h = ( struct elf_link_hash_entry * ) h -> root . u . i . link ; } if ( h -> root . type == bfd_link_hash_indirect ) return TRUE ; if ( ! _bfd_elf_fix_symbol_flags ( h , eif ) ) return FALSE ; if ( ! h -> needs_plt && ( h -> def_regular || ! h -> def_dynamic || ( ! h -> ref_regular && ( h -> u . weakdef == NULL || h -> u . weakdef -> dynindx == -1 ) ) ) ) { h -> plt = elf_hash_table ( eif -> info ) -> init_plt_offset ; return TRUE ; } if ( h -> dynamic_adjusted ) return TRUE ; h -> dynamic_adjusted = 1 ; if ( h -> u . weakdef != NULL ) { h -> u . weakdef -> ref_regular = 1 ; if ( ! _bfd_elf_adjust_dynamic_symbol ( h -> u . weakdef , eif ) ) return FALSE ; } if ( h -> size == 0 && h -> type == STT_NOTYPE && ! h -> needs_plt ) ( * _bfd_error_handler ) ( _ ( " " ) , h -> root . root . string ) ; dynobj = elf_hash_table ( eif -> info ) -> dynobj ; bed = get_elf_backend_data ( dynobj ) ; if ( ! ( * bed -> elf_backend_adjust_dynamic_symbol ) ( eif -> info , h ) ) { eif -> failed = TRUE ; return FALSE ; } return TRUE ; }
Make the backend pick a good value for a dynamic symbol.
Make the backend pick a good value for a dynamic symbol .
/* When warning symbols are created, they **replace** the "real"
	 entry in the hash table, thus we never get to see the real
	 symbol in a hash traversal.  So look at it now.  */ /* Ignore indirect symbols.  These are added by the versioning code.  */ /* Fix the symbol flags.  */ /* If this symbol does not require a PLT entry, and it is not
     defined by a dynamic object, or is not referenced by a regular
     object, ignore it.  We do have to handle a weak defined symbol,
     even if no regular object refers to it, if we decided to add it
     to the dynamic symbol table.  FIXME: Do we normally need to worry
     about symbols which are defined by one dynamic object and
     referenced by another one?  */ /* If we've already adjusted this symbol, don't do it again.  This
     can happen via a recursive call.  */ /* Don't look at this symbol again.  Note that we must set this
     after checking the above conditions, because we may look at a
     symbol once, decide not to do anything, and then get called
     recursively later after REF_REGULAR is set below.  */ /* If this is a weak definition, and we know a real definition, and
     the real symbol is not itself defined by a regular object file,
     then get a good value for the real definition.  We handle the
     real symbol first, for the convenience of the backend routine.

     Note that there is a confusing case here.  If the real definition
     is defined by a regular object file, we don't get the real symbol
     from the dynamic object, but we do get the weak symbol.  If the
     processor backend uses a COPY reloc, then if some routine in the
     dynamic object changes the real symbol, we will not see that
     change in the corresponding weak symbol.  This is the way other
     ELF linkers work as well, and seems to be a result of the shared
     library model.

     I will clarify this issue.  Most SVR4 shared libraries define the
     variable _timezone and define timezone as a weak synonym.  The
     tzset call changes _timezone.  If you write
       extern int timezone;
       int _timezone = 5;
       int main () { tzset (); printf ("%d %d\n", timezone, _timezone); }
     you might expect that, since timezone is a synonym for _timezone,
     the same number will print both times.  However, if the processor
     backend uses a COPY reloc, then actually timezone will be copied
     into your process image, and, since you define _timezone
     yourself, _timezone will not.  Thus timezone and _timezone will
     wind up at different memory locations.  The tzset call will set
     _timezone, leaving timezone unchanged.  */ /* If we get to this point, we know there is an implicit
	 reference by a regular object file via the weak symbol H.
	 FIXME: Is this really true?  What if the traversal finds
	 H->U.WEAKDEF before it finds H?  */ /* If a symbol has no type and no size and does not require a PLT
     entry, then we are probably about to do the wrong thing here: we
     are probably going to create a COPY reloc for an empty object.
     This case can arise when a shared object is built with assembly
     code, and the assembly code fails to set the symbol type.  */