This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

refcounts ought to start from zero



This patch is about turning code in check_relocs like the following

      if (h->got.refcount == -1)
	h->got.refcount = 1;
      else
	h->got.refcount += 1;

into the simpler

      h->got.refcount += 1;

by starting refcounts at zero.

Sounds easy, but it's complicated by a number of factors.  Firstly, h->got
(and h->plt) are unions;  The fields are initially used as refcounts, then
later as offsets, and zero happens to be a valid offset.  Depending on the
back-end, one or more of adjust_dynamic_relocs, elf_gc_common_final_link,
and size_dynamic_sections turn the refcounts into offsets.  The problem
here being that should the linker need to create a symbol when the fields
are used as offsets, we need to initialise the offset to -1 as opposed to
initialising the refcount to zero.  Otherwise finish_dynamic_symbol might
think the symbol has a valid got and plt offset.  Problem solved by
init_refcount.  Secondly, some of the ELF back-ends, eg. elf32-sparc, claim
to support garbage collection but don't implement reference counting.
These back-ends use got.offset and plt.offset as offsets right from the
beginning, and so need the fields initialised to -1.  That's why it's
necessary to have elf_backend_can_refcount.

bfd/ChangeLog
	* 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.
	(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.
	* 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.

I'll check this in soon unless someone finds fatal flaws.  HP in
particular, could you verify that this doesn't break cris?  elf32-cris
has a few unusual features...

-- 
Alan Modra

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.46
diff -u -p -r1.46 elf-bfd.h
--- elf-bfd.h	2001/09/25 04:34:50	1.46
+++ elf-bfd.h	2001/09/28 05:55:49
@@ -28,7 +28,7 @@ Foundation, Inc., 59 Temple Place - Suit
 #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: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.94
diff -u -p -r1.94 elf.c
--- elf.c	2001/09/24 01:38:31	1.94
+++ elf.c	2001/09/28 06:09:40
@@ -944,31 +944,31 @@ _bfd_elf_link_hash_newfunc (entry, table
      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
       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, i
 	| 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, ab
 
   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: bfd/elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.12
diff -u -p -r1.12 elf32-cris.c
--- elf32-cris.c	2001/09/24 01:38:31	1.12
+++ elf32-cris.c	2001/09/28 05:55:56
@@ -2315,10 +2315,9 @@ cris_elf_check_relocs (abfd, info, sec, 
 		 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, 
 
 	  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, 
 		  /* 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, 
 		      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, 
 	    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, 
 
 	      /* 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: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.50
diff -u -p -r1.50 elf32-hppa.c
--- elf32-hppa.c	2001/09/28 08:56:51	1.50
+++ elf32-hppa.c	2001/09/28 09:00:52
@@ -1359,10 +1359,7 @@ elf32_hppa_check_relocs (abfd, info, sec
 
 	  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
 	    {
 	      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
@@ -4375,6 +4367,7 @@ elf32_hppa_elf_get_symbol_type (elf_sym,
 #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: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.51
diff -u -p -r1.51 elf32-i386.c
--- elf32-i386.c	2001/09/27 16:18:42	1.51
+++ elf32-i386.c	2001/09/28 09:00:50
@@ -703,10 +703,7 @@ elf_i386_check_relocs (abfd, info, sec, 
 	  /* 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 +751,8 @@ elf_i386_check_relocs (abfd, info, sec, 
 	  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 +769,7 @@ elf_i386_check_relocs (abfd, info, sec, 
 
 	      /* 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 +1267,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 +1299,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)
@@ -2141,7 +2130,10 @@ elf_i386_finish_dynamic_symbol (output_b
       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 +2257,7 @@ elf_i386_finish_dynamic_sections (output
       for (; dyncon < dynconend; dyncon++)
 	{
 	  Elf_Internal_Dyn dyn;
+	  asection *s;
 
 	  bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
 
@@ -2282,10 +2275,11 @@ elf_i386_finish_dynamic_sections (output
 	      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 +2294,11 @@ elf_i386_finish_dynamic_sections (output
 		 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 +2360,7 @@ elf_i386_finish_dynamic_sections (output
 #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: bfd/elf32-m68k.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m68k.c,v
retrieving revision 1.27
diff -u -p -r1.27 elf32-m68k.c
--- elf32-m68k.c	2001/09/24 01:38:31	1.27
+++ elf32-m68k.c	2001/09/28 05:56:06
@@ -534,10 +534,8 @@ elf_m68k_check_relocs (abfd, info, sec, 
 
 	  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, 
 		  /* 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, 
 		  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, 
 		      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, 
 	    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, 
 	    }
 
 	  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, 
 		  /* 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, 
 	    {
 	      /* 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: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.31
diff -u -p -r1.31 elf32-ppc.c
--- elf32-ppc.c	2001/09/24 01:38:31	1.31
+++ elf32-ppc.c	2001/09/28 05:56:08
@@ -2184,7 +2184,7 @@ ppc_elf_check_relocs (abfd, info, sec, r
 
 	  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, r
 		  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, r
 		  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, r
                      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, r
 	      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: bfd/elf32-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-s390.c,v
retrieving revision 1.8
diff -u -p -r1.8 elf32-s390.c
--- elf32-s390.c	2001/09/24 01:38:31	1.8
+++ elf32-s390.c	2001/09/28 05:56:10
@@ -577,10 +577,8 @@ elf_s390_check_relocs (abfd, info, sec, 
 
 	  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, 
 		  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, 
 		  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, 
 		      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, 
 	  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: bfd/elf64-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-s390.c,v
retrieving revision 1.8
diff -u -p -r1.8 elf64-s390.c
--- elf64-s390.c	2001/09/24 01:38:31	1.8
+++ elf64-s390.c	2001/09/28 05:56:16
@@ -541,10 +541,8 @@ elf_s390_check_relocs (abfd, info, sec, 
 
 	  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, 
 		  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, 
 
 		  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, 
 		      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, 
 	  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_si
 #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: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.27
diff -u -p -r1.27 elf64-x86-64.c
--- elf64-x86-64.c	2001/09/24 01:38:31	1.27
+++ elf64-x86-64.c	2001/09/28 05:56:17
@@ -442,10 +442,8 @@ elf64_x86_64_check_relocs (abfd, info, s
 
 	  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)
 		    {
@@ -456,8 +454,7 @@ elf64_x86_64_check_relocs (abfd, info, s
 		  sgot->_raw_size += GOT_ENTRY_SIZE;
 		  srelgot->_raw_size += sizeof (Elf64_External_Rela);
 		}
-	      else
-		h->got.refcount += 1;
+	      h->got.refcount += 1;
 	    }
 	  else
 	    {
@@ -469,16 +466,13 @@ elf64_x86_64_check_relocs (abfd, info, s
 		  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)
 		    {
@@ -488,8 +482,7 @@ elf64_x86_64_check_relocs (abfd, info, s
 		      srelgot->_raw_size += sizeof (Elf64_External_Rela);
 		    }
 		}
-	      else
-		local_got_refcounts[r_symndx] += 1;
+	      local_got_refcounts[r_symndx] += 1;
 	    }
 	  break;
 
@@ -507,10 +500,7 @@ elf64_x86_64_check_relocs (abfd, info, s
 	    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:
@@ -1960,6 +1950,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: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.108
diff -u -p -r1.108 elflink.h
--- elflink.h	2001/09/24 01:38:31	1.108
+++ elflink.h	2001/09/28 05:56:25
@@ -2920,6 +2920,10 @@ NAME(bfd_elf,size_dynamic_sections) (out
   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: bfd/elfxx-target.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-target.h,v
retrieving revision 1.29
diff -u -p -r1.29 elfxx-target.h
--- elfxx-target.h	2001/09/18 09:57:24	1.29
+++ elfxx-target.h	2001/09/28 05:56:28
@@ -102,6 +102,9 @@ Foundation, Inc., 59 Temple Place - Suit
 #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 elf
   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: bfd/linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.17
diff -u -p -r1.17 linker.c
--- linker.c	2001/09/21 02:12:28	1.17
+++ linker.c	2001/09/28 05:56:30
@@ -445,28 +445,27 @@ _bfd_link_hash_newfunc (entry, table, st
      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, t
      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.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]