FreeBSD/contrib/binutils/bfd/elflink.c
/* Propagate collected vtable information.  This is called through
   elf_link_hash_traverse.  */
Propagate collected vtable information.  This is called through
elf_link_hash_traverse.
Propagate collected vtable information . This is called through elf_link_hash_traverse .
static bfd_boolean
elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp)
{
  if (h->root.type == bfd_link_hash_warning)
    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  if (h->vtable == NULL || h->vtable->parent == NULL)
    return TRUE;
  if (h->vtable->parent == (struct elf_link_hash_entry *) -1)
    return TRUE;
  if (h->vtable->used && h->vtable->used[-1])
    return TRUE;
  elf_gc_propagate_vtable_entries_used (h->vtable->parent, okp);
  if (h->vtable->used == NULL)
    {
      h->vtable->used = h->vtable->parent->vtable->used;
      h->vtable->size = h->vtable->parent->vtable->size;
    }
  else
    {
      size_t n;
      bfd_boolean *cu, *pu;
      cu = h->vtable->used;
      cu[-1] = TRUE;
      pu = h->vtable->parent->vtable->used;
      if (pu != NULL)
	{
	  const struct elf_backend_data *bed;
	  unsigned int log_file_align;
	  bed = get_elf_backend_data (h->root.u.def.section->owner);
	  log_file_align = bed->s->log_file_align;
	  n = h->vtable->parent->vtable->size >> log_file_align;
	  while (n--)
	    {
	      if (*pu)
		*cu = TRUE;
	      pu++;
	      cu++;
	    }
	}
    }
  return TRUE;
}
static bfd_boolean elf_gc_propagate_vtable_entries_used ( struct elf_link_hash_entry * h , void * okp ) { if ( h -> root . type == bfd_link_hash_warning ) h = ( struct elf_link_hash_entry * ) h -> root . u . i . link ; if ( h -> vtable == NULL || h -> vtable -> parent == NULL ) return TRUE ; if ( h -> vtable -> parent == ( struct elf_link_hash_entry * ) -1 ) return TRUE ; if ( h -> vtable -> used && h -> vtable -> used [ -1 ] ) return TRUE ; elf_gc_propagate_vtable_entries_used ( h -> vtable -> parent , okp ) ; if ( h -> vtable -> used == NULL ) { h -> vtable -> used = h -> vtable -> parent -> vtable -> used ; h -> vtable -> size = h -> vtable -> parent -> vtable -> size ; } else { size_t n ; bfd_boolean * cu , * pu ; cu = h -> vtable -> used ; cu [ -1 ] = TRUE ; pu = h -> vtable -> parent -> vtable -> used ; if ( pu != NULL ) { const struct elf_backend_data * bed ; unsigned int log_file_align ; bed = get_elf_backend_data ( h -> root . u . def . section -> owner ) ; log_file_align = bed -> s -> log_file_align ; n = h -> vtable -> parent -> vtable -> size >> log_file_align ; while ( n -- ) { if ( * pu ) * cu = TRUE ; pu ++ ; cu ++ ; } } } return TRUE ; }
Propagate collected vtable information.
Propagate collected vtable information .
/* Those that are not vtables.  */ /* Those vtables that do not have parents, we cannot merge.  */ /* If we've already been done, exit.  */ /* Make sure the parent's table is up to date.  */ /* None of this table's entries were referenced.  Re-use the
	 parent's table.  */ /* Or the parent's entries into ours.  */