ooo-build r11272 - trunk/patches/test



Author: michael
Date: Tue Jan 15 17:06:04 2008
New Revision: 11272
URL: http://svn.gnome.org/viewvc/ooo-build?rev=11272&view=rev

Log:
semi-working (though horribly hacked)


Added:
   trunk/patches/test/binutils-vt-copy-2.diff
Modified:
   trunk/patches/test/gcc-vt-copy-2.diff

Added: trunk/patches/test/binutils-vt-copy-2.diff
==============================================================================
--- (empty file)
+++ trunk/patches/test/binutils-vt-copy-2.diff	Tue Jan 15 17:06:04 2008
@@ -0,0 +1,1574 @@
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-binutils-2.17.50/bfd/elf-bfd.h binutils-2.17.50/bfd/elf-bfd.h
+--- pristine-binutils-2.17.50/bfd/elf-bfd.h	2008-01-09 16:45:22.000000000 +0000
++++ binutils-2.17.50/bfd/elf-bfd.h	2008-01-09 17:04:17.000000000 +0000
+@@ -1787,6 +1787,12 @@
+ extern void _bfd_elf_init_2_index_sections
+   (bfd *, struct bfd_link_info *);
+ 
++/* elf-vtreloc */
++extern bfd_boolean _bfd_elf_vtreloc_accumulate
++  (bfd *, struct bfd_link_info *);
++extern bfd_boolean _bfd_elf_vtreloc_fill
++  (bfd *, struct bfd_link_info *);
++
+ extern bfd_boolean _bfd_elfcore_make_pseudosection
+   (bfd *, char *, size_t, ufile_ptr);
+ extern char *_bfd_elfcore_strndup
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-binutils-2.17.50/bfd/elf-vtreloc.c binutils-2.17.50/bfd/elf-vtreloc.c
+--- pristine-binutils-2.17.50/bfd/elf-vtreloc.c	2008-01-09 16:54:44.000000000 +0000
++++ binutils-2.17.50/bfd/elf-vtreloc.c	2008-01-15 15:40:27.000000000 +0000
+@@ -0,0 +1,596 @@
++#include "sysdep.h"
++#include "bfd.h"
++#include "sysdep.h"
++#include "bfdlink.h"
++#include "libbfd.h"
++#define ARCH_SIZE 0
++#include "elf-bfd.h"
++#include "safe-ctype.h"
++#include "libiberty.h"
++
++typedef struct _CopyEntry CopyEntry;
++
++typedef struct {
++    bfd       *abfd;
++    CopyEntry *sorted;
++    CopyEntry *unsorted;
++} VtRelocs;
++
++struct _CopyEntry {
++    struct elf_link_hash_entry *src;
++    bfd_vma                     src_offset;
++    struct elf_link_hash_entry *dest;
++    bfd_vma                     dest_offset;
++    bfd_vma                     bitmask;
++
++    /* chain */
++    CopyEntry *next;
++};
++
++static void
++prepend (CopyEntry **list, CopyEntry *p)
++{
++    p->next = *list;
++    *list = p;
++}
++
++static int
++copy_entry_equal (const CopyEntry *a, const CopyEntry *b)
++{
++    return (a->src == b->src &&
++            a->src_offset == b->src_offset &&
++            a->dest == b->dest &&
++            a->dest_offset == b->dest_offset &&
++            a->bitmask == b->bitmask);
++}
++
++/*
++ * FIXME - should be a hash lookup / something fast.
++ */
++static CopyEntry *
++find_with_dest (CopyEntry *list,
++                struct elf_link_hash_entry *e)
++{
++    while (list)
++      {
++        if (list->dest == e)
++          break;
++        list = list->next;
++      }
++    return list;
++}
++
++static CopyEntry *
++find_equal_entry (CopyEntry *list, CopyEntry *e)
++{
++  while (list)
++    {
++      if (copy_entry_equal (list, e))
++        break;
++      list = list->next;
++    }
++  return list;
++}
++
++/*
++ * Transfer from unsorted -> sorted.
++ * NB. simple-minded algorithm, N^3 with degenerate case
++ */
++static void
++sort_relocs (VtRelocs *vtr)
++{
++    CopyEntry *p;
++    CopyEntry *pending;
++    CopyEntry *next;
++
++    fprintf (stderr, "Sorting ...");
++    do
++      {
++        pending = NULL;
++        
++        for (p = vtr->unsorted; p; p = next)
++          {
++            next = p->next;
++            if (!find_with_dest (vtr->unsorted, p->src))
++            {
++              /* FIXME: sorting by offset, to ensure as
++                 good as possible contiguous access will
++                 require a more complex node structure:
++                 with aggregation per 'dest', and
++                 internal sorting within that */
++              prepend (&vtr->sorted, p);
++            }
++            else
++              prepend (&pending, p);
++          }
++        vtr->unsorted = pending;
++      }
++    while (pending);
++    fprintf (stderr, " done\n");
++}
++
++static void
++check_reloc (Elf_Internal_Rela *rel, int type_mask)
++{
++  if ((rel->r_info & type_mask) != STT_OBJECT)
++      fprintf (stderr, "broken vtreloc type\n");
++  if (rel->r_addend != 0)
++      fprintf (stderr, "unexpected reloc addend\n");
++}
++
++static void
++print_rel (const char *type, 
++           struct elf_link_hash_entry *target)
++{
++  fprintf (stderr, "%s '%s' %d %d %d %d i:%ld\n",
++           type, target->root.root.string,
++           target->ref_regular, target->def_regular,
++           target->ref_dynamic, target->def_dynamic,
++           target->dynindx);
++}
++
++static void
++add_reloc (VtRelocs *vtr,
++           bfd      *inputobj,
++           Elf_Internal_Rela *src_rel,
++           Elf_Internal_Rela *dest_rel,
++           unsigned char     *data)
++{
++  unsigned r_sym_shift;
++  unsigned r_type_mask;
++  unsigned incr;
++  unsigned symidx;
++  const struct elf_backend_data *bed;
++  struct elf_link_hash_entry *dest, *src;
++  Elf_Internal_Shdr *hdr;
++  CopyEntry *e;
++
++  hdr = &elf_tdata (inputobj)->symtab_hdr;
++  bed = get_elf_backend_data (inputobj);
++  if (bed->s->arch_size == 32)
++    {
++      r_type_mask = 0xff;
++      r_sym_shift = 8;
++      incr = 4;
++    }
++  else
++    {
++      r_type_mask = 0xffffffff;
++      r_sym_shift = 32;
++      incr = 8;
++    }
++
++  check_reloc (src_rel, r_type_mask);
++  check_reloc (dest_rel, r_type_mask);
++
++/*
++#define elf_sym_hashes(bfd)	(elf_tdata(bfd) -> sym_hashes)
++#define elf_tdata(bfd)		((bfd) -> tdata.elf_obj_data)
++  Elf
++  cf. RELOC_FOR_GLOBAL_SYMBOL ...
++*/
++
++  symidx = (dest_rel->r_info >> r_sym_shift);
++  fprintf (stderr, "symidx %d (-%d)!\n", symidx, hdr->sh_info);
++
++  if (symidx < hdr->sh_info) // local symbol ...
++  {
++      fprintf (stderr, "Error/FIXME: local dest symbol !");
++      return;
++  }
++
++  symidx -= hdr->sh_info;
++  dest = elf_sym_hashes (inputobj) [symidx];
++  if (!dest) {
++      fprintf (stderr, "no rel %d!\n", symidx);
++      return;
++  }
++
++  /* Eliminate relocs to no longer present internal vtables. */
++  if (!dest->def_regular)
++    {
++      print_rel ("Abandoning dest", dest);
++      fprintf (stderr, "Ref count %ld %ld dynindx %d\n",
++               dest->got.refcount, dest->plt.refcount,
++               (int) dest->dynindx);
++      /* unref the symbol somehow (!?) */
++      return;
++    }
++
++  // FIXME: do we need something like this for indirect / warnings !?
++/*    while (target->root.type == bfd_link_hash_indirect
++           || target->root.type == bfd_link_hash_warning)
++           target = (struct elf_link_hash_entry *) target->root.u.i.link; */
++  fprintf (stderr, "dest link type %d\n", dest->root.type);
++  if (dest->root.type == bfd_link_hash_undefined ||
++      dest->root.type == bfd_link_hash_undefweak)
++    {
++      fprintf (stderr, "undefined dest sym '%s'\n", dest->root.root.string);
++      return;
++    }
++
++  /* Consider: should we eliminate all internal -> internal
++     copies ? it's possible we are more space / time
++     efficient - so no for now. */
++
++  symidx = (src_rel->r_info >> r_sym_shift);
++  if (symidx < hdr->sh_info) // local symbol ...
++  {
++      fprintf (stderr, "Error/FIXME: local src symbol !");
++      return;
++  }
++  symidx -= hdr->sh_info;
++  src = elf_sym_hashes (inputobj) [symidx];
++  if (src->root.type == bfd_link_hash_undefined ||
++      src->root.type == bfd_link_hash_undefweak)
++    {
++      fprintf (stderr, "undefined src sym '%s'\n", src->root.root.string);
++      return;
++    }
++
++  print_rel ("Src", src);
++  print_rel ("Dst", dest);
++
++  e = bfd_zalloc (vtr->abfd, sizeof (CopyEntry));
++
++  e->src = src;
++  e->dest = dest;
++
++  if (dest_rel->r_offset - src_rel->r_offset != bed->s->arch_size / 8)
++      fprintf (stderr, "Mis-paired vtrelocs\n");
++
++  e->src_offset = bfd_get (bed->s->arch_size, inputobj, data);
++  data += incr;
++  e->dest_offset = bfd_get (bed->s->arch_size, inputobj, data);
++  data += incr;
++  e->bitmask = bfd_get (bed->s->arch_size, inputobj, data);
++
++  /* Simple minded dupliates elision */
++  if (find_equal_entry (vtr->unsorted, e))
++    bfd_release (vtr->abfd, e);          
++  else
++    {
++      prepend (&vtr->unsorted, e);  
++
++      fprintf (stderr, "Copy: '%s'+%d -> '%s'+%d (0x%x)\n",
++               e->src->root.root.string,
++               (int)e->src_offset,
++               e->dest->root.root.string,
++               (int)e->dest_offset,
++               (int)e->bitmask);
++    }
++}
++
++static VtRelocs *global_vtr;
++
++bfd_boolean _bfd_elf_vtreloc_accumulate (bfd *output_bfd,
++                                         struct bfd_link_info *info)
++{
++  bfd *dynobj;
++  dynobj = elf_hash_table (info)->dynobj;
++  if (info->vtreloc)
++    { // .vtrelocs
++      bfd_size_type sec_size = 0;
++      asection *vtreloc_sec;
++      asection *vtrelrel;
++      bfd *inputobj;
++      VtRelocs *vtr;
++      Elf_Internal_Rela last_rela;
++      bfd_size_type num_relocs;
++
++      vtr = bfd_zalloc (output_bfd, sizeof (VtRelocs));
++      vtr->abfd = output_bfd;
++      global_vtr = vtr;
++
++      /* FIXME: we need to elide relocs that turn out
++         to be purely internal:
++         eg. internal -> internal copy src / dest,
++         others are less troublesome - though removing
++         empty ones would be nice (?).
++         We want to trap every -named- reloc ...
++      */
++      for (inputobj = info->input_bfds;
++	   inputobj;
++	   inputobj = inputobj->link_next)
++	{
++	  asection *s;
++          struct bfd_elf_section_data *es; /* elf-bfd.h */
++          unsigned i;
++          Elf_Internal_Rela *relocs, *p;
++          unsigned char *sec_data;
++	  long storage_needed;
++	  asymbol **symtab;
++	  long number_of_symbols;
++	  const struct elf_backend_data *bed = get_elf_backend_data (inputobj);
++
++	  if (inputobj->flags & (DYNAMIC | BFD_LINKER_CREATED))
++	    continue;
++	  s = bfd_get_section_by_name (inputobj, ".vtrelocs");
++          if (!s)
++            continue;
++	  /* XXX Hmm, this seems to generate many NONE relocs, probably from
++	     the original relocs to this section.  Perhaps discard them
++	     earlier.  */
++	  /* FIXME: we really don't want to keep these around, quick hack
++	 *** due to having relocs pointing to these sections */
++	  /*	  s->flags |= SEC_EXCLUDE; */
++          es = elf_section_data (s);
++          if (!es)
++            continue;
++
++          if (!s->reloc_count)
++            continue;
++
++          fprintf (stderr, "Relocs: size %d, count %d contents %p\n",
++                   (int)es->rel_hdr.sh_size, es->rel_count,
++                   s->contents);
++          
++
++          /* Can't find this info anywhere else for some reason: */
++          p = relocs = _bfd_elf_link_read_relocs (inputobj, s, NULL, NULL,
++                                                  info->keep_memory);
++
++	  /* Experimental stuff to get at the BFD relocs (translated back
++	     from the real ELF relocs.  */
++	  storage_needed = bfd_get_symtab_upper_bound (inputobj);
++	  if (storage_needed <= 0)
++	    return FALSE;
++	  symtab = xmalloc (storage_needed);
++	  number_of_symbols = bfd_canonicalize_symtab (inputobj, symtab);
++	  if (number_of_symbols < 0)
++	    return FALSE;
++
++	  if (! bed->s->slurp_reloc_table (inputobj, s, symtab, FALSE))
++	    return FALSE;
++          
++	  /* Now inputobj->relocation will contain BFD relocs.  */
++
++          sec_data = bfd_malloc (es->this_hdr.sh_size);
++          
++          /* Slurp the data */
++          if (bfd_seek (inputobj, es->this_hdr.sh_offset, SEEK_SET) != 0)
++            return FALSE;
++          if (bfd_bread (sec_data, es->this_hdr.sh_size, inputobj) != es->this_hdr.sh_size)
++            return FALSE;
++
++          if (es->this_hdr.sh_size % s->reloc_count != 0)
++              fprintf (stderr, "ERROR: mismatching vtreloc sec & reloc count "
++                       "0x%x, 0x%x -> %d\n",
++                       (int)es->this_hdr.sh_size, (int)s->reloc_count,
++                       (int)es->this_hdr.sh_size % s->reloc_count);
++
++          /* Assumes an even number of relocs sorted by address ... */
++          for (i = 0; i < s->reloc_count / 2; i++)
++          {
++              unsigned int entry_size;
++              entry_size = (get_elf_backend_data (inputobj)->s->arch_size / 8) * 3;
++              
++	      last_rela = *p;
++              add_reloc (vtr, inputobj, p, p + 1,
++                         sec_data + i * entry_size);
++              p+=2;
++          }
++          free (sec_data);
++          if (es->relocs != relocs)
++              free (relocs);
++        }
++
++      /* So - we need to sort these guys as we work out the sizes */
++      /* We need to generate an internal list of XYZ type 
++           + eliminate all external -> external work ... 
++           + add all external -> internal copies to 'sorted' list
++              + [ fool-proof GC roots ]
++           + add other symbols to 'pending' list.
++           + read / generate src: [symbol + offset, dest: sym + offset, bitmask data]
++      */
++      sort_relocs (vtr);
++      num_relocs = 0;
++      sec_size = 0;
++      {
++        CopyEntry *e;
++	for (e = vtr->sorted; e; e = e->next)
++	  {
++	    sec_size += 3;  /* Word entries.  */
++	    num_relocs += 2;
++	  }
++      }
++      /*
++         Finally:
++           + build new custom section
++           + emit new relocations for it ...
++      */
++      
++      vtreloc_sec = bfd_get_section_by_name (dynobj, ".suse.vtrelocs");
++      if (vtreloc_sec)
++        {
++	  bfd_size_type rel_size;
++	  bfd_size_type size;
++	  const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
++	  vtrelrel = bfd_get_section_by_name (dynobj, ".rel.suse.vtrelocs");
++	  if (!vtrelrel)
++	    return FALSE;
++
++          {
++              unsigned int entry_size;
++              entry_size = (bed->s->arch_size / 8);
++              /* + 1 for null termination */
++              vtreloc_sec->size = (sec_size + 1) * entry_size;
++              vtreloc_sec->contents = bfd_zalloc (dynobj, vtreloc_sec->size);
++//	      if (!_bfd_elf_add_dynamic_entry (info, DT_SUSE_VTRELOC, 0))
++//	        return FALSE;
++          }
++
++	  rel_size = bed->s->sizeof_rel;
++	  if (bed->default_use_rela_p)
++	    {
++	      rel_size = bed->s->sizeof_rela;
++	    }
++
++	  size = rel_size * num_relocs;
++	  fprintf (stderr, "Need %ld bytes of relocs rel-size %ld\n",
++                   size, rel_size);
++	  vtrelrel->size = size;
++        }
++      else
++        fprintf (stderr, "Horrendous error ! - no .suse.vtrelocs\n");
++
++    }
++  else
++    {
++      asection *vtreloc_sec;
++      vtreloc_sec = bfd_get_section_by_name (dynobj, ".vtrelocs");
++/*  FIXME - foo !
++	if (vtreloc_sec)
++	      vtreloc_sec->flags |= SEC_EXCLUDE; */
++    }
++  return TRUE;
++}
++
++static void
++generate_reloc (bfd                        *dynobj,
++                struct elf_link_hash_entry *target,
++                asection                   *vtreloc_sec,
++                asection                   *vtrelrel,
++                bfd_vma                     num_entry,
++                int                         is_dest,
++                bfd_size_type              *adjust_relative)
++{
++    bfd_size_type sym_idx, rel_size;
++    reloc_howto_type *howto;
++    void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
++    bfd_byte *loc;
++    Elf_Internal_Rela outrel;
++    const struct elf_backend_data *bed;
++
++    bed = get_elf_backend_data (dynobj);
++
++    rel_size = bed->s->sizeof_rel;
++    swap_out = bed->s->swap_reloc_out;
++    if (bed->default_use_rela_p)
++    {
++        rel_size = bed->s->sizeof_rela;
++        swap_out = bed->s->swap_reloca_out;
++    }
++
++    /* XXX: unwind this goodness etc. */
++    while (target->root.type == bfd_link_hash_indirect
++           || target->root.type == bfd_link_hash_warning)
++      target = (struct elf_link_hash_entry *) target->root.u.i.link;
++
++    fprintf (stderr, "Reloc '%s' %d %d %d %d i:%ld ",
++             target->root.root.string,
++             target->ref_regular, target->def_regular,
++             target->ref_dynamic, target->def_dynamic,
++             target->dynindx);
++    if (is_dest /* force relative */ || target->dynindx <= 0)
++      fprintf (stderr, "'%s' vma 0x%lx offset %ld output off %ld\n",
++               target->root.u.def.section->name,
++               target->root.u.def.section->output_section->vma,
++               target->root.u.def.value,
++               target->root.u.def.section->output_offset);
++    else
++      fprintf (stderr, "\n");
++
++    /* XXX: RELOC64 too */
++    if (is_dest /* force relative */ || target->dynindx <= 0)
++      { /* do a relative reloc ... */
++        howto = bfd_reloc_type_lookup (dynobj, BFD_RELOC_386_RELATIVE);
++        sym_idx = 0;
++        BFD_ASSERT (target->root.type == bfd_link_hash_defweak);
++        *adjust_relative = (target->root.u.def.section->output_section->vma +
++                            target->root.u.def.section->output_offset);
++      }
++    else
++      {
++        howto = bfd_reloc_type_lookup (dynobj, BFD_RELOC_32);
++        sym_idx = target->dynindx;
++        *adjust_relative = 0;
++      }
++
++    /* generate relocation */
++    outrel.r_offset = vtreloc_sec->output_section->vma;
++    outrel.r_offset += num_entry * 3 * 4; // XXX: 4 ?
++    if (is_dest) outrel.r_offset += 4; // XXX: 4
++    outrel.r_info = ELF32_R_INFO (sym_idx, howto->type);
++    outrel.r_addend = 0;
++
++    loc = vtrelrel->contents + (vtrelrel->reloc_count++ * rel_size);
++    swap_out (dynobj, &outrel, loc);
++}
++
++bfd_boolean _bfd_elf_vtreloc_fill (bfd *output_bfd,
++                                   struct bfd_link_info *info)
++{
++  bfd *dynobj;
++  dynobj = elf_hash_table (info)->dynobj;
++
++  fprintf (stderr, "Foo: generate .suse.vtrelocs relocs\n");
++
++  if (info->vtreloc)
++    {
++      asection *vtreloc_sec;
++      asection *vtrelrel;
++
++      vtreloc_sec = bfd_get_section_by_name (dynobj, ".suse.vtrelocs");
++      if (vtreloc_sec)
++        {
++	  CopyEntry *e;
++	  bfd_size_type entries, adjust_relative, entry_size;
++	  const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
++          bfd_byte *data;
++
++          entry_size = (bed->s->arch_size / 8);
++
++	  vtrelrel = bfd_get_section_by_name (dynobj, ".rel.suse.vtrelocs");
++	  if (!vtrelrel)
++	    return FALSE;
++	  if (!vtrelrel->contents)
++	    {
++	      fprintf (stderr, "Nothing allocated for relocs\n");
++	      return FALSE;
++	    }
++
++	  BFD_ASSERT (vtreloc_sec->output_offset == 0);
++	  entries = 0;
++	  vtrelrel->reloc_count = 0;
++          data = vtreloc_sec->contents;
++	  for (e = global_vtr->sorted; e; e = e->next)
++	    {
++	      /* Source */
++              generate_reloc (output_bfd, e->src, vtreloc_sec, vtrelrel,
++                              entries, FALSE, &adjust_relative);
++              bfd_put(bed->s->arch_size, output_bfd,
++                      e->src_offset + adjust_relative, data);
++              data += entry_size;
++
++              /* Dest */
++              generate_reloc (output_bfd, e->dest, vtreloc_sec, vtrelrel,
++                              entries, TRUE, &adjust_relative);
++              bfd_put(bed->s->arch_size, output_bfd,
++                      e->dest_offset + adjust_relative, data);
++              data += entry_size;
++
++              bfd_put(bed->s->arch_size, dynobj, e->bitmask, data);
++              data += entry_size;
++
++              entries++;
++            }
++          BFD_ASSERT (vtrelrel->reloc_count * (bed->default_use_rela_p ? bed->s->sizeof_rela : bed->s->sizeof_rel)
++                      == vtrelrel->size);
++        }
++      else
++        fprintf (stderr, "Horrendous error ! - no .suse.vtrelocs\n");
++    }
++  else
++    {
++      asection *vtreloc_sec;
++      fprintf (stderr, "TESTME: exclude .vtrelocs if none present\n");
++      vtreloc_sec = bfd_get_section_by_name (dynobj, ".suse.vtrelocs");
++      if (vtreloc_sec)
++        vtreloc_sec->flags |= SEC_EXCLUDE;
++      vtreloc_sec = bfd_get_section_by_name (dynobj, ".rel.suse.vtrelocs");
++      if (vtreloc_sec)
++        vtreloc_sec->flags |= SEC_EXCLUDE;
++    }
++  return TRUE;
++}
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-binutils-2.17.50/bfd/elf.c binutils-2.17.50/bfd/elf.c
+--- pristine-binutils-2.17.50/bfd/elf.c	2008-01-09 16:45:22.000000000 +0000
++++ binutils-2.17.50/bfd/elf.c	2008-01-09 17:04:17.000000000 +0000
+@@ -1240,6 +1240,7 @@
+ 	    case DT_USED: name = "USED"; break;
+ 	    case DT_FILTER: name = "FILTER"; stringp = TRUE; break;
+ 	    case DT_GNU_HASH: name = "GNU_HASH"; break;
++        case DT_SUSE_VTRELOC: name = "SUSE_VTRELOC"; break;
+ 	    }
+ 
+ 	  fprintf (f, "  %-11s ", name);
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-binutils-2.17.50/bfd/elflink.c binutils-2.17.50/bfd/elflink.c
+--- pristine-binutils-2.17.50/bfd/elflink.c	2008-01-09 16:45:22.000000000 +0000
++++ binutils-2.17.50/bfd/elflink.c	2008-01-15 15:50:27.000000000 +0000
+@@ -148,6 +148,34 @@
+   return TRUE;
+ }
+ 
++static int
++_bfd_elf_create_vtreloc_sections (struct bfd_link_info *info)
++{
++  bfd *abfd;
++  asection *s;
++  flagword flags;
++  const struct elf_backend_data *bed;
++
++  abfd = elf_hash_table (info)->dynobj;
++  bed = get_elf_backend_data (abfd);
++  flags = bed->dynamic_sec_flags;
++
++  s = bfd_make_section (abfd, ".suse.vtrelocs");
++  if (s == NULL
++      || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
++      || ! bfd_set_section_alignment (abfd, s, 2))
++    return FALSE;
++  s = bfd_make_section (abfd, ".rel.suse.vtrelocs");
++  if (s == NULL
++      || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY
++                                  | SEC_HAS_CONTENTS
++                                  | SEC_IN_MEMORY | SEC_LINKER_CREATED)
++      || ! bfd_set_section_alignment (abfd, s, 2))
++      return FALSE;
++
++  return TRUE;
++}
++
+ /* Create some sections which will be filled in with dynamic linking
+    information.  ABFD is an input file which requires dynamic sections
+    to be created.  The dynamic sections take up virtual memory space
+@@ -2266,6 +2294,7 @@
+ 	return FALSE;
+ 
+       elf_section_data (o)->rel_hashes = p;
++      fprintf (stderr, "allocated rel_hashes for asec %p\n", o);
+     }
+ 
+   return TRUE;
+@@ -3291,7 +3320,25 @@
+   bed = get_elf_backend_data (abfd);
+ 
+   if ((abfd->flags & DYNAMIC) == 0)
++  {
++    asection *vtrel_sec;
++
+     dynamic = FALSE;
++
++    vtrel_sec = bfd_get_section_by_name (abfd, ".vtrelocs");
++    if (vtrel_sec)
++      {
++        fprintf (stderr, "Has vtrelocs ! %d\n", (int)vtrel_sec->size);
++        if (!info->vtreloc)
++          {
++            info->vtreloc = 1;
++            if (!_bfd_elf_create_vtreloc_sections (info))
++              goto error_return;
++          }
++/*        FIXME: quick hack here ...
++	  vtrel_sec->flags |= SEC_EXCLUDE; */
++      }
++  }
+   else
+     {
+       dynamic = TRUE;
+@@ -3603,6 +3650,7 @@
+   else
+     hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+ 
++/* FIXME: cut/paste this ! ....*/
+   symcount = hdr->sh_size / bed->s->sizeof_sym;
+ 
+   /* The sh_info field of the symtab header tells us where the
+@@ -4978,8 +5026,14 @@
+   switch (bfd_get_format (abfd))
+     {
+     case bfd_object:
++      fprintf (stderr, "add_symbols from %s object '%s'\n",
++               abfd->flags & DYNAMIC ? "dynamic" : "static",
++               abfd->filename);
++      // from an .o or .so file ...
+       return elf_link_add_object_symbols (abfd, info);
+     case bfd_archive:
++      fprintf (stderr, "add_symbols from archive '%s'\n", abfd->filename);
++      // from a .a file ...
+       return elf_link_add_archive_symbols (abfd, info);
+     default:
+       bfd_set_error (bfd_error_wrong_format);
+@@ -5372,6 +5426,8 @@
+ 	}
+     }
+ 
++  _bfd_elf_vtreloc_accumulate (output_bfd, info);
++
+   /* Any syms created from now on start with -1 in
+      got.refcount/offset and plt.refcount/offset.  */
+   elf_hash_table (info)->init_got_refcount
+@@ -5652,6 +5708,13 @@
+ 	    return FALSE;
+ 	}
+ 
++      s = bfd_get_section_by_name (output_bfd, ".suse.vtrelocs");
++      if (s != NULL)
++	{
++          if (!_bfd_elf_add_dynamic_entry (info, DT_SUSE_VTRELOC, 0))
++	    return FALSE;
++	}
++
+       dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
+       /* If .dynstr is excluded from the link, we don't want any of
+ 	 these tags.  Strictly, we should be checking each section
+@@ -7159,6 +7222,8 @@
+   size_t symbuf_size;
+   /* And same for symshndxbuf.  */
+   size_t shndxbuf_size;
++  /* .suse.vtreloc section.  */
++  asection *vtreloc_sec;
+ };
+ 
+ /* This struct is used to pass information to elf_link_output_extsym.  */
+@@ -7902,6 +7967,8 @@
+   bfd_vma r_type_mask;
+   int r_sym_shift;
+ 
++  fprintf (stderr, "elf_link_adjust_relocs ... %p\n", rel_hash);
++
+   if (rel_hdr->sh_entsize == bed->s->sizeof_rel)
+     {
+       swap_in = bed->s->swap_reloc_in;
+@@ -10038,6 +10105,7 @@
+       finfo.dynsym_sec = NULL;
+       finfo.hash_sec = NULL;
+       finfo.symver_sec = NULL;
++      finfo.vtreloc_sec = NULL;
+     }
+   else
+     {
+@@ -10045,6 +10113,7 @@
+       finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash");
+       BFD_ASSERT (finfo.dynsym_sec != NULL);
+       finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version");
++      finfo.vtreloc_sec = bfd_get_section_by_name (dynobj, ".suse.vtrelocs");
+       /* Note that it is OK if symver_sec is NULL.  */
+     }
+ 
+@@ -10104,6 +10173,10 @@
+   max_sym_count = 0;
+   max_sym_shndx_count = 0;
+   merged = FALSE;
++
++  if (dynobj && !info->relocatable)
++    _bfd_elf_vtreloc_fill (finfo.output_bfd, info);
++
+   for (o = abfd->sections; o != NULL; o = o->next)
+     {
+       struct bfd_elf_section_data *esdo = elf_section_data (o);
+@@ -10732,6 +10805,10 @@
+       if ((o->flags & SEC_RELOC) == 0)
+ 	continue;
+ 
++      fprintf (stderr, "rel_hashes for asec %p is %d, %p\n", o,
++               (int)elf_section_data (o)->rel_count,
++               elf_section_data (o)->rel_hashes);
++
+       elf_link_adjust_relocs (abfd, &elf_section_data (o)->rel_hdr,
+ 			      elf_section_data (o)->rel_count,
+ 			      elf_section_data (o)->rel_hashes);
+@@ -10869,6 +10946,11 @@
+ 	    case DT_VERNEED:
+ 	      name = ".gnu.version_r";
+ 	      goto get_vma;
++	    case DT_SUSE_VTRELOC:
++	      name = ".suse.vtrelocs";
++	      o = bfd_get_section_by_name (abfd, name);
++              fprintf (stderr, "got section vma at 0x%x\n", o->vma);
++	      goto get_vma;
+ 	    case DT_VERSYM:
+ 	      name = ".gnu.version";
+ 	    get_vma:
+@@ -11129,6 +11211,8 @@
+   bfd_boolean is_eh;
+   asection *group_sec;
+ 
++/* #warning "Do we want to ignore relocs inside .suse.vtreloc ?" */
++
+   sec->gc_mark = 1;
+ 
+   /* Mark all the sections in the group.  */
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-binutils-2.17.50/bfd/elflink.c~ binutils-2.17.50/bfd/elflink.c~
+--- pristine-binutils-2.17.50/bfd/elflink.c~	2008-01-09 12:42:12.000000000 +0000
++++ binutils-2.17.50/bfd/elflink.c~	2008-01-14 14:28:26.000000000 +0000
+@@ -5707,6 +5707,13 @@
+ 	    return FALSE;
+ 	}
+ 
++      s = bfd_get_section_by_name (output_bfd, ".suse.vtrelocs");
++      if (s != NULL)
++	{
++          if (!_bfd_elf_add_dynamic_entry (info, DT_SUSE_VTRELOC, 0))
++	    return FALSE;
++	}
++
+       dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
+       /* If .dynstr is excluded from the link, we don't want any of
+ 	 these tags.  Strictly, we should be checking each section
+@@ -10097,6 +10104,7 @@
+       finfo.dynsym_sec = NULL;
+       finfo.hash_sec = NULL;
+       finfo.symver_sec = NULL;
++      finfo.vtreloc_sec = NULL;
+     }
+   else
+     {
+@@ -10104,6 +10112,7 @@
+       finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash");
+       BFD_ASSERT (finfo.dynsym_sec != NULL);
+       finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version");
++      finfo.vtreloc_sec = bfd_get_section_by_name (dynobj, ".suse.vtrelocs");
+       /* Note that it is OK if symver_sec is NULL.  */
+     }
+ 
+@@ -10937,7 +10946,9 @@
+ 	      name = ".gnu.version_r";
+ 	      goto get_vma;
+ 	    case DT_SUSE_VTRELOC:
+-	      name = ".suse.vtreloc";
++	      name = ".suse.vtrelocs";
++	      o = bfd_get_section_by_name (abfd, name);
++              fprintf (stderr, "got section vma at 0x%x\n", o->vma);
+ 	      goto get_vma;
+ 	    case DT_VERSYM:
+ 	      name = ".gnu.version";
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-binutils-2.17.50/include/bfdlink.h binutils-2.17.50/include/bfdlink.h
+--- pristine-binutils-2.17.50/include/bfdlink.h	2008-01-09 16:45:22.000000000 +0000
++++ binutils-2.17.50/include/bfdlink.h	2008-01-09 17:04:17.000000000 +0000
+@@ -293,6 +293,10 @@
+   /* TRUE if the new ELF dynamic tags are enabled. */
+   unsigned int new_dtags: 1;
+ 
++  /* TRUE if we want to produce copy-based vtable relocation
++     data. This saves both space and time.  */
++  unsigned int vtreloc: 1;
++
+   /* TRUE if non-PLT relocs should be merged into one reloc section
+      and sorted so that relocs against the same symbol come together.  */
+   unsigned int combreloc: 1;
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-binutils-2.17.50/include/elf/common.h binutils-2.17.50/include/elf/common.h
+--- pristine-binutils-2.17.50/include/elf/common.h	2008-01-09 16:45:22.000000000 +0000
++++ binutils-2.17.50/include/elf/common.h	2008-01-09 17:04:17.000000000 +0000
+@@ -624,6 +624,13 @@
+ #define DT_USED		0x7ffffffe
+ #define DT_FILTER	0x7fffffff
+ 
++/* SUSE specific pieces - at a random OS specific address, after
++   previous 2 (direct/hashvals) development sections  */
++#define DT_SUSE_LO (0x6cbdd030 + 2)
++#define DT_SUSE_VTRELOC   DT_SUSE_LO
++#define DT_SUSE_HI 0x6cbdd040
++#define DT_SUSE_TAGIDX(tag) (tag - DT_SUSE_LO)
++#define DT_SUSENUM 1
+ 
+ /* Values used in DT_FEATURE .dynamic entry.  */
+ #define DTF_1_PARINIT	0x00000001
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-binutils-2.17.50/ld/ldmain.c binutils-2.17.50/ld/ldmain.c
+--- pristine-binutils-2.17.50/ld/ldmain.c	2008-01-09 16:45:22.000000000 +0000
++++ binutils-2.17.50/ld/ldmain.c	2008-01-09 17:04:17.000000000 +0000
+@@ -1105,6 +1105,7 @@
+ 	    asection *section,
+ 	    bfd_vma value)
+ {
++  fprintf (stderr, "add_to_set '%s'\n", h->root.string);
+   if (config.warn_constructors)
+     einfo (_("%P: warning: global constructor %s used\n"),
+ 	   h->root.string);
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-binutils-2.17.50/ld/lexsup.c binutils-2.17.50/ld/lexsup.c
+--- pristine-binutils-2.17.50/ld/lexsup.c	2008-01-09 16:45:22.000000000 +0000
++++ binutils-2.17.50/ld/lexsup.c	2008-01-09 17:04:17.000000000 +0000
+@@ -157,6 +157,7 @@
+   OPTION_ACCEPT_UNKNOWN_INPUT_ARCH,
+   OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH,
+   OPTION_PIE,
++  OPTION_VTRELOC,
+   OPTION_UNRESOLVED_SYMBOLS,
+   OPTION_WARN_UNRESOLVED_SYMBOLS,
+   OPTION_ERROR_UNRESOLVED_SYMBOLS,
+@@ -409,6 +410,8 @@
+   { {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED},
+     '\0', NULL, N_("Do not allow unresolved references in object files"),
+     TWO_DASHES },
++  { {"vtreloc", no_argument, NULL, OPTION_VTRELOC},
++    '\0', NULL, N_("Build vtable copy reloc data"), TWO_DASHES },
+   { {"allow-shlib-undefined", no_argument, NULL, OPTION_ALLOW_SHLIB_UNDEFINED},
+     '\0', NULL, N_("Allow unresolved references in shared libaries"),
+     TWO_DASHES },
+@@ -1171,6 +1174,9 @@
+ 	case OPTION_DEFAULT_SCRIPT:
+ 	  command_line.default_script = optarg;
+ 	  break;
++	case OPTION_VTRELOC:
++	  link_info.vtreloc = TRUE;
++	  break;
+ 	case OPTION_SECTION_START:
+ 	  {
+ 	    char *optarg2;
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-binutils-2.17.50/ld/scripttempl/elf.sc binutils-2.17.50/ld/scripttempl/elf.sc
+--- pristine-binutils-2.17.50/ld/scripttempl/elf.sc	2008-01-09 16:45:22.000000000 +0000
++++ binutils-2.17.50/ld/scripttempl/elf.sc	2008-01-15 15:42:22.000000000 +0000
+@@ -285,6 +285,7 @@
+ eval $COMBRELOCCAT <<EOF
+   .rel.init     ${RELOCATING-0} : { *(.rel.init) }
+   .rela.init    ${RELOCATING-0} : { *(.rela.init) }
++  .rel.suse.vtrelocs     ${RELOCATING-0} : { *(.rel.suse.vtrelocs) }
+   .rel.text     ${RELOCATING-0} : { *(.rel.text${RELOCATING+ .rel.text.* .rel.gnu.linkonce.t.*}) }
+   .rela.text    ${RELOCATING-0} : { *(.rela.text${RELOCATING+ .rela.text.* .rela.gnu.linkonce.t.*}) }
+   .rel.fini     ${RELOCATING-0} : { *(.rel.fini) }
+@@ -321,7 +322,7 @@
+     {
+ EOF
+ sed -e '/^[ 	]*[{}][ 	]*$/d;/:[ 	]*$/d;/\.rela\./d;s/^.*: { *\(.*\)}$/      \1/' $COMBRELOC
+-cat <<EOF
++cat <<EOF 
+     }
+   .rela.dyn     ${RELOCATING-0} :
+     {
+@@ -410,6 +411,16 @@
+   ${SMALL_DATA_DTOR-${RELOCATING+${DTOR}}}
+   .jcr          ${RELOCATING-0} : { KEEP (*(.jcr)) }
+ 
++  /* Virtual table copy relocation tables */
++  __vtrelocs = .;
++  .suse.vtrelocs  :
++  {
++    KEEP (*(.suse.vtrelocs))
++      /* FIXME: hack to avoid getting hurt by tmp.
++       relocs into these sections */
++    KEEP (*(.vtrelocs))
++  }
++
+   ${RELOCATING+${DATARELRO}}
+   ${OTHER_RELRO_SECTIONS}
+   ${TEXT_DYNAMIC-${DYNAMIC}}
+--- /dev/null	2007-09-21 22:50:58.000000000 +0100
++++ binutils-2.17.50/bfd/elf-vtreloc.c	2008-01-15 15:40:27.000000000 +0000
+@@ -0,0 +1,596 @@
++#include "sysdep.h"
++#include "bfd.h"
++#include "sysdep.h"
++#include "bfdlink.h"
++#include "libbfd.h"
++#define ARCH_SIZE 0
++#include "elf-bfd.h"
++#include "safe-ctype.h"
++#include "libiberty.h"
++
++typedef struct _CopyEntry CopyEntry;
++
++typedef struct {
++    bfd       *abfd;
++    CopyEntry *sorted;
++    CopyEntry *unsorted;
++} VtRelocs;
++
++struct _CopyEntry {
++    struct elf_link_hash_entry *src;
++    bfd_vma                     src_offset;
++    struct elf_link_hash_entry *dest;
++    bfd_vma                     dest_offset;
++    bfd_vma                     bitmask;
++
++    /* chain */
++    CopyEntry *next;
++};
++
++static void
++prepend (CopyEntry **list, CopyEntry *p)
++{
++    p->next = *list;
++    *list = p;
++}
++
++static int
++copy_entry_equal (const CopyEntry *a, const CopyEntry *b)
++{
++    return (a->src == b->src &&
++            a->src_offset == b->src_offset &&
++            a->dest == b->dest &&
++            a->dest_offset == b->dest_offset &&
++            a->bitmask == b->bitmask);
++}
++
++/*
++ * FIXME - should be a hash lookup / something fast.
++ */
++static CopyEntry *
++find_with_dest (CopyEntry *list,
++                struct elf_link_hash_entry *e)
++{
++    while (list)
++      {
++        if (list->dest == e)
++          break;
++        list = list->next;
++      }
++    return list;
++}
++
++static CopyEntry *
++find_equal_entry (CopyEntry *list, CopyEntry *e)
++{
++  while (list)
++    {
++      if (copy_entry_equal (list, e))
++        break;
++      list = list->next;
++    }
++  return list;
++}
++
++/*
++ * Transfer from unsorted -> sorted.
++ * NB. simple-minded algorithm, N^3 with degenerate case
++ */
++static void
++sort_relocs (VtRelocs *vtr)
++{
++    CopyEntry *p;
++    CopyEntry *pending;
++    CopyEntry *next;
++
++    fprintf (stderr, "Sorting ...");
++    do
++      {
++        pending = NULL;
++        
++        for (p = vtr->unsorted; p; p = next)
++          {
++            next = p->next;
++            if (!find_with_dest (vtr->unsorted, p->src))
++            {
++              /* FIXME: sorting by offset, to ensure as
++                 good as possible contiguous access will
++                 require a more complex node structure:
++                 with aggregation per 'dest', and
++                 internal sorting within that */
++              prepend (&vtr->sorted, p);
++            }
++            else
++              prepend (&pending, p);
++          }
++        vtr->unsorted = pending;
++      }
++    while (pending);
++    fprintf (stderr, " done\n");
++}
++
++static void
++check_reloc (Elf_Internal_Rela *rel, int type_mask)
++{
++  if ((rel->r_info & type_mask) != STT_OBJECT)
++      fprintf (stderr, "broken vtreloc type\n");
++  if (rel->r_addend != 0)
++      fprintf (stderr, "unexpected reloc addend\n");
++}
++
++static void
++print_rel (const char *type, 
++           struct elf_link_hash_entry *target)
++{
++  fprintf (stderr, "%s '%s' %d %d %d %d i:%ld\n",
++           type, target->root.root.string,
++           target->ref_regular, target->def_regular,
++           target->ref_dynamic, target->def_dynamic,
++           target->dynindx);
++}
++
++static void
++add_reloc (VtRelocs *vtr,
++           bfd      *inputobj,
++           Elf_Internal_Rela *src_rel,
++           Elf_Internal_Rela *dest_rel,
++           unsigned char     *data)
++{
++  unsigned r_sym_shift;
++  unsigned r_type_mask;
++  unsigned incr;
++  unsigned symidx;
++  const struct elf_backend_data *bed;
++  struct elf_link_hash_entry *dest, *src;
++  Elf_Internal_Shdr *hdr;
++  CopyEntry *e;
++
++  hdr = &elf_tdata (inputobj)->symtab_hdr;
++  bed = get_elf_backend_data (inputobj);
++  if (bed->s->arch_size == 32)
++    {
++      r_type_mask = 0xff;
++      r_sym_shift = 8;
++      incr = 4;
++    }
++  else
++    {
++      r_type_mask = 0xffffffff;
++      r_sym_shift = 32;
++      incr = 8;
++    }
++
++  check_reloc (src_rel, r_type_mask);
++  check_reloc (dest_rel, r_type_mask);
++
++/*
++#define elf_sym_hashes(bfd)	(elf_tdata(bfd) -> sym_hashes)
++#define elf_tdata(bfd)		((bfd) -> tdata.elf_obj_data)
++  Elf
++  cf. RELOC_FOR_GLOBAL_SYMBOL ...
++*/
++
++  symidx = (dest_rel->r_info >> r_sym_shift);
++  fprintf (stderr, "symidx %d (-%d)!\n", symidx, hdr->sh_info);
++
++  if (symidx < hdr->sh_info) // local symbol ...
++  {
++      fprintf (stderr, "Error/FIXME: local dest symbol !");
++      return;
++  }
++
++  symidx -= hdr->sh_info;
++  dest = elf_sym_hashes (inputobj) [symidx];
++  if (!dest) {
++      fprintf (stderr, "no rel %d!\n", symidx);
++      return;
++  }
++
++  /* Eliminate relocs to no longer present internal vtables. */
++  if (!dest->def_regular)
++    {
++      print_rel ("Abandoning dest", dest);
++      fprintf (stderr, "Ref count %ld %ld dynindx %d\n",
++               dest->got.refcount, dest->plt.refcount,
++               (int) dest->dynindx);
++      /* unref the symbol somehow (!?) */
++      return;
++    }
++
++  // FIXME: do we need something like this for indirect / warnings !?
++/*    while (target->root.type == bfd_link_hash_indirect
++           || target->root.type == bfd_link_hash_warning)
++           target = (struct elf_link_hash_entry *) target->root.u.i.link; */
++  fprintf (stderr, "dest link type %d\n", dest->root.type);
++  if (dest->root.type == bfd_link_hash_undefined ||
++      dest->root.type == bfd_link_hash_undefweak)
++    {
++      fprintf (stderr, "undefined dest sym '%s'\n", dest->root.root.string);
++      return;
++    }
++
++  /* Consider: should we eliminate all internal -> internal
++     copies ? it's possible we are more space / time
++     efficient - so no for now. */
++
++  symidx = (src_rel->r_info >> r_sym_shift);
++  if (symidx < hdr->sh_info) // local symbol ...
++  {
++      fprintf (stderr, "Error/FIXME: local src symbol !");
++      return;
++  }
++  symidx -= hdr->sh_info;
++  src = elf_sym_hashes (inputobj) [symidx];
++  if (src->root.type == bfd_link_hash_undefined ||
++      src->root.type == bfd_link_hash_undefweak)
++    {
++      fprintf (stderr, "undefined src sym '%s'\n", src->root.root.string);
++      return;
++    }
++
++  print_rel ("Src", src);
++  print_rel ("Dst", dest);
++
++  e = bfd_zalloc (vtr->abfd, sizeof (CopyEntry));
++
++  e->src = src;
++  e->dest = dest;
++
++  if (dest_rel->r_offset - src_rel->r_offset != bed->s->arch_size / 8)
++      fprintf (stderr, "Mis-paired vtrelocs\n");
++
++  e->src_offset = bfd_get (bed->s->arch_size, inputobj, data);
++  data += incr;
++  e->dest_offset = bfd_get (bed->s->arch_size, inputobj, data);
++  data += incr;
++  e->bitmask = bfd_get (bed->s->arch_size, inputobj, data);
++
++  /* Simple minded dupliates elision */
++  if (find_equal_entry (vtr->unsorted, e))
++    bfd_release (vtr->abfd, e);          
++  else
++    {
++      prepend (&vtr->unsorted, e);  
++
++      fprintf (stderr, "Copy: '%s'+%d -> '%s'+%d (0x%x)\n",
++               e->src->root.root.string,
++               (int)e->src_offset,
++               e->dest->root.root.string,
++               (int)e->dest_offset,
++               (int)e->bitmask);
++    }
++}
++
++static VtRelocs *global_vtr;
++
++bfd_boolean _bfd_elf_vtreloc_accumulate (bfd *output_bfd,
++                                         struct bfd_link_info *info)
++{
++  bfd *dynobj;
++  dynobj = elf_hash_table (info)->dynobj;
++  if (info->vtreloc)
++    { // .vtrelocs
++      bfd_size_type sec_size = 0;
++      asection *vtreloc_sec;
++      asection *vtrelrel;
++      bfd *inputobj;
++      VtRelocs *vtr;
++      Elf_Internal_Rela last_rela;
++      bfd_size_type num_relocs;
++
++      vtr = bfd_zalloc (output_bfd, sizeof (VtRelocs));
++      vtr->abfd = output_bfd;
++      global_vtr = vtr;
++
++      /* FIXME: we need to elide relocs that turn out
++         to be purely internal:
++         eg. internal -> internal copy src / dest,
++         others are less troublesome - though removing
++         empty ones would be nice (?).
++         We want to trap every -named- reloc ...
++      */
++      for (inputobj = info->input_bfds;
++	   inputobj;
++	   inputobj = inputobj->link_next)
++	{
++	  asection *s;
++          struct bfd_elf_section_data *es; /* elf-bfd.h */
++          unsigned i;
++          Elf_Internal_Rela *relocs, *p;
++          unsigned char *sec_data;
++	  long storage_needed;
++	  asymbol **symtab;
++	  long number_of_symbols;
++	  const struct elf_backend_data *bed = get_elf_backend_data (inputobj);
++
++	  if (inputobj->flags & (DYNAMIC | BFD_LINKER_CREATED))
++	    continue;
++	  s = bfd_get_section_by_name (inputobj, ".vtrelocs");
++          if (!s)
++            continue;
++	  /* XXX Hmm, this seems to generate many NONE relocs, probably from
++	     the original relocs to this section.  Perhaps discard them
++	     earlier.  */
++	  /* FIXME: we really don't want to keep these around, quick hack
++	 *** due to having relocs pointing to these sections */
++	  /*	  s->flags |= SEC_EXCLUDE; */
++          es = elf_section_data (s);
++          if (!es)
++            continue;
++
++          if (!s->reloc_count)
++            continue;
++
++          fprintf (stderr, "Relocs: size %d, count %d contents %p\n",
++                   (int)es->rel_hdr.sh_size, es->rel_count,
++                   s->contents);
++          
++
++          /* Can't find this info anywhere else for some reason: */
++          p = relocs = _bfd_elf_link_read_relocs (inputobj, s, NULL, NULL,
++                                                  info->keep_memory);
++
++	  /* Experimental stuff to get at the BFD relocs (translated back
++	     from the real ELF relocs.  */
++	  storage_needed = bfd_get_symtab_upper_bound (inputobj);
++	  if (storage_needed <= 0)
++	    return FALSE;
++	  symtab = xmalloc (storage_needed);
++	  number_of_symbols = bfd_canonicalize_symtab (inputobj, symtab);
++	  if (number_of_symbols < 0)
++	    return FALSE;
++
++	  if (! bed->s->slurp_reloc_table (inputobj, s, symtab, FALSE))
++	    return FALSE;
++          
++	  /* Now inputobj->relocation will contain BFD relocs.  */
++
++          sec_data = bfd_malloc (es->this_hdr.sh_size);
++          
++          /* Slurp the data */
++          if (bfd_seek (inputobj, es->this_hdr.sh_offset, SEEK_SET) != 0)
++            return FALSE;
++          if (bfd_bread (sec_data, es->this_hdr.sh_size, inputobj) != es->this_hdr.sh_size)
++            return FALSE;
++
++          if (es->this_hdr.sh_size % s->reloc_count != 0)
++              fprintf (stderr, "ERROR: mismatching vtreloc sec & reloc count "
++                       "0x%x, 0x%x -> %d\n",
++                       (int)es->this_hdr.sh_size, (int)s->reloc_count,
++                       (int)es->this_hdr.sh_size % s->reloc_count);
++
++          /* Assumes an even number of relocs sorted by address ... */
++          for (i = 0; i < s->reloc_count / 2; i++)
++          {
++              unsigned int entry_size;
++              entry_size = (get_elf_backend_data (inputobj)->s->arch_size / 8) * 3;
++              
++	      last_rela = *p;
++              add_reloc (vtr, inputobj, p, p + 1,
++                         sec_data + i * entry_size);
++              p+=2;
++          }
++          free (sec_data);
++          if (es->relocs != relocs)
++              free (relocs);
++        }
++
++      /* So - we need to sort these guys as we work out the sizes */
++      /* We need to generate an internal list of XYZ type 
++           + eliminate all external -> external work ... 
++           + add all external -> internal copies to 'sorted' list
++              + [ fool-proof GC roots ]
++           + add other symbols to 'pending' list.
++           + read / generate src: [symbol + offset, dest: sym + offset, bitmask data]
++      */
++      sort_relocs (vtr);
++      num_relocs = 0;
++      sec_size = 0;
++      {
++        CopyEntry *e;
++	for (e = vtr->sorted; e; e = e->next)
++	  {
++	    sec_size += 3;  /* Word entries.  */
++	    num_relocs += 2;
++	  }
++      }
++      /*
++         Finally:
++           + build new custom section
++           + emit new relocations for it ...
++      */
++      
++      vtreloc_sec = bfd_get_section_by_name (dynobj, ".suse.vtrelocs");
++      if (vtreloc_sec)
++        {
++	  bfd_size_type rel_size;
++	  bfd_size_type size;
++	  const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
++	  vtrelrel = bfd_get_section_by_name (dynobj, ".rel.suse.vtrelocs");
++	  if (!vtrelrel)
++	    return FALSE;
++
++          {
++              unsigned int entry_size;
++              entry_size = (bed->s->arch_size / 8);
++              /* + 1 for null termination */
++              vtreloc_sec->size = (sec_size + 1) * entry_size;
++              vtreloc_sec->contents = bfd_zalloc (dynobj, vtreloc_sec->size);
++//	      if (!_bfd_elf_add_dynamic_entry (info, DT_SUSE_VTRELOC, 0))
++//	        return FALSE;
++          }
++
++	  rel_size = bed->s->sizeof_rel;
++	  if (bed->default_use_rela_p)
++	    {
++	      rel_size = bed->s->sizeof_rela;
++	    }
++
++	  size = rel_size * num_relocs;
++	  fprintf (stderr, "Need %ld bytes of relocs rel-size %ld\n",
++                   size, rel_size);
++	  vtrelrel->size = size;
++        }
++      else
++        fprintf (stderr, "Horrendous error ! - no .suse.vtrelocs\n");
++
++    }
++  else
++    {
++      asection *vtreloc_sec;
++      vtreloc_sec = bfd_get_section_by_name (dynobj, ".vtrelocs");
++/*  FIXME - foo !
++	if (vtreloc_sec)
++	      vtreloc_sec->flags |= SEC_EXCLUDE; */
++    }
++  return TRUE;
++}
++
++static void
++generate_reloc (bfd                        *dynobj,
++                struct elf_link_hash_entry *target,
++                asection                   *vtreloc_sec,
++                asection                   *vtrelrel,
++                bfd_vma                     num_entry,
++                int                         is_dest,
++                bfd_size_type              *adjust_relative)
++{
++    bfd_size_type sym_idx, rel_size;
++    reloc_howto_type *howto;
++    void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *);
++    bfd_byte *loc;
++    Elf_Internal_Rela outrel;
++    const struct elf_backend_data *bed;
++
++    bed = get_elf_backend_data (dynobj);
++
++    rel_size = bed->s->sizeof_rel;
++    swap_out = bed->s->swap_reloc_out;
++    if (bed->default_use_rela_p)
++    {
++        rel_size = bed->s->sizeof_rela;
++        swap_out = bed->s->swap_reloca_out;
++    }
++
++    /* XXX: unwind this goodness etc. */
++    while (target->root.type == bfd_link_hash_indirect
++           || target->root.type == bfd_link_hash_warning)
++      target = (struct elf_link_hash_entry *) target->root.u.i.link;
++
++    fprintf (stderr, "Reloc '%s' %d %d %d %d i:%ld ",
++             target->root.root.string,
++             target->ref_regular, target->def_regular,
++             target->ref_dynamic, target->def_dynamic,
++             target->dynindx);
++    if (is_dest /* force relative */ || target->dynindx <= 0)
++      fprintf (stderr, "'%s' vma 0x%lx offset %ld output off %ld\n",
++               target->root.u.def.section->name,
++               target->root.u.def.section->output_section->vma,
++               target->root.u.def.value,
++               target->root.u.def.section->output_offset);
++    else
++      fprintf (stderr, "\n");
++
++    /* XXX: RELOC64 too */
++    if (is_dest /* force relative */ || target->dynindx <= 0)
++      { /* do a relative reloc ... */
++        howto = bfd_reloc_type_lookup (dynobj, BFD_RELOC_386_RELATIVE);
++        sym_idx = 0;
++        BFD_ASSERT (target->root.type == bfd_link_hash_defweak);
++        *adjust_relative = (target->root.u.def.section->output_section->vma +
++                            target->root.u.def.section->output_offset);
++      }
++    else
++      {
++        howto = bfd_reloc_type_lookup (dynobj, BFD_RELOC_32);
++        sym_idx = target->dynindx;
++        *adjust_relative = 0;
++      }
++
++    /* generate relocation */
++    outrel.r_offset = vtreloc_sec->output_section->vma;
++    outrel.r_offset += num_entry * 3 * 4; // XXX: 4 ?
++    if (is_dest) outrel.r_offset += 4; // XXX: 4
++    outrel.r_info = ELF32_R_INFO (sym_idx, howto->type);
++    outrel.r_addend = 0;
++
++    loc = vtrelrel->contents + (vtrelrel->reloc_count++ * rel_size);
++    swap_out (dynobj, &outrel, loc);
++}
++
++bfd_boolean _bfd_elf_vtreloc_fill (bfd *output_bfd,
++                                   struct bfd_link_info *info)
++{
++  bfd *dynobj;
++  dynobj = elf_hash_table (info)->dynobj;
++
++  fprintf (stderr, "Foo: generate .suse.vtrelocs relocs\n");
++
++  if (info->vtreloc)
++    {
++      asection *vtreloc_sec;
++      asection *vtrelrel;
++
++      vtreloc_sec = bfd_get_section_by_name (dynobj, ".suse.vtrelocs");
++      if (vtreloc_sec)
++        {
++	  CopyEntry *e;
++	  bfd_size_type entries, adjust_relative, entry_size;
++	  const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
++          bfd_byte *data;
++
++          entry_size = (bed->s->arch_size / 8);
++
++	  vtrelrel = bfd_get_section_by_name (dynobj, ".rel.suse.vtrelocs");
++	  if (!vtrelrel)
++	    return FALSE;
++	  if (!vtrelrel->contents)
++	    {
++	      fprintf (stderr, "Nothing allocated for relocs\n");
++	      return FALSE;
++	    }
++
++	  BFD_ASSERT (vtreloc_sec->output_offset == 0);
++	  entries = 0;
++	  vtrelrel->reloc_count = 0;
++          data = vtreloc_sec->contents;
++	  for (e = global_vtr->sorted; e; e = e->next)
++	    {
++	      /* Source */
++              generate_reloc (output_bfd, e->src, vtreloc_sec, vtrelrel,
++                              entries, FALSE, &adjust_relative);
++              bfd_put(bed->s->arch_size, output_bfd,
++                      e->src_offset + adjust_relative, data);
++              data += entry_size;
++
++              /* Dest */
++              generate_reloc (output_bfd, e->dest, vtreloc_sec, vtrelrel,
++                              entries, TRUE, &adjust_relative);
++              bfd_put(bed->s->arch_size, output_bfd,
++                      e->dest_offset + adjust_relative, data);
++              data += entry_size;
++
++              bfd_put(bed->s->arch_size, dynobj, e->bitmask, data);
++              data += entry_size;
++
++              entries++;
++            }
++          BFD_ASSERT (vtrelrel->reloc_count * (bed->default_use_rela_p ? bed->s->sizeof_rela : bed->s->sizeof_rel)
++                      == vtrelrel->size);
++        }
++      else
++        fprintf (stderr, "Horrendous error ! - no .suse.vtrelocs\n");
++    }
++  else
++    {
++      asection *vtreloc_sec;
++      fprintf (stderr, "TESTME: exclude .vtrelocs if none present\n");
++      vtreloc_sec = bfd_get_section_by_name (dynobj, ".suse.vtrelocs");
++      if (vtreloc_sec)
++        vtreloc_sec->flags |= SEC_EXCLUDE;
++      vtreloc_sec = bfd_get_section_by_name (dynobj, ".rel.suse.vtrelocs");
++      if (vtreloc_sec)
++        vtreloc_sec->flags |= SEC_EXCLUDE;
++    }
++  return TRUE;
++}

Modified: trunk/patches/test/gcc-vt-copy-2.diff
==============================================================================
--- trunk/patches/test/gcc-vt-copy-2.diff	(original)
+++ trunk/patches/test/gcc-vt-copy-2.diff	Tue Jan 15 17:06:04 2008
@@ -1,3 +1,18 @@
+diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-gcc-4.2.1-simple/gcc/cgraph.c gcc-4.2.1-simple/gcc/cgraph.c
+--- pristine-gcc-4.2.1-simple/gcc/cgraph.c	2007-03-13 10:38:31.000000000 +0000
++++ gcc-4.2.1-simple/gcc/cgraph.c	2008-01-15 16:49:44.000000000 +0000
+@@ -928,6 +928,11 @@
+ void
+ cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
+ {
++  if (getenv ("DEBUG")) {
++    fprintf (stderr, "Mark node '%s' as needed\n",
++	     cgraph_varpool_node_name (node));
++    dump_cgraph_varpool_node (stderr, node);
++  }
+   if (!node->needed && node->finalized
+       && !TREE_ASM_WRITTEN (node->decl))
+     cgraph_varpool_enqueue_needed_node (node);
 diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-gcc-4.2.1-simple/gcc/collect2.c gcc-4.2.1-simple/gcc/collect2.c
 --- pristine-gcc-4.2.1-simple/gcc/collect2.c	2006-12-11 12:18:13.000000000 +0000
 +++ gcc-4.2.1-simple/gcc/collect2.c	2008-01-10 12:20:49.000000000 +0000
@@ -12,7 +27,7 @@
  
 diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-gcc-4.2.1-simple/gcc/cp/class.c gcc-4.2.1-simple/gcc/cp/class.c
 --- pristine-gcc-4.2.1-simple/gcc/cp/class.c	2007-07-05 10:02:39.000000000 +0100
-+++ gcc-4.2.1-simple/gcc/cp/class.c	2008-01-15 13:01:40.000000000 +0000
++++ gcc-4.2.1-simple/gcc/cp/class.c	2008-01-15 16:56:50.000000000 +0000
 @@ -136,7 +136,7 @@
  static tree fixed_type_or_null (tree, int *, int *);
  static tree build_simple_base_path (tree expr, tree binfo);
@@ -37,7 +52,7 @@
  static void clone_constructors_and_destructors (tree);
  static tree build_clone (tree, tree);
  static void update_vtable_entry_for_fn (tree, tree, tree, tree *, unsigned);
-@@ -6355,6 +6355,49 @@
+@@ -6355,6 +6355,51 @@
    return decl;
  }
  
@@ -70,9 +85,11 @@
 +      DECL_IGNORED_P (d) = 1;
 +      TREE_READONLY (d) = 1;
 +      TREE_STATIC (d) = 1;
++      TREE_PUBLIC (d) = 0;
++      DECL_COMDAT (d) = 1;
 +      /* Mark the variable as undefined -- but remember that we can
 +	 define it later if we need to do so.  */
-+      DECL_EXTERNAL (d) = 1;
++      DECL_EXTERNAL (d) = 0;
 +      DECL_NOT_REALLY_EXTERN (d) = 1;
 +      set_linkage_according_to_type (t, d);
 +      pushdecl_top_level_and_finish (d, NULL_TREE);
@@ -87,7 +104,7 @@
  
  /* Returns the binfo for the primary base of BINFO.  If the resulting
     BINFO is a virtual base, and it is inherited elsewhere in the
-@@ -6637,6 +6680,25 @@
+@@ -6637,6 +6682,25 @@
    dump_thunk (stderr, 0, fn);
  }
  
@@ -113,7 +130,7 @@
  /* Virtual function table initialization.  */
  
  /* Create all the necessary vtables for T and its base classes.  */
-@@ -6647,19 +6709,33 @@
+@@ -6647,19 +6711,33 @@
    tree list;
    tree vbase;
  
@@ -149,7 +166,7 @@
      }
  
    if (BINFO_VTABLE (TYPE_BINFO (t)))
-@@ -6676,6 +6752,10 @@
+@@ -6676,6 +6754,10 @@
    layout_vtable_decl (binfo, list_length (inits));
    decl = get_vtbl_decl_for_binfo (binfo);
    initialize_artificial_var (decl, inits);
@@ -160,7 +177,7 @@
    dump_vtable (BINFO_TYPE (binfo), binfo, decl);
  }
  
-@@ -6945,6 +7025,7 @@
+@@ -6945,6 +7027,7 @@
    tree inits;
    tree id;
    tree vbase;
@@ -168,7 +185,7 @@
  
    /* See if we've already created this construction vtable group.  */
    id = mangle_ctor_vtbl_for_type (t, binfo);
-@@ -6955,11 +7036,13 @@
+@@ -6955,11 +7038,13 @@
    /* Build a version of VTBL (with the wrong type) for use in
       constructing the addresses of secondary vtables in the
       construction vtable group.  */
@@ -183,7 +200,7 @@
  
    /* Add the vtables for each of our virtual bases using the vbase in T
       binfo.  */
-@@ -6973,7 +7056,7 @@
+@@ -6973,7 +7058,7 @@
  	continue;
        b = copied_binfo (vbase, binfo);
  
@@ -192,7 +209,7 @@
      }
    inits = TREE_VALUE (list);
  
-@@ -6986,6 +7069,11 @@
+@@ -6986,6 +7071,11 @@
    CLASSTYPE_VTABLES (t) = chainon (CLASSTYPE_VTABLES (t), vtbl);
    initialize_artificial_var (vtbl, inits);
    dump_vtable (t, binfo, vtbl);
@@ -204,7 +221,7 @@
  }
  
  /* Add the vtbl initializers for BINFO (and its bases other than
-@@ -7003,7 +7091,8 @@
+@@ -7003,7 +7093,8 @@
  		       tree orig_binfo,
  		       tree rtti_binfo,
  		       tree t,
@@ -214,7 +231,7 @@
  {
    int i;
    tree base_binfo;
-@@ -7026,7 +7115,7 @@
+@@ -7026,7 +7117,7 @@
    TREE_VALUE (inits)
      = chainon (TREE_VALUE (inits),
  	       dfs_accumulate_vtbl_inits (binfo, orig_binfo,
@@ -223,7 +240,7 @@
  
    /* Walk the BINFO and its bases.  We walk in preorder so that as we
       initialize each vtable we can figure out at what offset the
-@@ -7041,7 +7130,7 @@
+@@ -7041,7 +7132,7 @@
        accumulate_vtbl_inits (base_binfo,
  			     BINFO_BASE_BINFO (orig_binfo, i),
  			     rtti_binfo, t,
@@ -232,7 +249,7 @@
      }
  }
  
-@@ -7053,7 +7142,8 @@
+@@ -7053,7 +7144,8 @@
  			   tree orig_binfo,
  			   tree rtti_binfo,
  			   tree t,
@@ -242,7 +259,7 @@
  {
    tree inits = NULL_TREE;
    tree vtbl = NULL_TREE;
-@@ -7120,7 +7210,7 @@
+@@ -7120,7 +7212,7 @@
  
        /* Compute the initializer for this vtable.  */
        inits = build_vtbl_initializer (binfo, orig_binfo, t, rtti_binfo,
@@ -251,7 +268,7 @@
  
        /* Figure out the position to which the VPTR should point.  */
        vtbl = TREE_PURPOSE (l);
-@@ -7154,6 +7244,40 @@
+@@ -7154,6 +7246,40 @@
    return inits;
  }
  
@@ -292,7 +309,7 @@
  static GTY(()) tree abort_fndecl_addr;
  
  /* Construct the initializer for BINFO's virtual function table.  BINFO
-@@ -7184,7 +7308,8 @@
+@@ -7184,7 +7310,8 @@
  			tree orig_binfo,
  			tree t,
  			tree rtti_binfo,
@@ -302,7 +319,7 @@
  {
    tree v, b;
    tree vfun_inits;
-@@ -7192,6 +7317,8 @@
+@@ -7192,6 +7319,8 @@
    unsigned ix;
    tree vbinfo;
    VEC(tree,gc) *vbases;
@@ -311,7 +328,7 @@
  
    /* Initialize VID.  */
    memset (&vid, 0, sizeof (vid));
-@@ -7213,7 +7340,7 @@
+@@ -7213,7 +7342,7 @@
       signature, we share the vcall offsets.  */
    vid.fns = VEC_alloc (tree, gc, 32);
    /* Add the vcall and vbase offset entries.  */
@@ -320,7 +337,7 @@
  
    /* Clear BINFO_VTABLE_PATH_MARKED; it's set by
       build_vbase_offset_vtbl_entries.  */
-@@ -7240,18 +7367,52 @@
+@@ -7240,18 +7369,52 @@
  	}
      }
  
@@ -374,7 +391,7 @@
  
        fn = BV_FN (v);
        fn_original = fn;
-@@ -7281,7 +7442,10 @@
+@@ -7281,7 +7444,10 @@
  	{
  	  /* We found a defn before a lost primary; go ahead as normal.  */
  	  if (look_for_overrides_here (BINFO_TYPE (b), fn_original))
@@ -386,7 +403,7 @@
  
  	  /* The nearest definition is from a lost primary; clear the
  	     slot.  */
-@@ -7299,6 +7463,9 @@
+@@ -7299,6 +7465,9 @@
  	  delta = BV_DELTA (v);
  	  vcall_index = BV_VCALL_INDEX (v);
  
@@ -396,7 +413,7 @@
  	  gcc_assert (TREE_CODE (delta) == INTEGER_CST);
  	  gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
  
-@@ -7319,9 +7486,40 @@
+@@ -7319,9 +7488,40 @@
  		  if (!DECL_NAME (fn))
  		    finish_thunk (fn);
  		}
@@ -440,7 +457,7 @@
  	    }
  	}
  
-@@ -7346,8 +7544,34 @@
+@@ -7346,8 +7546,34 @@
  	}
        else
  	vfun_inits = tree_cons (NULL_TREE, init, vfun_inits);
@@ -475,7 +492,7 @@
    /* The initializers for virtual functions were built up in reverse
       order; straighten them out now.  */
    vfun_inits = nreverse (vfun_inits);
-@@ -7363,7 +7587,8 @@
+@@ -7363,7 +7589,8 @@
     offsets in BINFO, which is in the hierarchy dominated by T.  */
  
  static void
@@ -485,7 +502,7 @@
  {
    tree b;
  
-@@ -7371,10 +7596,17 @@
+@@ -7371,10 +7598,17 @@
       corresponding to the primary base class.  */
    b = get_primary_binfo (binfo);
    if (b)
@@ -604,7 +621,7 @@
    pop_namespace ();
 diff -u -r -x testsuite -x libjava -x cc-nptl -x build-dir -x '*.orig' -x obj-i586-suse-linux -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' pristine-gcc-4.2.1-simple/gcc/cp/decl2.c gcc-4.2.1-simple/gcc/cp/decl2.c
 --- pristine-gcc-4.2.1-simple/gcc/cp/decl2.c	2007-06-28 14:16:12.000000000 +0100
-+++ gcc-4.2.1-simple/gcc/cp/decl2.c	2008-01-15 13:11:33.000000000 +0000
++++ gcc-4.2.1-simple/gcc/cp/decl2.c	2008-01-15 16:46:07.000000000 +0000
 @@ -1530,6 +1530,26 @@
       info.  */
    note_debug_info_needed (ctype);
@@ -632,7 +649,7 @@
    return true;
  }
  
-@@ -2910,6 +2930,147 @@
+@@ -2910,6 +2930,150 @@
      finish_objects (function_key, priority, body);
  }
  
@@ -760,17 +777,20 @@
 +	if (DECL_NOT_REALLY_EXTERN (decl) && decl_needed_p (decl))
 +	  {
 +	    DECL_EXTERNAL (decl) = 0;
++	    comdat_linkage (decl);
++	    DECL_COMDAT (decl) = 1;
 +	    ctor = build_constructor_from_list (TREE_TYPE (decl), inits);
 +	    initialize_artificial_var (decl, ctor);
-+	    TREE_PUBLIC (decl) = 1;
++	    TREE_PUBLIC (decl) = 0;
 +	    DECL_WEAK (decl) = 1;
 +	    DECL_INTERFACE_KNOWN (decl) = 1;
-+	    mark_used (decl);
++/*	    mark_used (decl); */
 +/*	    rest_of_decl_compilation (decl, 1, 1); */
 +	    finish_decl (decl, ctor, NULL_TREE);
 +
-+	    fprintf (stderr, "Generate vtreloc variable '%s'",
-+		     decl_as_string (decl, TFF_PLAIN_IDENTIFIER));
++	    fprintf (stderr, "Generate vtreloc variable '%s' comdat? %d",
++		     decl_as_string (decl, TFF_PLAIN_IDENTIFIER),
++		     DECL_COMDAT (decl));
 +	  }
 +      }
 +    }
@@ -780,7 +800,7 @@
  /* Generate constructor and destructor functions for the priority
     indicated by N.  */
  
-@@ -3128,11 +3289,15 @@
+@@ -3128,11 +3292,15 @@
  	 get emitted.  */
        for (i = VEC_length (tree, unemitted_tinfo_decls);
  	   VEC_iterate (tree, unemitted_tinfo_decls, --i, t);)
@@ -796,7 +816,7 @@
  
        /* The list of objects with static storage duration is built up
  	 in reverse order.  We clear STATIC_AGGREGATES so that any new
-@@ -3312,6 +3477,9 @@
+@@ -3312,6 +3480,9 @@
  	}
      }
  



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]