ooo-build r11272 - trunk/patches/test
- From: michael svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r11272 - trunk/patches/test
- Date: Tue, 15 Jan 2008 17:06:04 +0000 (GMT)
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]