FreeBSD/contrib/binutils/bfd/elflink.c
/* Called from check_relocs to record the existence of a VTINHERIT reloc.  */
Called from check_relocs to record the existence of a VTINHERIT reloc.
Called from check_relocs to record the existence of a VTINHERIT reloc .
bfd_boolean
bfd_elf_gc_record_vtinherit (bfd *abfd,
			     asection *sec,
			     struct elf_link_hash_entry *h,
			     bfd_vma offset)
{
  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
  struct elf_link_hash_entry **search, *child;
  bfd_size_type extsymcount;
  const struct elf_backend_data *bed = get_elf_backend_data (abfd);
  extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size / bed->s->sizeof_sym;
  if (!elf_bad_symtab (abfd))
    extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info;
  sym_hashes = elf_sym_hashes (abfd);
  sym_hashes_end = sym_hashes + extsymcount;
  for (search = sym_hashes; search != sym_hashes_end; ++search)
    {
      if ((child = *search) != NULL
	  && (child->root.type == bfd_link_hash_defined
	      || child->root.type == bfd_link_hash_defweak)
	  && child->root.u.def.section == sec
	  && child->root.u.def.value == offset)
	goto win;
    }
  (*_bfd_error_handler) ("%B: %A+%lu: No symbol found for INHERIT",
			 abfd, sec, (unsigned long) offset);
  bfd_set_error (bfd_error_invalid_operation);
  return FALSE;
 win:
  if (!child->vtable)
    {
      child->vtable = bfd_zalloc (abfd, sizeof (*child->vtable));
      if (!child->vtable)
	return FALSE;
    }
  if (!h)
    {
      child->vtable->parent = (struct elf_link_hash_entry *) -1;
    }
  else
    child->vtable->parent = h;
  return TRUE;
}
bfd_boolean bfd_elf_gc_record_vtinherit ( bfd * abfd , asection * sec , struct elf_link_hash_entry * h , bfd_vma offset ) { struct elf_link_hash_entry * * sym_hashes , * * sym_hashes_end ; struct elf_link_hash_entry * * search , * child ; bfd_size_type extsymcount ; const struct elf_backend_data * bed = get_elf_backend_data ( abfd ) ; extsymcount = elf_tdata ( abfd ) -> symtab_hdr . sh_size / bed -> s -> sizeof_sym ; if ( ! elf_bad_symtab ( abfd ) ) extsymcount -= elf_tdata ( abfd ) -> symtab_hdr . sh_info ; sym_hashes = elf_sym_hashes ( abfd ) ; sym_hashes_end = sym_hashes + extsymcount ; for ( search = sym_hashes ; search != sym_hashes_end ; ++ search ) { if ( ( child = * search ) != NULL && ( child -> root . type == bfd_link_hash_defined || child -> root . type == bfd_link_hash_defweak ) && child -> root . u . def . section == sec && child -> root . u . def . value == offset ) goto win ; } ( * _bfd_error_handler ) ( " " , abfd , sec , ( unsigned long ) offset ) ; bfd_set_error ( bfd_error_invalid_operation ) ; return FALSE ; win : if ( ! child -> vtable ) { child -> vtable = bfd_zalloc ( abfd , sizeof ( * child -> vtable ) ) ; if ( ! child -> vtable ) return FALSE ; } if ( ! h ) { child -> vtable -> parent = ( struct elf_link_hash_entry * ) -1 ; } else child -> vtable -> parent = h ; return TRUE ; }
Called from check_relocs to record the existence of a VTINHERIT reloc.
Called from check_relocs to record the existence of a VTINHERIT reloc .
/* The sh_info field of the symtab header tells us where the
     external symbols start.  We don't care about the local symbols at
     this point.  */ /* Hunt down the child symbol, which is in this section at the same
     offset as the relocation.  */ /* This *should* only be the absolute section.  It could potentially
	 be that someone has defined a non-global vtable though, which
	 would be bad.  It isn't worth paging in the local symbols to be
	 sure though; that case should simply be handled by the assembler.  */