* elf-bfd.h (struct elf_link_local_dynamic_entry): Add init_refcount.
authorAlan Modra <amodra@gmail.com>
Sat, 29 Sep 2001 06:21:59 +0000 (06:21 +0000)
committerAlan Modra <amodra@gmail.com>
Sat, 29 Sep 2001 06:21:59 +0000 (06:21 +0000)
(struct elf_backend_data): Add can_refcount.
* elf.c (_bfd_elf_link_hash_newfunc): Get rid of a few casts.  Set
got.refcount and plt.refcount from init_refcount.
(_bfd_elf_link_hash_table_init): Set up init_refcount.
(_bfd_elf_link_hash_copy_indirect): Reference got/plt.refcount
rather than got/plt.offset, and test for <= 0 rather than -1.
* elflink.h (size_dynamic_sections): Set init_refcount to -1.
* elfxx-target.h (elf_backend_can_refcount): Define.
(elfNN_bed): Init can_refcount.
* linker.c (_bfd_link_hash_newfunc): Get rid of a few casts.
(_bfd_generic_link_hash_newfunc): Likewise.
* elf32-cris.c (cris_elf_check_relocs): Modify for refcounts
starting from zero.
(elf_backend_can_refcount): Define.
* elf32-hppa.c (elf32_hppa_check_relocs): Modify for refcounts
starting from zero.
(elf32_hppa_copy_indirect_symbol): Make static to agree with
prototype.
(elf_backend_can_refcount): Define.
* elf32-i386.c (elf_i386_check_relocs): Modify for refcounts
starting from zero.
(allocate_dynrelocs): Set plt/got.offset rather than *.refcount.
(elf_i386_finish_dynamic_symbol): Expand SHN_UNDEF comment.
(elf_i386_finish_dynamic_sections): Use local var so line < 80 chars.
(elf_backend_can_refcount): Define.
(elf_i386_copy_indirect_symbol): Make static to agree with
prototype.  Formatting fix.
* elf32-m68k.c (elf_m68k_check_relocs): Modify for refcounts
starting from zero.
(elf_backend_can_refcount): Define.
* elf32-ppc.c (ppc_elf_check_relocs): Modify for refcounts
starting from zero.
(elf_backend_can_refcount): Define.
* elf32-s390.c (elf_s390_check_relocs): Modify for refcounts
starting from zero.
(elf_backend_can_refcount): Define.
* elf64-s390.c (elf_s390_check_relocs): Modify for refcounts
starting from zero.
(elf_backend_can_refcount): Define.
* elf64-x86-64.c (elf64_x86_64_check_relocs): Modify for refcounts
starting from zero.
(elf_backend_can_refcount): Define.

14 files changed:
bfd/ChangeLog
bfd/elf-bfd.h
bfd/elf.c
bfd/elf32-cris.c
bfd/elf32-hppa.c
bfd/elf32-i386.c
bfd/elf32-m68k.c
bfd/elf32-ppc.c
bfd/elf32-s390.c
bfd/elf64-s390.c
bfd/elf64-x86-64.c
bfd/elflink.h
bfd/elfxx-target.h
bfd/linker.c

index fd02d0b..b68f724 100644 (file)
@@ -1,5 +1,49 @@
 2001-09-29  Alan Modra  <amodra@bigpond.net.au>
 
+       * elf-bfd.h (struct elf_link_local_dynamic_entry): Add init_refcount.
+       (struct elf_backend_data): Add can_refcount.
+       * elf.c (_bfd_elf_link_hash_newfunc): Get rid of a few casts.  Set
+       got.refcount and plt.refcount from init_refcount.
+       (_bfd_elf_link_hash_table_init): Set up init_refcount.
+       (_bfd_elf_link_hash_copy_indirect): Reference got/plt.refcount
+       rather than got/plt.offset, and test for <= 0 rather than -1.
+       * elflink.h (size_dynamic_sections): Set init_refcount to -1.
+       * elfxx-target.h (elf_backend_can_refcount): Define.
+       (elfNN_bed): Init can_refcount.
+       * linker.c (_bfd_link_hash_newfunc): Get rid of a few casts.
+       (_bfd_generic_link_hash_newfunc): Likewise.
+       * elf32-cris.c (cris_elf_check_relocs): Modify for refcounts
+       starting from zero.
+       (elf_backend_can_refcount): Define.
+       * elf32-hppa.c (elf32_hppa_check_relocs): Modify for refcounts
+       starting from zero.
+       (elf32_hppa_copy_indirect_symbol): Make static to agree with
+       prototype.
+       (elf_backend_can_refcount): Define.
+       * elf32-i386.c (elf_i386_check_relocs): Modify for refcounts
+       starting from zero.
+       (allocate_dynrelocs): Set plt/got.offset rather than *.refcount.
+       (elf_i386_finish_dynamic_symbol): Expand SHN_UNDEF comment.
+       (elf_i386_finish_dynamic_sections): Use local var so line < 80 chars.
+       (elf_backend_can_refcount): Define.
+       (elf_i386_copy_indirect_symbol): Make static to agree with
+       prototype.  Formatting fix.
+       * elf32-m68k.c (elf_m68k_check_relocs): Modify for refcounts
+       starting from zero.
+       (elf_backend_can_refcount): Define.
+       * elf32-ppc.c (ppc_elf_check_relocs): Modify for refcounts
+       starting from zero.
+       (elf_backend_can_refcount): Define.
+       * elf32-s390.c (elf_s390_check_relocs): Modify for refcounts
+       starting from zero.
+       (elf_backend_can_refcount): Define.
+       * elf64-s390.c (elf_s390_check_relocs): Modify for refcounts
+       starting from zero.
+       (elf_backend_can_refcount): Define.
+       * elf64-x86-64.c (elf64_x86_64_check_relocs): Modify for refcounts
+       starting from zero.
+       (elf_backend_can_refcount): Define.
+
        * som.c (som_write_symbol_strings): Cast current_offset in
        bfd_seek call to match param type.
 
index 6f0ae0f..e1f38b9 100644 (file)
@@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "bfdlink.h"
 
 /* The number of entries in a section is its size divided by the size
-   of a single entry.  This is normally only applicaable to reloc and
+   of a single entry.  This is normally only applicable to reloc and
    symbol table sections.  */
 #define NUM_SHDR_ENTRIES(shdr) ((shdr)->sh_size / (shdr)->sh_entsize)
 
@@ -223,33 +223,50 @@ struct elf_link_local_dynamic_entry
 struct elf_link_hash_table
 {
   struct bfd_link_hash_table root;
+
   /* Whether we have created the special dynamic sections required
      when linking against or generating a shared object.  */
   boolean dynamic_sections_created;
+
   /* The BFD used to hold special sections created by the linker.
      This will be the first BFD found which requires these sections to
      be created.  */
   bfd *dynobj;
+
+  /* The value to use when initialising got.refcount/offset and
+     plt.refcount/offset in an elf_link_hash_entry.  Set to zero when
+     the values are refcounts.  Set to -1 in size_dynamic_sections
+     when the values may be offsets.  */
+  bfd_signed_vma init_refcount;
+
   /* The number of symbols found in the link which must be put into
      the .dynsym section.  */
   bfd_size_type dynsymcount;
+
   /* The string table of dynamic symbols, which becomes the .dynstr
      section.  */
   struct bfd_strtab_hash *dynstr;
+
   /* The number of buckets in the hash table in the .hash section.
      This is based on the number of dynamic symbols.  */
   bfd_size_type bucketcount;
+
   /* A linked list of DT_NEEDED names found in dynamic objects
      included in the link.  */
   struct bfd_link_needed_list *needed;
+
   /* The _GLOBAL_OFFSET_TABLE_ symbol.  */
   struct elf_link_hash_entry *hgot;
+
   /* A pointer to information used to link stabs in sections.  */
   PTR stab_info;
+
   /* A pointer to information used to merge SEC_MERGE sections.  */
   PTR merge_info;
+
   /* A linked list of local symbols to be added to .dynsym.  */
   struct elf_link_local_dynamic_entry *dynlocal;
+
   /* A linked list of DT_RPATH/DT_RUNPATH names found in dynamic
      objects included in the link.  */
   struct bfd_link_needed_list *runpath;
@@ -726,6 +743,7 @@ struct elf_backend_data
   unsigned plt_not_loaded : 1;
   unsigned plt_alignment : 4;
   unsigned can_gc_sections : 1;
+  unsigned can_refcount : 1;
   unsigned want_got_sym : 1;
   unsigned want_dynbss : 1;
 };
index a6ceafb..2927d56 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -944,31 +944,31 @@ _bfd_elf_link_hash_newfunc (entry, table, string)
      struct bfd_hash_table *table;
      const char *string;
 {
-  struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
-
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
-  if (ret == (struct elf_link_hash_entry *) NULL)
-    ret = ((struct elf_link_hash_entry *)
-          bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)));
-  if (ret == (struct elf_link_hash_entry *) NULL)
-    return (struct bfd_hash_entry *) ret;
+  if (entry == NULL)
+    {
+      entry = bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry));
+      if (entry == NULL)
+       return entry;
+    }
 
   /* Call the allocation method of the superclass.  */
-  ret = ((struct elf_link_hash_entry *)
-        _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
-                                table, string));
-  if (ret != (struct elf_link_hash_entry *) NULL)
+  entry = _bfd_link_hash_newfunc (entry, table, string);
+  if (entry != NULL)
     {
+      struct elf_link_hash_entry *ret = (struct elf_link_hash_entry *) entry;
+      struct elf_link_hash_table *htab = (struct elf_link_hash_table *) table;
+
       /* Set local fields.  */
       ret->indx = -1;
       ret->size = 0;
       ret->dynindx = -1;
       ret->dynstr_index = 0;
       ret->weakdef = NULL;
-      ret->got.offset = (bfd_vma) -1;
-      ret->plt.offset = (bfd_vma) -1;
-      ret->linker_section_pointer = (elf_linker_section_pointers_t *)0;
+      ret->got.refcount = htab->init_refcount;
+      ret->plt.refcount = htab->init_refcount;
+      ret->linker_section_pointer = NULL;
       ret->verinfo.verdef = NULL;
       ret->vtable_entries_used = NULL;
       ret->vtable_entries_size = 0;
@@ -982,7 +982,7 @@ _bfd_elf_link_hash_newfunc (entry, table, string)
       ret->elf_link_hash_flags = ELF_LINK_NON_ELF;
     }
 
-  return (struct bfd_hash_entry *) ret;
+  return entry;
 }
 
 /* Copy data from an indirect symbol to its direct symbol, hiding the
@@ -1002,21 +1002,21 @@ _bfd_elf_link_hash_copy_indirect (dir, ind)
        | ELF_LINK_HASH_REF_REGULAR_NONWEAK
        | ELF_LINK_NON_GOT_REF));
 
-  /* Copy over the global and procedure linkage table offset entries.
+  /* Copy over the global and procedure linkage table refcount entries.
      These may have been already set up by a check_relocs routine.  */
-  if (dir->got.offset == (bfd_vma) -1)
+  if (dir->got.refcount <= 0)
     {
-      dir->got.offset = ind->got.offset;
-      ind->got.offset = (bfd_vma) -1;
+      dir->got.refcount = ind->got.refcount;
+      ind->got.refcount = 0;
     }
-  BFD_ASSERT (ind->got.offset == (bfd_vma) -1);
+  BFD_ASSERT (ind->got.refcount <= 0);
 
-  if (dir->plt.offset == (bfd_vma) -1)
+  if (dir->plt.refcount <= 0)
     {
-      dir->plt.offset = ind->plt.offset;
-      ind->plt.offset = (bfd_vma) -1;
+      dir->plt.refcount = ind->plt.refcount;
+      ind->plt.refcount = 0;
     }
-  BFD_ASSERT (ind->plt.offset == (bfd_vma) -1);
+  BFD_ASSERT (ind->plt.refcount <= 0);
 
   if (dir->dynindx == -1)
     {
@@ -1053,6 +1053,7 @@ _bfd_elf_link_hash_table_init (table, abfd, newfunc)
 
   table->dynamic_sections_created = false;
   table->dynobj = NULL;
+  table->init_refcount = get_elf_backend_data (abfd)->can_refcount - 1;
   /* The first dynamic symbol is a dummy.  */
   table->dynsymcount = 1;
   table->dynstr = NULL;
index aca0852..8178425 100644 (file)
@@ -2315,10 +2315,9 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
                 GOT entries.  */
              amt = symtab_hdr->sh_info + 1;
              amt *= sizeof (bfd_signed_vma);
-             local_got_refcounts = ((bfd_signed_vma *) bfd_alloc (abfd, amt));
+             local_got_refcounts = ((bfd_signed_vma *) bfd_zalloc (abfd, amt));
              if (local_got_refcounts == NULL)
                return false;
-             memset (local_got_refcounts, -1, (size_t) amt);
 
              local_got_refcounts++;
              elf_local_got_refcounts (abfd) = local_got_refcounts;
@@ -2371,10 +2370,8 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
 
          if (h != NULL)
            {
-             if (h->got.refcount == -1)
+             if (h->got.refcount == 0)
                {
-                 h->got.refcount = 1;
-
                  /* Make sure this symbol is output as a dynamic symbol.  */
                  if (h->dynindx == -1)
                    {
@@ -2387,16 +2384,13 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
                  /* Allocate relocation space.  */
                  srelgot->_raw_size += sizeof (Elf32_External_Rela);
                }
-             else
-               h->got.refcount++;
+             h->got.refcount++;
            }
          else
            {
              /* This is a global offset table entry for a local symbol.  */
-             if (local_got_refcounts[r_symndx] == -1)
+             if (local_got_refcounts[r_symndx] == 0)
                {
-                 local_got_refcounts[r_symndx] = 1;
-
                  sgot->_raw_size += 4;
                  if (info->shared)
                    {
@@ -2406,8 +2400,7 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
                      srelgot->_raw_size += sizeof (Elf32_External_Rela);
                    }
                }
-             else
-               local_got_refcounts[r_symndx]++;
+             local_got_refcounts[r_symndx]++;
            }
          break;
 
@@ -2440,10 +2433,7 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
            continue;
 
          h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-         if (h->plt.refcount == -1)
-           h->plt.refcount = 1;
-         else
-           h->plt.refcount++;
+         h->plt.refcount++;
          break;
 
        case R_CRIS_8:
@@ -2478,10 +2468,7 @@ cris_elf_check_relocs (abfd, info, sec, relocs)
 
              /* Make sure a plt entry is created for this symbol if it
                 turns out to be a function defined by a dynamic object.  */
-             if (h->plt.refcount == -1)
-               h->plt.refcount = 1;
-             else
-               h->plt.refcount++;
+             h->plt.refcount++;
            }
 
          /* If we are creating a shared library and this is not a local
@@ -3013,6 +3000,7 @@ elf_cris_reloc_type_class (rela)
 #define elf_backend_check_relocs                cris_elf_check_relocs
 
 #define elf_backend_can_gc_sections            1
+#define elf_backend_can_refcount               1
 
 #define elf_backend_object_p                   cris_elf_object_p
 #define elf_backend_final_write_processing \
index b1ec63c..8b662ab 100644 (file)
@@ -1133,7 +1133,7 @@ elf32_hppa_create_dynamic_sections (abfd, info)
 
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
-void
+static void
 elf32_hppa_copy_indirect_symbol (dir, ind)
      struct elf_link_hash_entry *dir, *ind;
 {
@@ -1359,10 +1359,7 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
 
          if (h != NULL)
            {
-             if (h->elf.got.refcount == -1)
-               h->elf.got.refcount = 1;
-             else
-               h->elf.got.refcount += 1;
+             h->elf.got.refcount += 1;
            }
          else
            {
@@ -1404,13 +1401,8 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs)
            {
              if (h != NULL)
                {
-                 if (h->elf.plt.refcount == -1)
-                   {
-                     h->elf.plt.refcount = 1;
-                     h->elf.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-                   }
-                 else
-                   h->elf.plt.refcount += 1;
+                 h->elf.elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+                 h->elf.plt.refcount += 1;
 
                  /* If this .plt entry is for a plabel, mark it so
                     that adjust_dynamic_symbol will keep the entry
@@ -3491,7 +3483,6 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
      Elf_Internal_Sym *local_syms;
      asection **local_sections;
 {
-  bfd *dynobj;
   bfd_vma *local_got_offsets;
   struct elf32_hppa_link_hash_table *htab;
   Elf_Internal_Shdr *symtab_hdr;
@@ -3501,7 +3492,6 @@ elf32_hppa_relocate_section (output_bfd, info, input_bfd, input_section,
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
   htab = hppa_link_hash_table (info);
-  dynobj = htab->elf.dynobj;
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
   rel = relocs;
@@ -4019,10 +4009,8 @@ elf32_hppa_finish_dynamic_symbol (output_bfd, info, h, sym)
      Elf_Internal_Sym *sym;
 {
   struct elf32_hppa_link_hash_table *htab;
-  bfd *dynobj;
 
   htab = hppa_link_hash_table (info);
-  dynobj = htab->elf.dynobj;
 
   if (h->plt.offset != (bfd_vma) -1)
     {
@@ -4375,6 +4363,7 @@ elf32_hppa_elf_get_symbol_type (elf_sym, type)
 #define elf_backend_reloc_type_class        elf32_hppa_reloc_type_class
 
 #define elf_backend_can_gc_sections         1
+#define elf_backend_can_refcount            1
 #define elf_backend_plt_alignment           2
 #define elf_backend_want_got_plt            0
 #define elf_backend_plt_readonly            0
index dbd137f..192aa4e 100644 (file)
@@ -44,8 +44,7 @@ static boolean create_got_section
   PARAMS((bfd *, struct bfd_link_info *));
 static boolean elf_i386_create_dynamic_sections
   PARAMS((bfd *, struct bfd_link_info *));
-static void
-elf_i386_copy_indirect_symbol
+static void elf_i386_copy_indirect_symbol
   PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));
 static boolean elf_i386_check_relocs
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
@@ -629,7 +628,7 @@ elf_i386_create_dynamic_sections (dynobj, info)
 
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
-void
+static void
 elf_i386_copy_indirect_symbol (dir, ind)
      struct elf_link_hash_entry *dir, *ind;
 {
@@ -703,10 +702,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
          /* This symbol requires a global offset table entry.  */
          if (h != NULL)
            {
-             if (h->got.refcount == -1)
-               h->got.refcount = 1;
-             else
-               h->got.refcount += 1;
+             h->got.refcount += 1;
            }
          else
            {
@@ -754,13 +750,8 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
          if (h == NULL)
            continue;
 
-         if (h->plt.refcount == -1)
-           {
-             h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-             h->plt.refcount = 1;
-           }
-         else
-           h->plt.refcount += 1;
+         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+         h->plt.refcount += 1;
          break;
 
        case R_386_32:
@@ -777,10 +768,7 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
 
              /* We may need a .plt entry if the function this reloc
                 refers to is in a shared lib.  */
-             if (h->plt.refcount == -1)
-               h->plt.refcount = 1;
-             else
-               h->plt.refcount += 1;
+             h->plt.refcount += 1;
            }
 
          /* If we are creating a shared library, and this is a reloc
@@ -1278,13 +1266,13 @@ allocate_dynrelocs (h, inf)
        }
       else
        {
-         h->plt.refcount = -1;
+         h->plt.offset = (bfd_vma) -1;
          h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
        }
     }
   else
     {
-      h->plt.refcount = -1;
+      h->plt.offset = (bfd_vma) -1;
       h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
     }
 
@@ -1310,7 +1298,7 @@ allocate_dynrelocs (h, inf)
        htab->srelgot->_raw_size += sizeof (Elf32_External_Rel);
     }
   else
-    h->got.refcount = -1;
+    h->got.offset = (bfd_vma) -1;
 
   eh = (struct elf_i386_link_hash_entry *) h;
   if (eh->dyn_relocs == NULL)
@@ -1648,7 +1636,6 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
      asection **local_sections;
 {
   struct elf_i386_link_hash_table *htab;
-  bfd *dynobj;
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes;
   bfd_vma *local_got_offsets;
@@ -1656,7 +1643,6 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
   Elf_Internal_Rela *relend;
 
   htab = elf_i386_hash_table (info);
-  dynobj = htab->elf.dynobj;
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (input_bfd);
   local_got_offsets = elf_local_got_offsets (input_bfd);
@@ -2066,10 +2052,8 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
      Elf_Internal_Sym *sym;
 {
   struct elf_i386_link_hash_table *htab;
-  bfd *dynobj;
 
   htab = elf_i386_hash_table (info);
-  dynobj = htab->elf.dynobj;
 
   if (h->plt.offset != (bfd_vma) -1)
     {
@@ -2141,7 +2125,10 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
       if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
        {
          /* Mark the symbol as undefined, rather than as defined in
-            the .plt section.  Leave the value alone.  */
+            the .plt section.  Leave the value alone.  This is a clue
+            for the dynamic linker, to make function pointer
+            comparisons work between an application and shared
+            library.  */  
          sym->st_shndx = SHN_UNDEF;
        }
     }
@@ -2265,6 +2252,7 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
       for (; dyncon < dynconend; dyncon++)
        {
          Elf_Internal_Dyn dyn;
+         asection *s;
 
          bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
 
@@ -2282,10 +2270,11 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
              break;
 
            case DT_PLTRELSZ:
-             if (htab->srelplt->output_section->_cooked_size != 0)
-               dyn.d_un.d_val = htab->srelplt->output_section->_cooked_size;
+             s = htab->srelplt->output_section;
+             if (s->_cooked_size != 0)
+               dyn.d_un.d_val = s->_cooked_size;
              else
-               dyn.d_un.d_val = htab->srelplt->output_section->_raw_size;
+               dyn.d_un.d_val = s->_raw_size;
              break;
 
            case DT_RELSZ:
@@ -2300,10 +2289,11 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
                 about changing the DT_REL entry.  */
              if (htab->srelplt != NULL)
                {
-                 if (htab->srelplt->output_section->_cooked_size != 0)
-                   dyn.d_un.d_val -= htab->srelplt->output_section->_cooked_size;
+                 s = htab->srelplt->output_section;
+                 if (s->_cooked_size != 0)
+                   dyn.d_un.d_val -= s->_cooked_size;
                  else
-                   dyn.d_un.d_val -= htab->srelplt->output_section->_raw_size;
+                   dyn.d_un.d_val -= s->_raw_size;
                }
              break;
            }
@@ -2365,6 +2355,7 @@ elf_i386_finish_dynamic_sections (output_bfd, info)
 #define ELF_MAXPAGESIZE                        0x1000
 
 #define elf_backend_can_gc_sections    1
+#define elf_backend_can_refcount       1
 #define elf_backend_want_got_plt       1
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
index 80613f1..c325224 100644 (file)
@@ -534,10 +534,8 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
 
          if (h != NULL)
            {
-             if (h->got.refcount == -1)
+             if (h->got.refcount == 0)
                {
-                 h->got.refcount = 1;
-
                  /* Make sure this symbol is output as a dynamic symbol.  */
                  if (h->dynindx == -1)
                    {
@@ -550,8 +548,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
                  /* Allocate relocation space.  */
                  srelgot->_raw_size += sizeof (Elf32_External_Rela);
                }
-             else
-               h->got.refcount++;
+             h->got.refcount++;
            }
          else
            {
@@ -563,16 +560,13 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
                  size = symtab_hdr->sh_info;
                  size *= sizeof (bfd_signed_vma);
                  local_got_refcounts = ((bfd_signed_vma *)
-                                        bfd_alloc (abfd, size));
+                                        bfd_zalloc (abfd, size));
                  if (local_got_refcounts == NULL)
                    return false;
                  elf_local_got_refcounts (abfd) = local_got_refcounts;
-                 memset (local_got_refcounts, -1, (size_t) size);
                }
-             if (local_got_refcounts[r_symndx] == -1)
+             if (local_got_refcounts[r_symndx] == 0)
                {
-                 local_got_refcounts[r_symndx] = 1;
-
                  sgot->_raw_size += 4;
                  if (info->shared)
                    {
@@ -582,8 +576,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
                      srelgot->_raw_size += sizeof (Elf32_External_Rela);
                    }
                }
-             else
-               local_got_refcounts[r_symndx]++;
+             local_got_refcounts[r_symndx]++;
            }
          break;
 
@@ -603,10 +596,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
            continue;
 
          h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-         if (h->plt.refcount == -1)
-           h->plt.refcount = 1;
-         else
-           h->plt.refcount++;
+         h->plt.refcount++;
          break;
 
        case R_68K_PLT8O:
@@ -631,10 +621,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
            }
 
          h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-         if (h->plt.refcount == -1)
-           h->plt.refcount = 1;
-         else
-           h->plt.refcount++;
+         h->plt.refcount++;
          break;
 
        case R_68K_PC8:
@@ -662,10 +649,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
                  /* Make sure a plt entry is created for this symbol if
                     it turns out to be a function defined by a dynamic
                     object.  */
-                 if (h->plt.refcount == -1)
-                   h->plt.refcount = 1;
-                 else
-                   h->plt.refcount++;
+                 h->plt.refcount++;
                }
              break;
            }
@@ -677,10 +661,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs)
            {
              /* Make sure a plt entry is created for this symbol if it
                 turns out to be a function defined by a dynamic object.  */
-             if (h->plt.refcount == -1)
-               h->plt.refcount = 1;
-             else
-               h->plt.refcount++;
+             h->plt.refcount++;
            }
 
          /* If we are creating a shared library, we need to copy the
@@ -2357,6 +2338,7 @@ elf32_m68k_reloc_type_class (rela)
 #define elf_backend_reloc_type_class   elf32_m68k_reloc_type_class
 
 #define elf_backend_can_gc_sections 1
+#define elf_backend_can_refcount 1
 #define elf_backend_want_got_plt 1
 #define elf_backend_plt_readonly 1
 #define elf_backend_want_plt_sym 0
index d770b2b..f314349 100644 (file)
@@ -2184,7 +2184,7 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
 
          if (h != NULL)
            {
-             if (h->got.refcount == -1)
+             if (h->got.refcount == 0)
                {
                  /* Make sure this symbol is output as a dynamic symbol.  */
                  if (h->dynindx == -1)
@@ -2195,11 +2195,8 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
                  sgot->_raw_size += 4;
                  /* Allocate relocation space.  */
                  srelgot->_raw_size += sizeof (Elf32_External_Rela);
-
-                 h->got.refcount = 1;
                }
-             else
-               h->got.refcount++;
+             h->got.refcount++;
            }
          else
            {
@@ -2211,13 +2208,12 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
                  size = symtab_hdr->sh_info;
                  size *= sizeof (bfd_signed_vma);
                  local_got_refcounts
-                   = (bfd_signed_vma *) bfd_alloc (abfd, size);
+                   = (bfd_signed_vma *) bfd_zalloc (abfd, size);
                  if (local_got_refcounts == NULL)
                    return false;
                  elf_local_got_refcounts (abfd) = local_got_refcounts;
-                 memset (local_got_refcounts, -1, (size_t) size);
                }
-             if (local_got_refcounts[r_symndx] == -1)
+             if (local_got_refcounts[r_symndx] == 0)
                {
                  sgot->_raw_size += 4;
 
@@ -2226,11 +2222,8 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
                      dynamic linker can adjust this GOT entry.  */
                  if (info->shared)
                    srelgot->_raw_size += sizeof (Elf32_External_Rela);
-
-                 local_got_refcounts[r_symndx] = 1;
                }
-             else
-               local_got_refcounts[r_symndx]++;
+             local_got_refcounts[r_symndx]++;
            }
          break;
 
@@ -2343,13 +2336,8 @@ ppc_elf_check_relocs (abfd, info, sec, relocs)
              if (! bfd_elf32_link_record_dynamic_symbol (info, h))
                return false;
            }
-         if (h->plt.refcount == -1)
-           {
-             h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-             h->plt.refcount = 1;
-           }
-         else
-           h->plt.refcount++;
+         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+         h->plt.refcount++;
          break;
 
          /* The following relocations don't need to propagate the
@@ -3821,6 +3809,7 @@ ppc_elf_grok_psinfo (abfd, note)
 #define elf_backend_plt_not_loaded     1
 #define elf_backend_got_symbol_offset  4
 #define elf_backend_can_gc_sections    1
+#define elf_backend_can_refcount       1
 #define elf_backend_got_header_size    12
 #define elf_backend_plt_header_size    PLT_INITIAL_ENTRY_SIZE
 
index 73db3f7..c8f5a8f 100644 (file)
@@ -577,10 +577,8 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
 
          if (h != NULL)
            {
-             if (h->got.refcount == -1)
+             if (h->got.refcount == 0)
                {
-                 h->got.refcount = 1;
-
                  /* Make sure this symbol is output as a dynamic symbol.  */
                  if (h->dynindx == -1)
                    {
@@ -591,8 +589,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
                  sgot->_raw_size += 4;
                  srelgot->_raw_size += sizeof (Elf32_External_Rela);
                }
-             else
-               h->got.refcount += 1;
+             h->got.refcount += 1;
            }
          else
            {
@@ -604,16 +601,13 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
                  size = symtab_hdr->sh_info;
                  size *= sizeof (bfd_signed_vma);
                  local_got_refcounts = (bfd_signed_vma *)
-                                        bfd_alloc (abfd, size);
+                                        bfd_zalloc (abfd, size);
                  if (local_got_refcounts == NULL)
                    return false;
                  elf_local_got_refcounts (abfd) = local_got_refcounts;
-                 memset (local_got_refcounts, -1, (size_t) size);
                }
-             if (local_got_refcounts[r_symndx] == -1)
+             if (local_got_refcounts[r_symndx] == 0)
                {
-                 local_got_refcounts[r_symndx] = 1;
-
                  sgot->_raw_size += 4;
                  if (info->shared)
                    {
@@ -623,8 +617,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
                      srelgot->_raw_size += sizeof (Elf32_External_Rela);
                    }
                }
-             else
-               local_got_refcounts[r_symndx] += 1;
+             local_got_refcounts[r_symndx] += 1;
            }
          break;
 
@@ -642,13 +635,8 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
          if (h == NULL)
            continue;
 
-         if (h->plt.refcount == -1)
-           {
-             h->plt.refcount = 1;
-             h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-           }
-         else
-           h->plt.refcount += 1;
+         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+         h->plt.refcount += 1;
          break;
 
         case R_390_8:
@@ -2164,6 +2152,7 @@ elf_s390_reloc_type_class (rela)
 #define ELF_MAXPAGESIZE 0x1000
 
 #define elf_backend_can_gc_sections    1
+#define elf_backend_can_refcount       1
 #define elf_backend_want_got_plt       1
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
index 02a436f..aeba855 100644 (file)
@@ -541,10 +541,8 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
 
          if (h != NULL)
            {
-             if (h->got.refcount == -1)
+             if (h->got.refcount == 0)
                {
-                 h->got.refcount = 1;
-
                  /* Make sure this symbol is output as a dynamic symbol.  */
                  if (h->dynindx == -1)
                    {
@@ -555,8 +553,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
                  sgot->_raw_size += 8;
                  srelgot->_raw_size += sizeof (Elf64_External_Rela);
                }
-             else
-               h->got.refcount += 1;
+             h->got.refcount += 1;
            }
          else
            {
@@ -567,16 +564,13 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
 
                  size = symtab_hdr->sh_info * sizeof (bfd_vma);
                  local_got_refcounts = ((bfd_signed_vma *)
-                                        bfd_alloc (abfd, size));
+                                        bfd_zalloc (abfd, size));
                  if (local_got_refcounts == NULL)
                    return false;
                  elf_local_got_refcounts (abfd) = local_got_refcounts;
-                 memset (local_got_refcounts, -1, (size_t) size);
                }
-             if (local_got_refcounts[r_symndx] == -1)
+             if (local_got_refcounts[r_symndx] == 0)
                {
-                 local_got_refcounts[r_symndx] = 1;
-
                  sgot->_raw_size += 8;
                  if (info->shared)
                    {
@@ -586,9 +580,7 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
                      srelgot->_raw_size += sizeof (Elf64_External_Rela);
                    }
                }
-             else
-               local_got_refcounts[r_symndx] += 1;
-
+             local_got_refcounts[r_symndx] += 1;
            }
          break;
 
@@ -608,13 +600,8 @@ elf_s390_check_relocs (abfd, info, sec, relocs)
          if (h == NULL)
            continue;
 
-         if (h->plt.refcount == -1)
-           {
-             h->plt.refcount = 1;
-             h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-           }
-         else
-           h->plt.refcount += 1;
+         h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
+         h->plt.refcount += 1;
          break;
 
         case R_390_8:
@@ -2162,6 +2149,7 @@ const struct elf_size_info s390_elf64_size_info =
 #define elf_backend_size_info          s390_elf64_size_info
 
 #define elf_backend_can_gc_sections    1
+#define elf_backend_can_refcount       1
 #define elf_backend_want_got_plt       1
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
index decd987..3215421 100644 (file)
@@ -441,10 +441,8 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
 
          if (h != NULL)
            {
-             if (h->got.refcount == -1)
+             if (h->got.refcount == 0)
                {
-                 h->got.refcount = 1;
-
                  /* Make sure this symbol is output as a dynamic symbol.  */
                  if (h->dynindx == -1)
                    {
@@ -455,8 +453,7 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
                  sgot->_raw_size += GOT_ENTRY_SIZE;
                  srelgot->_raw_size += sizeof (Elf64_External_Rela);
                }
-             else
-               h->got.refcount += 1;
+             h->got.refcount += 1;
            }
          else
            {
@@ -468,16 +465,13 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
                  size = symtab_hdr->sh_info;
                  size *= sizeof (bfd_signed_vma);
                  local_got_refcounts = ((bfd_signed_vma *)
-                                        bfd_alloc (abfd, size));
+                                        bfd_zalloc (abfd, size));
                  if (local_got_refcounts == NULL)
                    return false;
                  elf_local_got_refcounts (abfd) = local_got_refcounts;
-                 memset (local_got_refcounts, -1, (size_t) size);
                }
-             if (local_got_refcounts[r_symndx] == -1)
+             if (local_got_refcounts[r_symndx] == 0)
                {
-                 local_got_refcounts[r_symndx] = 1;
-
                  sgot->_raw_size += GOT_ENTRY_SIZE;
                  if (info->shared)
                    {
@@ -487,8 +481,7 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
                      srelgot->_raw_size += sizeof (Elf64_External_Rela);
                    }
                }
-             else
-               local_got_refcounts[r_symndx] += 1;
+             local_got_refcounts[r_symndx] += 1;
            }
          break;
 
@@ -506,10 +499,7 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs)
            continue;
 
          h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-         if (h->plt.refcount == -1)
-           h->plt.refcount = 1;
-         else
-           h->plt.refcount += 1;
+         h->plt.refcount += 1;
          break;
 
        case R_X86_64_8:
@@ -1959,6 +1949,7 @@ elf64_x86_64_reloc_type_class (rela)
 #define ELF_MAXPAGESIZE                            0x100000
 
 #define elf_backend_can_gc_sections        1
+#define elf_backend_can_refcount           1
 #define elf_backend_want_got_plt           1
 #define elf_backend_plt_readonly           1
 #define elf_backend_want_plt_sym           0
index e38f0d5..73687fb 100644 (file)
@@ -2920,6 +2920,10 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
   if (! is_elf_hash_table (info))
     return false;
 
+  /* Any syms created from now on start with -1 in
+     got.refcount/offset and plt.refcount/offset.  */
+  elf_hash_table (info)->init_refcount = -1;
+
   /* The backend may have to create some sections regardless of whether
      we're dynamic or not.  */
   bed = get_elf_backend_data (output_bfd);
index 257572d..59da038 100644 (file)
@@ -102,6 +102,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #ifndef elf_backend_can_gc_sections
 #define elf_backend_can_gc_sections 0
 #endif
+#ifndef elf_backend_can_refcount
+#define elf_backend_can_refcount 0
+#endif
 #ifndef elf_backend_want_got_sym
 #define elf_backend_want_got_sym 1
 #endif
@@ -459,6 +462,7 @@ static const struct elf_backend_data elfNN_bed =
   elf_backend_plt_not_loaded,
   elf_backend_plt_alignment,
   elf_backend_can_gc_sections,
+  elf_backend_can_refcount,
   elf_backend_want_dynbss,
   elf_backend_want_got_sym
 };
index 182786e..e382895 100644 (file)
@@ -445,28 +445,27 @@ _bfd_link_hash_newfunc (entry, table, string)
      struct bfd_hash_table *table;
      const char *string;
 {
-  struct bfd_link_hash_entry *ret = (struct bfd_link_hash_entry *) entry;
-
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
-  if (ret == (struct bfd_link_hash_entry *) NULL)
-    ret = ((struct bfd_link_hash_entry *)
-          bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry)));
-  if (ret == (struct bfd_link_hash_entry *) NULL)
-    return NULL;
+  if (entry == NULL)
+    {
+      entry = bfd_hash_allocate (table, sizeof (struct bfd_link_hash_entry));
+      if (entry == NULL)
+       return entry;
+    }
 
   /* Call the allocation method of the superclass.  */
-  ret = ((struct bfd_link_hash_entry *)
-        bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
-
-  if (ret)
+  entry = bfd_hash_newfunc (entry, table, string);
+  if (entry)
     {
+      struct bfd_link_hash_entry *h = (struct bfd_link_hash_entry *) entry;
+
       /* Initialize the local fields.  */
-      ret->type = bfd_link_hash_new;
-      ret->next = NULL;
+      h->type = bfd_link_hash_new;
+      h->next = NULL;
     }
 
-  return (struct bfd_hash_entry *) ret;
+  return entry;
 }
 
 /* Initialize a link hash table.  The BFD argument is the one
@@ -642,30 +641,29 @@ _bfd_generic_link_hash_newfunc (entry, table, string)
      struct bfd_hash_table *table;
      const char *string;
 {
-  struct generic_link_hash_entry *ret =
-    (struct generic_link_hash_entry *) entry;
-
   /* Allocate the structure if it has not already been allocated by a
      subclass.  */
-  if (ret == (struct generic_link_hash_entry *) NULL)
-    ret = ((struct generic_link_hash_entry *)
-          bfd_hash_allocate (table, sizeof (struct generic_link_hash_entry)));
-  if (ret == (struct generic_link_hash_entry *) NULL)
-    return NULL;
+  if (entry == NULL)
+    {
+      entry = bfd_hash_allocate (table,
+                                sizeof (struct generic_link_hash_entry));
+      if (entry == NULL)
+       return entry;
+    }
 
   /* Call the allocation method of the superclass.  */
-  ret = ((struct generic_link_hash_entry *)
-        _bfd_link_hash_newfunc ((struct bfd_hash_entry *) ret,
-                                table, string));
-
-  if (ret)
+  entry = _bfd_link_hash_newfunc (entry, table, string);
+  if (entry)
     {
+      struct generic_link_hash_entry *ret;
+
       /* Set local fields.  */
+      ret = (struct generic_link_hash_entry *) entry;
       ret->written = false;
       ret->sym = NULL;
     }
 
-  return (struct bfd_hash_entry *) ret;
+  return entry;
 }
 
 /* Create an generic link hash table.  */