ooo-build r11255 - trunk/patches/test
- From: michael svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r11255 - trunk/patches/test
- Date: Mon, 14 Jan 2008 16:06:10 +0000 (GMT)
Author: michael
Date: Mon Jan 14 16:06:09 2008
New Revision: 11255
URL: http://svn.gnome.org/viewvc/ooo-build?rev=11255&view=rev
Log:
more work.
Modified:
trunk/patches/test/binutils-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 Mon Jan 14 16:06:09 2008
@@ -1,6 +1,600 @@
-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
+0a1,593
+> #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. */
+> 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");
+> 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-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 *);
@@ -14,434 +608,140 @@
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' 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;
- 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 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;
- }
-
-+static int
-+_bfd_elf_create_vtreloc_sections (struct bfd_link_info *info)
-+{
-+ bfd *abfd;
-+ asection *s;
-+ flagword flags;
-+ const struct elf_backend_data *bed;
+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-14 15:07:15.000000000 +0000
+@@ -0,0 +1,593 @@
++#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"
+
-+ abfd = elf_hash_table (info)->dynobj;
-+ bed = get_elf_backend_data (abfd);
-+ flags = bed->dynamic_sec_flags;
++typedef struct _CopyEntry CopyEntry;
+
-+ 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;
++typedef struct {
++ bfd *abfd;
++ CopyEntry *sorted;
++ CopyEntry *unsorted;
++} VtRelocs;
+
-+ return TRUE;
++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;
+}
+
- /* 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;
++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);
++}
+
- dynamic = FALSE;
++/*
++ * 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;
++}
+
-+ vtrel_sec = bfd_get_section_by_name (abfd, ".vtrelocs");
-+ if (vtrel_sec)
++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
+ {
-+ fprintf (stderr, "Has vtrelocs ! %d\n", (int)vtrel_sec->size);
-+ if (!info->vtreloc)
++ pending = NULL;
++
++ for (p = vtr->unsorted; p; p = next)
+ {
-+ info->vtreloc = 1;
-+ if (!_bfd_elf_create_vtreloc_sections (info))
-+ goto error_return;
++ 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);
+ }
-+ vtrel_sec->flags |= SEC_EXCLUDE;
++ vtr->unsorted = pending;
+ }
-+ }
- 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
-@@ -7159,6 +7214,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 +7959,8 @@
- bfd_vma r_type_mask;
- int r_sym_shift;
-
-+ fprintf (stderr, "elf_link_adjust_relocs ... %p\n", rel_hash);
++ while (pending);
++ fprintf (stderr, " done\n");
++}
+
- if (rel_hdr->sh_entsize == bed->s->sizeof_rel)
- {
- swap_in = bed->s->swap_reloc_in;
-@@ -10038,6 +10097,7 @@
- finfo.dynsym_sec = NULL;
- finfo.hash_sec = NULL;
- finfo.symver_sec = NULL;
-+ finfo.vtreloc_sec = NULL;
- }
- else
- {
-@@ -10045,6 +10105,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 +10165,10 @@
- max_sym_count = 0;
- max_sym_shndx_count = 0;
- merged = FALSE;
++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");
++}
+
-+ 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 +10797,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 +10938,9 @@
- case DT_VERNEED:
- name = ".gnu.version_r";
- goto get_vma;
-+ case DT_SUSE_VTRELOC:
-+ name = ".suse.vtrelocs";
-+ goto get_vma;
- case DT_VERSYM:
- name = ".gnu.version";
- get_vma:
-@@ -11129,6 +11201,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 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. */
- 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 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
- #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 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,
- 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 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,
- 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 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
- .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
++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,
@@ -477,10 +777,24 @@
+ 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];
++/*
++#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;
@@ -497,12 +811,36 @@
+ return;
+ }
+
-+ /* Consider: should we eliminate all internal -> internal
-+ copies ? it's possible we are more space / time
-+ efficient - so no for now. */
++ // 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) - hdr->sh_info;
++ 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);
@@ -628,7 +966,10 @@
+ return FALSE;
+
+ if (es->this_hdr.sh_size % s->reloc_count != 0)
-+ fprintf (stderr, "ERROR: mismatching vtreloc sec & reloc count\n");
++ 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++)
@@ -645,6 +986,7 @@
+ 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 ...
@@ -708,7 +1050,6 @@
+ 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;
@@ -864,24 +1205,8 @@
+ }
+ 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
+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;
@@ -891,9 +1216,9 @@
}
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
+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-14 14:28:26.000000000 +0000
@@ -148,6 +148,34 @@
return TRUE;
}
@@ -1085,8 +1410,27 @@
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
+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-09 17:04:17.000000000 +0000
+@@ -10097,6 +10097,7 @@
+ finfo.dynsym_sec = NULL;
+ finfo.hash_sec = NULL;
+ finfo.symver_sec = NULL;
++ finfo.vtreloc_sec = NULL;
+ }
+ else
+ {
+@@ -10104,6 +10105,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. */
+ }
+
+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. */
@@ -1099,8 +1443,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 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
+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
@@ -1116,8 +1460,8 @@
/* 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
+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,
@@ -1127,8 +1471,8 @@
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
+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,
@@ -1157,8 +1501,8 @@
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
+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-09 17:04:17.000000000 +0000
@@ -285,6 +285,7 @@
eval $COMBRELOCCAT <<EOF
@@ -1191,558 +1535,3 @@
${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/glibc-vt-reloc.diff
==============================================================================
--- trunk/patches/test/glibc-vt-reloc.diff (original)
+++ trunk/patches/test/glibc-vt-reloc.diff Mon Jan 14 16:06:09 2008
@@ -1,5 +1,5 @@
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-load.c glibc-2.6.1/elf/dl-load.c
---- /usr/src/packages/BUILD/glibc-2.6.1/elf/dl-load.c 2008-01-08 20:45:11.000000000 +0000
+--- glibc-2.6.1/elf/dl-load.c 2008-01-08 20:45:11.000000000 +0000el
+++ glibc-2.6.1/elf/dl-load.c 2008-01-11 15:23:16.000000000 +0000
@@ -1200,9 +1200,13 @@
@@ -16,9 +16,9 @@
if (__builtin_expect ((void *) l->l_map_start == MAP_FAILED, 0))
{
map_error:
-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-11 16:06:10.000000000 +0000
+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' glibc-2.6.1/elf/dl-reloc.c glibc-2.6.1/elf/dl-reloc.c
+--- 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-14 10:33:11.000000000 +0000
@@ -27,6 +27,9 @@
#include <sys/types.h>
#include "dynamic-link.h"
@@ -29,7 +29,7 @@
/* Statistics function. */
#ifdef SHARED
# define bump_num_cache_relocations() ++GL(dl_num_cache_relocations)
-@@ -133,6 +136,67 @@
+@@ -133,6 +136,68 @@
'\0', map->l_tls_blocksize - map->l_tls_initimage_size);
}
@@ -54,9 +54,10 @@
+ return;
+ }
+ rel = (ElfW(VtReloc) *)(D_PTR (map, l_info[SUSEIDX(DT_SUSE_VTRELOC)]));
-+ _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);
++ if (debug_output)
++ _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);
+ while (rel->r_src != 0)
+ {
+ ElfW(Addr) **src, **dest;
@@ -97,7 +98,7 @@
void
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
-@@ -174,11 +238,15 @@
+@@ -174,11 +239,15 @@
/* DT_TEXTREL is now in level 2 and might phase out at some time.
But we rewrite the DT_FLAGS entry to a DT_TEXTREL entry to make
testing easier and therefore it will be available at all time. */
@@ -114,7 +115,7 @@
for (ph = l->l_phdr; ph < &l->l_phdr[l->l_phnum]; ++ph)
if (ph->p_type == PT_LOAD && (ph->p_flags & PF_W) == 0)
{
-@@ -293,9 +361,12 @@
+@@ -293,9 +362,12 @@
#endif
}
@@ -127,7 +128,7 @@
/* Undo the segment protection changes. */
while (__builtin_expect (textrels != NULL, 0))
{
-@@ -307,6 +378,7 @@
+@@ -307,6 +379,7 @@
textrels = textrels->next;
}
@@ -135,8 +136,8 @@
/* In case we can protect the data now that the relocations are
done, do it. */
-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
+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' glibc-2.6.1/elf/dynamic-link.h glibc-2.6.1/elf/dynamic-link.h
+--- 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-10 18:08:21.000000000 +0000
@@ -65,6 +65,10 @@
#ifndef VERSYMIDX
@@ -167,8 +168,8 @@
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 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
+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' glibc-2.6.1/elf/elf.h glibc-2.6.1/elf/elf.h
+--- 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 16:43:02.000000000 +0000
@@ -518,6 +518,22 @@
Elf64_Sxword r_addend; /* Addend */
@@ -208,8 +209,8 @@
/* 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 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
+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' glibc-2.6.1/include/link.h glibc-2.6.1/include/link.h
+--- 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 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]