ooo-build r11242 - trunk/patches/test
- From: michael svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r11242 - trunk/patches/test
- Date: Thu, 10 Jan 2008 17:50:19 +0000 (GMT)
Author: michael
Date: Thu Jan 10 17:50:19 2008
New Revision: 11242
URL: http://svn.gnome.org/viewvc/ooo-build?rev=11242&view=rev
Log:
more work - finally doing something useful.
Modified:
trunk/patches/test/binutils-vt-copy.diff
trunk/patches/test/gcc-vt-copy.diff
trunk/patches/test/glibc-vt-reloc.diff
Modified: trunk/patches/test/binutils-vt-copy.diff
==============================================================================
--- trunk/patches/test/binutils-vt-copy.diff (original)
+++ trunk/patches/test/binutils-vt-copy.diff Thu Jan 10 17:50:19 2008
@@ -1,5 +1,5 @@
-diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/binutils-2.17.50/bfd/elf-bfd.h binutils-2.17.50/bfd/elf-bfd.h
---- /usr/src/packages/BUILD/binutils-2.17.50/bfd/elf-bfd.h 2007-07-19 09:51:03.000000000 +0100
+diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.17.50/bfd/elf-bfd.h binutils-2.17.50/bfd/elf-bfd.h
+--- binutils-2.17.50/bfd/elf-bfd.h 2007-07-19 09:51:03.000000000 +0100
+++ binutils-2.17.50/bfd/elf-bfd.h 2008-01-09 12:42:12.000000000 +0000
@@ -1787,6 +1787,12 @@
extern void _bfd_elf_init_2_index_sections
@@ -14,8 +14,8 @@
extern bfd_boolean _bfd_elfcore_make_pseudosection
(bfd *, char *, size_t, ufile_ptr);
extern char *_bfd_elfcore_strndup
-diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/binutils-2.17.50/bfd/elf.c binutils-2.17.50/bfd/elf.c
---- /usr/src/packages/BUILD/binutils-2.17.50/bfd/elf.c 2007-07-24 10:50:16.000000000 +0100
+diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.17.50/bfd/elf.c binutils-2.17.50/bfd/elf.c
+--- binutils-2.17.50/bfd/elf.c 2007-07-24 10:50:16.000000000 +0100
+++ binutils-2.17.50/bfd/elf.c 2008-01-09 12:44:13.000000000 +0000
@@ -1240,6 +1240,7 @@
case DT_USED: name = "USED"; break;
@@ -25,8 +25,8 @@
}
fprintf (f, " %-11s ", name);
-diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/binutils-2.17.50/bfd/elflink.c binutils-2.17.50/bfd/elflink.c
---- /usr/src/packages/BUILD/binutils-2.17.50/bfd/elflink.c 2007-07-25 09:33:23.000000000 +0100
+diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.17.50/bfd/elflink.c binutils-2.17.50/bfd/elflink.c
+--- binutils-2.17.50/bfd/elflink.c 2007-07-25 09:33:23.000000000 +0100
+++ binutils-2.17.50/bfd/elflink.c 2008-01-09 12:46:24.000000000 +0000
@@ -148,6 +148,34 @@
return TRUE;
@@ -189,7 +189,7 @@
name = ".gnu.version_r";
goto get_vma;
+ case DT_SUSE_VTRELOC:
-+ name = ".suse.vtreloc";
++ name = ".suse.vtrelocs";
+ goto get_vma;
case DT_VERSYM:
name = ".gnu.version";
@@ -203,8 +203,8 @@
sec->gc_mark = 1;
/* Mark all the sections in the group. */
-diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/binutils-2.17.50/include/bfdlink.h binutils-2.17.50/include/bfdlink.h
---- /usr/src/packages/BUILD/binutils-2.17.50/include/bfdlink.h 2007-07-10 12:10:44.000000000 +0100
+diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.17.50/include/bfdlink.h binutils-2.17.50/include/bfdlink.h
+--- binutils-2.17.50/include/bfdlink.h 2007-07-10 12:10:44.000000000 +0100
+++ binutils-2.17.50/include/bfdlink.h 2008-01-09 12:42:12.000000000 +0000
@@ -293,6 +293,10 @@
/* TRUE if the new ELF dynamic tags are enabled. */
@@ -217,8 +217,8 @@
/* 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 cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/binutils-2.17.50/include/elf/common.h binutils-2.17.50/include/elf/common.h
---- /usr/src/packages/BUILD/binutils-2.17.50/include/elf/common.h 2007-07-10 12:10:44.000000000 +0100
+diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.17.50/include/elf/common.h binutils-2.17.50/include/elf/common.h
+--- binutils-2.17.50/include/elf/common.h 2007-07-10 12:10:44.000000000 +0100
+++ binutils-2.17.50/include/elf/common.h 2008-01-09 13:19:01.000000000 +0000
@@ -624,6 +624,13 @@
#define DT_USED 0x7ffffffe
@@ -234,8 +234,8 @@
/* Values used in DT_FEATURE .dynamic entry. */
#define DTF_1_PARINIT 0x00000001
-diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/binutils-2.17.50/ld/ldmain.c binutils-2.17.50/ld/ldmain.c
---- /usr/src/packages/BUILD/binutils-2.17.50/ld/ldmain.c 2008-01-09 11:23:41.000000000 +0000
+diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.17.50/ld/ldmain.c binutils-2.17.50/ld/ldmain.c
+--- binutils-2.17.50/ld/ldmain.c 2008-01-09 11:23:41.000000000 +0000
+++ binutils-2.17.50/ld/ldmain.c 2008-01-09 12:42:11.000000000 +0000
@@ -1105,6 +1105,7 @@
asection *section,
@@ -245,8 +245,8 @@
if (config.warn_constructors)
einfo (_("%P: warning: global constructor %s used\n"),
h->root.string);
-diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/binutils-2.17.50/ld/lexsup.c binutils-2.17.50/ld/lexsup.c
---- /usr/src/packages/BUILD/binutils-2.17.50/ld/lexsup.c 2008-01-09 11:23:41.000000000 +0000
+diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.17.50/ld/lexsup.c binutils-2.17.50/ld/lexsup.c
+--- binutils-2.17.50/ld/lexsup.c 2008-01-09 11:23:41.000000000 +0000
+++ binutils-2.17.50/ld/lexsup.c 2008-01-09 12:42:11.000000000 +0000
@@ -157,6 +157,7 @@
OPTION_ACCEPT_UNKNOWN_INPUT_ARCH,
@@ -275,8 +275,8 @@
case OPTION_SECTION_START:
{
char *optarg2;
-diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/binutils-2.17.50/ld/scripttempl/elf.sc binutils-2.17.50/ld/scripttempl/elf.sc
---- /usr/src/packages/BUILD/binutils-2.17.50/ld/scripttempl/elf.sc 2007-07-10 12:10:44.000000000 +0100
+diff -u -r -x cc-nptl -x build-dir -x '*.orig' -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.17.50/ld/scripttempl/elf.sc binutils-2.17.50/ld/scripttempl/elf.sc
+--- binutils-2.17.50/ld/scripttempl/elf.sc 2007-07-10 12:10:44.000000000 +0100
+++ binutils-2.17.50/ld/scripttempl/elf.sc 2008-01-09 12:42:12.000000000 +0000
@@ -285,6 +285,7 @@
eval $COMBRELOCCAT <<EOF
@@ -309,3 +309,1440 @@
${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-10 15:52:00.000000000 +0000
+@@ -0,0 +1,552 @@
++#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);
++
++ symidx = (dest_rel->r_info >> r_sym_shift) - hdr->sh_info;
++ fprintf (stderr, "symidx %d!\n", symidx);
++ 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;
++ }
++
++ /* 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) - hdr->sh_info;
++ src = elf_sym_hashes (inputobj) [symidx];
++
++ 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. */
++ 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\n");
++
++ /* 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;
++ fprintf (stderr, "TESTME: exclude .vtrelocs if none present\n");
++ vtreloc_sec = bfd_get_section_by_name (dynobj, ".vtrelocs");
++ 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' /usr/src/packages/BUILD/binutils-2.17.50/bfd/elf-bfd.h binutils-2.17.50/bfd/elf-bfd.h
+--- /usr/src/packages/BUILD/binutils-2.17.50/bfd/elf-bfd.h 2007-07-19 09:51:03.000000000 +0100
++++ 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' /usr/src/packages/BUILD/binutils-2.17.50/bfd/elf.c binutils-2.17.50/bfd/elf.c
+--- /usr/src/packages/BUILD/binutils-2.17.50/bfd/elf.c 2007-07-24 10:50:16.000000000 +0100
++++ 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' /usr/src/packages/BUILD/binutils-2.17.50/bfd/elflink.c binutils-2.17.50/bfd/elflink.c
+--- /usr/src/packages/BUILD/binutils-2.17.50/bfd/elflink.c 2007-07-25 09:33:23.000000000 +0100
++++ binutils-2.17.50/bfd/elflink.c 2008-01-10 15:54:03.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,24 @@
+ 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;
++ }
++ vtrel_sec->flags |= SEC_EXCLUDE;
++ }
++ }
+ else
+ {
+ dynamic = TRUE;
+@@ -3603,6 +3649,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 +5025,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 +5425,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 +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
+@@ -7159,6 +7221,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 +7966,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 +10104,7 @@
+ finfo.dynsym_sec = NULL;
+ finfo.hash_sec = NULL;
+ finfo.symver_sec = NULL;
++ finfo.vtreloc_sec = NULL;
+ }
+ else
+ {
+@@ -10045,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. */
+ }
+
+@@ -10104,6 +10172,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 +10804,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 +10945,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 +11210,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' /usr/src/packages/BUILD/binutils-2.17.50/include/bfdlink.h binutils-2.17.50/include/bfdlink.h
+--- /usr/src/packages/BUILD/binutils-2.17.50/include/bfdlink.h 2007-07-10 12:10:44.000000000 +0100
++++ 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' /usr/src/packages/BUILD/binutils-2.17.50/include/elf/common.h binutils-2.17.50/include/elf/common.h
+--- /usr/src/packages/BUILD/binutils-2.17.50/include/elf/common.h 2007-07-10 12:10:44.000000000 +0100
++++ 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' /usr/src/packages/BUILD/binutils-2.17.50/ld/ldmain.c binutils-2.17.50/ld/ldmain.c
+--- /usr/src/packages/BUILD/binutils-2.17.50/ld/ldmain.c 2008-01-09 11:23:41.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' /usr/src/packages/BUILD/binutils-2.17.50/ld/lexsup.c binutils-2.17.50/ld/lexsup.c
+--- /usr/src/packages/BUILD/binutils-2.17.50/ld/lexsup.c 2008-01-09 11:23:41.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' /usr/src/packages/BUILD/binutils-2.17.50/ld/scripttempl/elf.sc binutils-2.17.50/ld/scripttempl/elf.sc
+--- /usr/src/packages/BUILD/binutils-2.17.50/ld/scripttempl/elf.sc 2007-07-10 12:10:44.000000000 +0100
++++ binutils-2.17.50/ld/scripttempl/elf.sc 2008-01-09 17:04:17.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,13 @@
+ ${SMALL_DATA_DTOR-${RELOCATING+${DTOR}}}
+ .jcr ${RELOCATING-0} : { KEEP (*(.jcr)) }
+
++ /* Virtual table copy relocation tables */
++ __vtrelocs = .;
++ .suse.vtrelocs :
++ {
++ KEEP (*(.suse.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-10 15:52:00.000000000 +0000
+@@ -0,0 +1,552 @@
++#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);
++
++ symidx = (dest_rel->r_info >> r_sym_shift) - hdr->sh_info;
++ fprintf (stderr, "symidx %d!\n", symidx);
++ 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;
++ }
++
++ /* 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) - hdr->sh_info;
++ src = elf_sym_hashes (inputobj) [symidx];
++
++ 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. */
++ 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\n");
++
++ /* 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;
++ fprintf (stderr, "TESTME: exclude .vtrelocs if none present\n");
++ vtreloc_sec = bfd_get_section_by_name (dynobj, ".vtrelocs");
++ 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.diff
==============================================================================
--- trunk/patches/test/gcc-vt-copy.diff (original)
+++ trunk/patches/test/gcc-vt-copy.diff Thu Jan 10 17:50:19 2008
@@ -696,114 +696,6 @@
/* We give C linkage to static constructors and destructors. */
push_lang_context (lang_name_c);
-diff -u -r -x testsuite -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' gcc-4.2.1-20070724/gcc/crtstuff.c gcc-4.2.1-20070724/gcc/crtstuff.c
---- gcc-4.2.1-20070724/gcc/crtstuff.c 2006-12-11 12:18:13.000000000 +0000
-+++ gcc-4.2.1-20070724/gcc/crtstuff.c 2008-01-09 16:01:54.000000000 +0000
-@@ -1,3 +1,9 @@
-+#undef MEEKS
-+#ifdef MEEKS
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <sys/mman.h>
-+#endif
- /* Specialized bits of code needed to support construction and
- destruction of file-scope objects in C++ code.
- Copyright (C) 1991, 1994, 1995, 1996, 1997, 1998,
-@@ -154,6 +160,17 @@
-
- #endif /* OBJECT_FORMAT_ELF */
-
-+
-+#ifdef MEEKS
-+typedef struct {
-+ void *src_pos;
-+ void *dest_pos;
-+ unsigned long bitmap;
-+} VtRelEntry;
-+
-+VtRelEntry *__vtrelocs __attribute__ ((weak)) __attribute__ ((__visibility__ ("hidden"))) = 0;
-+#endif
-+
- #ifdef CRT_BEGIN
-
- /* NOTE: In order to be able to support SVR4 shared libraries, we arrange
-@@ -516,6 +533,64 @@
- static void __attribute__((used))
- __do_global_ctors_aux (void)
- {
-+#ifdef MEEKS
-+#warning "Foo"
-+ {
-+ fprintf (stderr, "Check weak %p, %p!\n",
-+ __vtrelocs, &__vtrelocs);
-+ if (__vtrelocs && getenv("DO_VTLINK"))
-+ {
-+ VtRelEntry *p;
-+ unsigned long pagesize;
-+ unsigned long last_addr = 0;
-+ int debug_output = 0;
-+
-+ debug_output = getenv ("DO_VTLINK_DEBUG") != NULL;
-+
-+ pagesize = sysconf (_SC_PAGESIZE);
-+ for (p = &__vtrelocs; p && p->src_pos; p++)
-+ {
-+ fprintf (stderr, "Copy: %p -> %p, (0x%x)\n",
-+ p->src_pos, p->dest_pos, p->bitmap);
-+ unsigned long mask;
-+ void **src = p->src_pos;
-+ void **dest = p->dest_pos;
-+
-+ { /* ug ! */
-+ long addr = (long)dest;
-+ addr -= addr % pagesize;
-+ if (last_addr != addr)
-+ mprotect (addr, pagesize + 256, PROT_READ|PROT_WRITE|PROT_EXEC);
-+ last_addr = addr;
-+ }
-+
-+ for (mask = p->bitmap; mask; mask >>= 1)
-+ {
-+#ifdef DEBUG_ONLY
-+ fprintf (stderr, "%s copy [&%p -> &%p]\n",
-+ mask & 1 ? "do" : "no", src, dest);
-+#else
-+ if (mask & 1)
-+ {
-+ if (debug_output || !(*src == *dest || *dest == 0xdeadbeef))
-+ {
-+ fprintf (stderr, "do copy %10p to %10p %s [&%p -> &%p]\n",
-+ *src, *dest,
-+ *src == *dest || *dest == 0xdeadbeef ? "match" : "Bug !",
-+ src, dest);
-+ }
-+ *dest = *src;
-+ }
-+ else if (debug_output)
-+ fprintf (stderr, "no copy %10p to %10p %s\n",
-+ *src, *dest, *src == *dest && (int)*src > 0x100 ? "Bug !" : "skip");
-+#endif
-+ dest++; src++;
-+ }
-+ }
-+ }
-+ }
-+#endif
- func_ptr *p;
- for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--)
- (*p) ();
-diff -u -r -x testsuite -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' gcc-4.2.1-20070724/gcc/gcc.c gcc-4.2.1-20070724/gcc/gcc.c
---- gcc-4.2.1-20070724/gcc/gcc.c 2007-03-13 10:38:40.000000000 +0000
-+++ gcc-4.2.1-20070724/gcc/gcc.c 2008-01-09 15:26:55.000000000 +0000
-@@ -4594,6 +4594,8 @@
- const char *string;
- int value;
-
-+// fprintf (stderr, "do_spec_1 '%s'\n", spec);
-+
- while ((c = *p++))
- /* If substituting a switch, treat all chars like letters.
- Otherwise, NL, SPC, TAB and % are special. */
diff -u -r -x testsuite -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' gcc-4.2.1-20070724/gcc/tree.h gcc-4.2.1-20070724/gcc/tree.h
--- gcc-4.2.1-20070724/gcc/tree.h 2008-01-09 12:33:14.000000000 +0000
+++ gcc-4.2.1-20070724/gcc/tree.h 2008-01-09 15:27:54.000000000 +0000
@@ -825,18 +717,3 @@
/* In a VAR_DECL, nonzero if the decl is a register variable with
an explicit asm specification. */
#define DECL_HARD_REGISTER(NODE) (VAR_DECL_CHECK (NODE)->decl_with_vis.hard_register)
-diff -u -r -x testsuite -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' gcc-4.2.1-20070724/gcc/varasm.c gcc-4.2.1-20070724/gcc/varasm.c
---- gcc-4.2.1-20070724/gcc/varasm.c 2008-01-09 12:33:13.000000000 +0000
-+++ gcc-4.2.1-20070724/gcc/varasm.c 2008-01-09 15:26:55.000000000 +0000
-@@ -1795,6 +1795,11 @@
- if (flag_syntax_only)
- return;
-
-+ if (DECL_VTRELOC_INIT (decl))
-+ {
-+ /* FIXME: in fact not needed: remove me ... */
-+ }
-+
- app_disable ();
-
- if (! dont_output_data
Modified: trunk/patches/test/glibc-vt-reloc.diff
==============================================================================
--- trunk/patches/test/glibc-vt-reloc.diff (original)
+++ trunk/patches/test/glibc-vt-reloc.diff Thu Jan 10 17:50:19 2008
@@ -1,6 +1,6 @@
-diff -u -r -x cc-nptl -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/glibc-2.6.1/elf/dl-reloc.c glibc-2.6.1/elf/dl-reloc.c
+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' /usr/src/packages/BUILD/glibc-2.6.1/elf/dl-reloc.c glibc-2.6.1/elf/dl-reloc.c
--- /usr/src/packages/BUILD/glibc-2.6.1/elf/dl-reloc.c 2007-05-18 09:37:39.000000000 +0100
-+++ glibc-2.6.1/elf/dl-reloc.c 2008-01-09 12:30:34.000000000 +0000
++++ glibc-2.6.1/elf/dl-reloc.c 2008-01-10 17:49:56.000000000 +0000
@@ -27,6 +27,9 @@
#include <sys/types.h>
#include "dynamic-link.h"
@@ -11,7 +11,7 @@
/* Statistics function. */
#ifdef SHARED
# define bump_num_cache_relocations() ++GL(dl_num_cache_relocations)
-@@ -133,6 +136,25 @@
+@@ -133,6 +136,85 @@
'\0', map->l_tls_blocksize - map->l_tls_initimage_size);
}
@@ -19,25 +19,85 @@
+static void
+_dl_perform_vtrelocs (struct link_map *map, struct r_scope_elem *scope[])
+{
-+ u_int32_t *ptr;
++ ElfW(VtReloc) *rel;
++ int debug_output = GLRO(dl_debug_mask) & DL_DEBUG_RELOC;
++ int i;
+
-+ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_RELOC, 0))
-+ _dl_debug_printf ("new vtcopy-reloc processing\n");
++ if (debug_output)
++ _dl_debug_printf ("new vtcopy-reloc processing on '%s'\n", map->l_name);
+
-+ ptr = map->l_info[SUSEIDX(DT_SUSE_VTRELOC)];
-+ if (ptr == NULL) {
-+ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_RELOC, 0))
-+ _dl_debug_printf ("no vtreloc section in '%s'\n", map->l_name);
++ {
++ ElfW(Dyn) *item;
++ _dl_debug_printf ("fidx 0x%x\n", SUSEIDX(DT_SUSE_VTRELOC));
++ _dl_debug_printf ("in size 0x%x\n", sizeof (map->l_info) / sizeof(map->l_info[0]));
++ item = map->l_info[DT_STRTAB]; /* SUSEIDX(DT_SUSE_VTRELOC)]; */
++ _dl_debug_printf ("bits: 0x%x\n", item->d_tag);
++ _dl_debug_printf ("bits2: 0x%x\n", item->d_un.d_val);
++ _dl_debug_printf ("bits3: 0x%x\n", item->d_un.d_ptr);
++ item = map->l_info[SUSEIDX(DT_SUSE_VTRELOC)];
++ _dl_debug_printf ("vtreloc item: 0x%x\n", item);
++ if (!item)
++ return;
++ }
++
++#define TSTFOO_PTR(map, i) (map)->i->d_un.d_ptr
++ rel = (ElfW(VtReloc) *)(TSTFOO_PTR (map, l_info[SUSEIDX(DT_SUSE_VTRELOC)]));
++ _dl_debug_printf ("got d_ptr\n");
++ if (rel == NULL)
++ {
++ if (debug_output)
++ _dl_debug_printf ("no vtreloc section in '%s'\n", map->l_name);
+ return;
++ }
++ {
++ ElfW(Addr) p = map->l_info[DT_PLTGOT];
++ _dl_debug_printf ("pltgot at 0x%x (0x%x)\n", p, p - map->l_addr);
++ }
++ {
++ ElfW(Addr) p = map->l_info[DT_HASH];
++ _dl_debug_printf ("hash at 0x%x (0x%x)\n", p, p - map->l_addr);
+ }
-+ if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_RELOC, 0))
-+ _dl_debug_printf ("vtreloc section found in '%s' at %p (%p)\n",
-+ map->l_name, ptr, (ptr - map->l_addr));
++ _dl_debug_printf ("vtreloc section found in '%s' at 0x%x (0x%x) mapped at 0x%x\n",
++ map->l_name, rel, ((ElfW(Addr))rel - map->l_addr),
++ map->l_addr);
++ for (i = 0; i < 64; i++)
++ _dl_debug_printf ("0x%x: 0x%x\n", (int)&((unsigned char *)rel)[i],
++ ((unsigned char *)rel)[i]);
++ while (rel->r_src != 0)
++ {
++ ElfW(Addr) **src, **dest;
++ ElfW(Word) mask;
++
++ src = (void *)rel->r_src;
++ dest = (void *)rel->r_dest;
++ _dl_debug_printf ("copy from 0x%x to 0x%x mask 0x%x\n", src, dest, rel->r_mask);
++
++ for (mask = rel->r_mask; mask; mask >>= 1)
++ {
++ _dl_debug_printf ("%s copy [&0x%x -> &0x%x]\n",
++ mask & 1 ? "do" : "no", src, dest);
++ if (mask & 1)
++ {
++ if (debug_output || !(*src == *dest || *dest == (ElfW(Addr) *)0xdeadbeef))
++ {
++ _dl_debug_printf ("do copy 0x%x to 0x%x %s [&0x%x -> &0x%x]\n",
++ *src, *dest,
++ *src == *dest || *dest == (ElfW(Addr) *)0xdeadbeef ? "match" : "Bug",
++ src, dest);
++ }
++ *dest = *src;
++ }
++ else if (debug_output)
++ _dl_debug_printf ("no copy 0x%x to 0x%x %s\n",
++ *src, *dest, *src == *dest && (int)*src > 0x100 ? "Bug" : "skip");
++ dest++; src++;
++ }
++ }
+}
void
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
-@@ -293,6 +315,8 @@
+@@ -293,6 +375,8 @@
#endif
}
@@ -46,9 +106,9 @@
/* Mark the object so we know this work has been done. */
l->l_relocated = 1;
-diff -u -r -x cc-nptl -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/glibc-2.6.1/elf/dynamic-link.h glibc-2.6.1/elf/dynamic-link.h
+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' /usr/src/packages/BUILD/glibc-2.6.1/elf/dynamic-link.h glibc-2.6.1/elf/dynamic-link.h
--- /usr/src/packages/BUILD/glibc-2.6.1/elf/dynamic-link.h 2006-07-10 22:52:18.000000000 +0100
-+++ glibc-2.6.1/elf/dynamic-link.h 2008-01-09 12:19:55.000000000 +0000
++++ glibc-2.6.1/elf/dynamic-link.h 2008-01-10 17:45:16.000000000 +0000
@@ -65,6 +65,10 @@
#ifndef VERSYMIDX
# define VERSYMIDX(sym) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (sym))
@@ -60,17 +120,28 @@
/* Read the dynamic section at DYN and fill in INFO with indices DT_*. */
-@@ -104,6 +108,9 @@
- else if ((Elf32_Word) DT_ADDRTAGIDX (dyn->d_tag) < DT_ADDRNUM)
- info[DT_ADDRTAGIDX (dyn->d_tag) + DT_NUM + DT_THISPROCNUM
- + DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM] = dyn;
-+ else if (dyn->d_tag >= DT_SUSE_LO &&
-+ dyn->d_tag < DT_SUSE_LO + DT_SUSENUM)
-+ info[SUSEIDX(dyn->d_tag)] = dyn;
- ++dyn;
- }
+@@ -86,8 +90,20 @@
+
+ info = l->l_info;
-@@ -143,6 +150,7 @@
++ _dl_debug_printf ("Name '%s'\n", l->l_name ? l->l_name : "<noname>");
++ info[SUSEIDX(DT_SUSE_VTRELOC)] = 0;
++
+ while (dyn->d_tag != DT_NULL)
+ {
++ if (dyn->d_tag >= DT_SUSE_LO &&
++ dyn->d_tag < DT_SUSE_LO + DT_SUSENUM)
++ {
++ _dl_debug_printf ("assign at fidx 0x%x (0x%x)\n", SUSEIDX(dyn->d_tag), dyn);
++ info[SUSEIDX(dyn->d_tag)] = dyn;
++ } else
++ _dl_debug_printf ("tag 0x%x not >= 0x%x and < 0x%x\n",
++ dyn->d_tag, DT_SUSE_LO, DT_SUSE_LO + DT_SUSENUM);
++
+ if (dyn->d_tag < DT_NUM)
+ info[dyn->d_tag] = dyn;
+ else if (dyn->d_tag >= DT_LOPROC &&
+@@ -143,6 +159,7 @@
# endif
ADJUST_DYN_INFO (DT_JMPREL);
ADJUST_DYN_INFO (VERSYMIDX (DT_VERSYM));
@@ -78,16 +149,39 @@
ADJUST_DYN_INFO (DT_ADDRTAGIDX (DT_GNU_HASH) + DT_NUM + DT_THISPROCNUM
+ DT_VERSIONTAGNUM + DT_EXTRANUM + DT_VALNUM);
# undef ADJUST_DYN_INFO
-diff -u -r -x cc-nptl -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/glibc-2.6.1/elf/elf.h glibc-2.6.1/elf/elf.h
+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' /usr/src/packages/BUILD/glibc-2.6.1/elf/elf.h glibc-2.6.1/elf/elf.h
--- /usr/src/packages/BUILD/glibc-2.6.1/elf/elf.h 2007-05-18 09:37:39.000000000 +0100
-+++ glibc-2.6.1/elf/elf.h 2008-01-09 12:28:45.000000000 +0000
-@@ -734,6 +734,14 @@
++++ glibc-2.6.1/elf/elf.h 2008-01-09 16:43:02.000000000 +0000
+@@ -518,6 +518,22 @@
+ Elf64_Sxword r_addend; /* Addend */
+ } Elf64_Rela;
+
++/* VTable relocation entry */
++
++typedef struct
++{
++ Elf32_Addr r_src; /* source address */
++ Elf32_Addr r_dest; /* destination address */
++ Elf32_Word r_mask; /* copy bit-mask */
++} Elf32_VtReloc;
++
++typedef struct
++{
++ Elf64_Addr r_src; /* source address */
++ Elf64_Addr r_dest; /* destination address */
++ Elf64_Word r_mask; /* copy bit-mask */
++} Elf64_VtReloc;
++
+ /* How to extract and insert information held in the r_info field. */
+
+ #define ELF32_R_SYM(val) ((val) >> 8)
+@@ -734,6 +750,14 @@
#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
#define DT_VERSIONTAGNUM 16
+/* 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_LO (0x6cbdd030 + 2)
+#define DT_SUSE_VTRELOC DT_SUSE_LO
+#define DT_SUSE_HI 0x6cbdd040
+#define DT_SUSE_TAGIDX(tag) (tag - DT_SUSE_LO)
@@ -96,9 +190,9 @@
/* Sun added these machine-independent extensions in the "processor-specific"
range. Be compatible. */
#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */
-diff -u -r -x cc-nptl -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' /usr/src/packages/BUILD/glibc-2.6.1/include/link.h glibc-2.6.1/include/link.h
+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' /usr/src/packages/BUILD/glibc-2.6.1/include/link.h glibc-2.6.1/include/link.h
--- /usr/src/packages/BUILD/glibc-2.6.1/include/link.h 2007-08-03 14:57:06.000000000 +0100
-+++ glibc-2.6.1/include/link.h 2008-01-09 12:30:17.000000000 +0000
++++ glibc-2.6.1/include/link.h 2008-01-09 16:43:02.000000000 +0000
@@ -121,7 +121,7 @@
are indexed by DT_ADDRTAGIDX(tagvalue), see <elf.h>. */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]