This is the mail archive of the binutils@sourceware.org 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]
Other format: [Raw text]

Fix PR1540, abort on reference to versioned symbol


The linker currently aborts if one object file references an explicit
symbol version, and another file the default symbol version, when the
explicit version happens to be the same as the default provided by a
shared lib.  (If that's confusing, see the testcase in the PR.)  After
processing the two object files, we have

  foo, with dyn link info
  foo@VER_1, also with dyn link info

After processing the shared lib, we want to end up with

  foo --------------> foo@@VER_1
                       ^
  foo@VER_1 -----------|

ie. both foo and foo@VER_1 become indirect references to the default
sym, foo@@VER_1, and we want the dynamic link info transferred to
foo@@VER_1.  The trouble is that no matter which order we do the
transfer, at some point we require copy_indirect_symbol to handle a
direct and an indirect symbol both having dynamic link info.
_bfd_elf_link_hash_copy_indirect has never handled this situation,
neither have the various backend functions.  The following should fix
this, but I'm a little unsure whether tacking ia64's dyn_sym_info lists
together is correct.  Perhaps they ought to be merged in some manner.
Would an ia64 maintainer please look at this?

	PR ld/1540
	* elf-bfd.h (elf_backend_copy_indirect_symbol): Replace pointer to
	elf_backend_data with pointer to bfd_link_info.
	(_bfd_elf_link_hash_copy_indirect): Likewise.
	* elf.c (_bfd_elf_link_hash_copy_indirect): Likewise.  Handle
	direct and indirect symbols both having dynamic link info.
	* elf32-arm.c (elf32_arm_copy_indirect_symbol): Likewise.
	* elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Likewise.
	* elf32-i386.c (elf_i386_copy_indirect_symbol): Likewise.
	* elf32-m32r.c (m32r_elf_copy_indirect_symbol): Likewise.
	* elf32-ppc.c (ppc_elf_copy_indirect_symbol): Likewise.
	* elf32-s390.c (elf_s390_copy_indirect_symbol): Likewise.
	* elf32-sh.c (sh_elf_copy_indirect_symbol): Likewise.
	* elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
	* elf64-s390.c (elf_s390_copy_indirect_symbol): Likewise.
	* elf64-x86-64.c (elf64_x86_64_copy_indirect_symbol): Likewise.
	* elfxx-ia64.c (elfNN_ia64_hash_copy_indirect): Likewise.
	* elfxx-mips.c (_bfd_mips_elf_copy_indirect_symbol): Likewise.
	* elfxx-sparc.c (_bfd_sparc_elf_copy_indirect_symbol): Likewise.
	* elflink.c: Adjust all calls to bed->elf_backend_copy_indirect_symbol.
	* elfxx-mips.h (_bfd_mips_elf_copy_indirect_symbol): Update prototype.
	* elfxx-sparc.h (_bfd_sparc_elf_copy_indirect_symbol): Likewise.

Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.198
diff -u -p -r1.198 elf-bfd.h
--- bfd/elf-bfd.h	24 Oct 2005 01:40:58 -0000	1.198
+++ bfd/elf-bfd.h	25 Oct 2005 12:59:12 -0000
@@ -870,7 +870,7 @@ struct elf_backend_data
      newly created and plt/got refcounts and dynamic indices should not
      be copied.  */
   void (*elf_backend_copy_indirect_symbol)
-    (const struct elf_backend_data *, struct elf_link_hash_entry *,
+    (struct bfd_link_info *, struct elf_link_hash_entry *,
      struct elf_link_hash_entry *);
 
   /* Modify any information related to dynamic linking such that the
@@ -1462,7 +1462,7 @@ extern struct bfd_hash_entry *_bfd_elf_l
 extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
   (bfd *);
 extern void _bfd_elf_link_hash_copy_indirect
-  (const struct elf_backend_data *, struct elf_link_hash_entry *,
+  (struct bfd_link_info *, struct elf_link_hash_entry *,
    struct elf_link_hash_entry *);
 extern void _bfd_elf_link_hash_hide_symbol
   (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean);
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.316
diff -u -p -r1.316 elf.c
--- bfd/elf.c	24 Oct 2005 01:40:58 -0000	1.316
+++ bfd/elf.c	25 Oct 2005 12:59:17 -0000
@@ -1458,12 +1458,11 @@ _bfd_elf_link_hash_newfunc (struct bfd_h
    old indirect symbol.  Also used for copying flags to a weakdef.  */
 
 void
-_bfd_elf_link_hash_copy_indirect (const struct elf_backend_data *bed,
+_bfd_elf_link_hash_copy_indirect (struct bfd_link_info *info,
 				  struct elf_link_hash_entry *dir,
 				  struct elf_link_hash_entry *ind)
 {
-  bfd_signed_vma tmp;
-  bfd_signed_vma lowest_valid = bed->can_refcount;
+  struct elf_link_hash_table *htab;
 
   /* Copy down any references that we may have already seen to the
      symbol which just became indirect.  */
@@ -1480,33 +1479,32 @@ _bfd_elf_link_hash_copy_indirect (const 
 
   /* Copy over the global and procedure linkage table refcount entries.
      These may have been already set up by a check_relocs routine.  */
-  tmp = dir->got.refcount;
-  if (tmp < lowest_valid)
+  htab = elf_hash_table (info);
+  if (ind->got.refcount > htab->init_got_refcount.refcount)
     {
-      dir->got.refcount = ind->got.refcount;
-      ind->got.refcount = tmp;
+      if (dir->got.refcount < 0)
+	dir->got.refcount = 0;
+      dir->got.refcount += ind->got.refcount;
+      ind->got.refcount = htab->init_got_refcount.refcount;
     }
-  else
-    BFD_ASSERT (ind->got.refcount < lowest_valid);
 
-  tmp = dir->plt.refcount;
-  if (tmp < lowest_valid)
+  if (ind->plt.refcount > htab->init_plt_refcount.refcount)
     {
-      dir->plt.refcount = ind->plt.refcount;
-      ind->plt.refcount = tmp;
+      if (dir->plt.refcount < 0)
+	dir->plt.refcount = 0;
+      dir->plt.refcount += ind->plt.refcount;
+      ind->plt.refcount = htab->init_plt_refcount.refcount;
     }
-  else
-    BFD_ASSERT (ind->plt.refcount < lowest_valid);
 
-  if (dir->dynindx == -1)
+  if (ind->dynindx != -1)
     {
+      if (dir->dynindx != -1)
+	_bfd_elf_strtab_delref (htab->dynstr, dir->dynstr_index);
       dir->dynindx = ind->dynindx;
       dir->dynstr_index = ind->dynstr_index;
       ind->dynindx = -1;
       ind->dynstr_index = 0;
     }
-  else
-    BFD_ASSERT (ind->dynindx == -1);
 }
 
 void
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.59
diff -u -p -r1.59 elf32-arm.c
--- bfd/elf32-arm.c	19 Oct 2005 15:40:23 -0000	1.59
+++ bfd/elf32-arm.c	25 Oct 2005 12:59:21 -0000
@@ -1793,7 +1793,7 @@ elf32_arm_create_dynamic_sections (bfd *
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-elf32_arm_copy_indirect_symbol (const struct elf_backend_data *bed,
+elf32_arm_copy_indirect_symbol (struct bfd_link_info *info,
 				struct elf_link_hash_entry *dir,
 				struct elf_link_hash_entry *ind)
 {
@@ -1809,10 +1809,7 @@ elf32_arm_copy_indirect_symbol (const st
 	  struct elf32_arm_relocs_copied **pp;
 	  struct elf32_arm_relocs_copied *p;
 
-	  if (ind->root.type == bfd_link_hash_indirect)
-	    abort ();
-
-	  /* Add reloc counts against the weak sym to the strong sym
+	  /* Add reloc counts against the indirect sym to the direct sym
 	     list.  Merge any entries against the same section.  */
 	  for (pp = &eind->relocs_copied; (p = *pp) != NULL; )
 	    {
@@ -1836,16 +1833,9 @@ elf32_arm_copy_indirect_symbol (const st
       eind->relocs_copied = NULL;
     }
 
-  /* If the direct symbol already has an associated PLT entry, the
-     indirect symbol should not.  If it doesn't, swap refcount information
-     from the indirect symbol.  */
-  if (edir->plt_thumb_refcount == 0)
-    {
-      edir->plt_thumb_refcount = eind->plt_thumb_refcount;
-      eind->plt_thumb_refcount = 0;
-    }
-  else
-    BFD_ASSERT (eind->plt_thumb_refcount == 0);
+  /* Copy over PLT info.  */
+  edir->plt_thumb_refcount += eind->plt_thumb_refcount;
+  eind->plt_thumb_refcount = 0;
 
   if (ind->root.type == bfd_link_hash_indirect
       && dir->got.refcount <= 0)
@@ -1854,7 +1844,7 @@ elf32_arm_copy_indirect_symbol (const st
       eind->tls_type = GOT_UNKNOWN;
     }
 
-  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
 /* Create an ARM elf linker hash table.  */
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.139
diff -u -p -r1.139 elf32-hppa.c
--- bfd/elf32-hppa.c	6 Oct 2005 19:21:13 -0000	1.139
+++ bfd/elf32-hppa.c	25 Oct 2005 12:59:23 -0000
@@ -1004,7 +1004,7 @@ elf32_hppa_create_dynamic_sections (bfd 
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-elf32_hppa_copy_indirect_symbol (const struct elf_backend_data *bed,
+elf32_hppa_copy_indirect_symbol (struct bfd_link_info *info,
 				 struct elf_link_hash_entry *eh_dir,
 				 struct elf_link_hash_entry *eh_ind)
 {
@@ -1020,16 +1020,15 @@ elf32_hppa_copy_indirect_symbol (const s
 	  struct elf32_hppa_dyn_reloc_entry **hdh_pp;
 	  struct elf32_hppa_dyn_reloc_entry *hdh_p;
 
-	  if (eh_ind->root.type == bfd_link_hash_indirect)
-	    abort ();
-
-	  /* Add reloc counts against the weak sym to the strong sym
+	  /* Add reloc counts against the indirect sym to the direct sym
 	     list.  Merge any entries against the same section.  */
 	  for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
 	    {
 	      struct elf32_hppa_dyn_reloc_entry *hdh_q;
 
-	      for (hdh_q = hh_dir->dyn_relocs; hdh_q != NULL; hdh_q = hdh_q->hdh_next)
+	      for (hdh_q = hh_dir->dyn_relocs;
+		   hdh_q != NULL;
+		   hdh_q = hdh_q->hdh_next)
 		if (hdh_q->sec == hdh_p->sec)
 		  {
 #if RELATIVE_DYNRELOCS
@@ -1062,7 +1061,7 @@ elf32_hppa_copy_indirect_symbol (const s
       eh_dir->needs_plt |= eh_ind->needs_plt;
     }
   else
-   _bfd_elf_link_hash_copy_indirect (bed, eh_dir, eh_ind);
+   _bfd_elf_link_hash_copy_indirect (info, eh_dir, eh_ind);
 }
 
 /* Look through the relocs for a section during the first phase, and
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.149
diff -u -p -r1.149 elf32-i386.c
--- bfd/elf32-i386.c	31 Aug 2005 23:45:45 -0000	1.149
+++ bfd/elf32-i386.c	25 Oct 2005 12:59:25 -0000
@@ -772,7 +772,7 @@ elf_i386_create_dynamic_sections (bfd *d
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-elf_i386_copy_indirect_symbol (const struct elf_backend_data *bed,
+elf_i386_copy_indirect_symbol (struct bfd_link_info *info,
 			       struct elf_link_hash_entry *dir,
 			       struct elf_link_hash_entry *ind)
 {
@@ -788,10 +788,7 @@ elf_i386_copy_indirect_symbol (const str
 	  struct elf_i386_dyn_relocs **pp;
 	  struct elf_i386_dyn_relocs *p;
 
-	  if (ind->root.type == bfd_link_hash_indirect)
-	    abort ();
-
-	  /* Add reloc counts against the weak sym to the strong sym
+	  /* Add reloc counts against the indirect sym to the direct sym
 	     list.  Merge any entries against the same section.  */
 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
 	    {
@@ -836,7 +833,7 @@ elf_i386_copy_indirect_symbol (const str
       dir->pointer_equality_needed |= ind->pointer_equality_needed;
     }
   else
-    _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+    _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
 static int
Index: bfd/elf32-m32r.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m32r.c,v
retrieving revision 1.74
diff -u -p -r1.74 elf32-m32r.c
--- bfd/elf32-m32r.c	6 Oct 2005 19:21:13 -0000	1.74
+++ bfd/elf32-m32r.c	25 Oct 2005 12:59:27 -0000
@@ -1755,7 +1755,7 @@ m32r_elf_create_dynamic_sections (bfd *a
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-m32r_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+m32r_elf_copy_indirect_symbol (struct bfd_link_info *info,
                                struct elf_link_hash_entry *dir,
                                struct elf_link_hash_entry *ind)
 {
@@ -1772,10 +1772,7 @@ m32r_elf_copy_indirect_symbol (const str
           struct elf_m32r_dyn_relocs **pp;
           struct elf_m32r_dyn_relocs *p;
 
-          if (ind->root.type == bfd_link_hash_indirect)
-            abort ();
-
-          /* Add reloc counts against the weak sym to the strong sym
+          /* Add reloc counts against the indirect sym to the direct sym
              list.  Merge any entries against the same section.  */
           for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
             {
@@ -1799,7 +1796,7 @@ m32r_elf_copy_indirect_symbol (const str
       eind->dyn_relocs = NULL;
     }
 
-  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
 
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.182
diff -u -p -r1.182 elf32-ppc.c
--- bfd/elf32-ppc.c	24 Oct 2005 04:32:50 -0000	1.182
+++ bfd/elf32-ppc.c	25 Oct 2005 12:59:30 -0000
@@ -2565,12 +2565,11 @@ ppc_elf_create_dynamic_sections (bfd *ab
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-ppc_elf_copy_indirect_symbol (const struct elf_backend_data *bed ATTRIBUTE_UNUSED,
+ppc_elf_copy_indirect_symbol (struct bfd_link_info *info,
 			      struct elf_link_hash_entry *dir,
 			      struct elf_link_hash_entry *ind)
 {
   struct ppc_elf_link_hash_entry *edir, *eind;
-  bfd_signed_vma tmp;
 
   edir = (struct ppc_elf_link_hash_entry *) dir;
   eind = (struct ppc_elf_link_hash_entry *) ind;
@@ -2582,10 +2581,7 @@ ppc_elf_copy_indirect_symbol (const stru
 	  struct ppc_elf_dyn_relocs **pp;
 	  struct ppc_elf_dyn_relocs *p;
 
-	  if (ind->root.type == bfd_link_hash_indirect)
-	    abort ();
-
-	  /* Add reloc counts against the weak sym to the strong sym
+	  /* Add reloc counts against the indirect sym to the direct sym
 	     list.  Merge any entries against the same section.  */
 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
 	    {
@@ -2631,14 +2627,8 @@ ppc_elf_copy_indirect_symbol (const stru
 
   /* Copy over the GOT refcount entries that we may have already seen to
      the symbol which just became indirect.  */
-  tmp = edir->elf.got.refcount;
-  if (tmp < 1)
-    {
-      edir->elf.got.refcount = eind->elf.got.refcount;
-      eind->elf.got.refcount = tmp;
-    }
-  else
-    BFD_ASSERT (eind->elf.got.refcount < 1);
+  edir->elf.got.refcount += eind->elf.got.refcount;
+  eind->elf.got.refcount = 0;
 
   /* And plt entries.  */
   if (eind->elf.plt.plist != NULL)
@@ -2669,15 +2659,16 @@ ppc_elf_copy_indirect_symbol (const stru
       eind->elf.plt.plist = NULL;
     }
 
-  if (edir->elf.dynindx == -1)
+  if (eind->elf.dynindx != -1)
     {
+      if (edir->elf.dynindx != -1)
+	_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+				edir->elf.dynstr_index);
       edir->elf.dynindx = eind->elf.dynindx;
       edir->elf.dynstr_index = eind->elf.dynstr_index;
       eind->elf.dynindx = -1;
       eind->elf.dynstr_index = 0;
     }
-  else
-    BFD_ASSERT (eind->elf.dynindx == -1);
 }
 
 /* Return 1 if target is one of ours.  */
Index: bfd/elf32-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-s390.c,v
retrieving revision 1.78
diff -u -p -r1.78 elf32-s390.c
--- bfd/elf32-s390.c	6 Oct 2005 19:21:14 -0000	1.78
+++ bfd/elf32-s390.c	25 Oct 2005 12:59:33 -0000
@@ -41,7 +41,7 @@ static bfd_boolean create_got_section
 static bfd_boolean elf_s390_create_dynamic_sections
   PARAMS((bfd *, struct bfd_link_info *));
 static void elf_s390_copy_indirect_symbol
-  PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *,
+  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *,
 	   struct elf_link_hash_entry *));
 static bfd_boolean elf_s390_check_relocs
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
@@ -855,8 +855,8 @@ elf_s390_create_dynamic_sections (dynobj
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-elf_s390_copy_indirect_symbol (bed, dir, ind)
-     const struct elf_backend_data *bed;
+elf_s390_copy_indirect_symbol (info, dir, ind)
+     struct bfd_link_info *info;
      struct elf_link_hash_entry *dir, *ind;
 {
   struct elf_s390_link_hash_entry *edir, *eind;
@@ -871,10 +871,7 @@ elf_s390_copy_indirect_symbol (bed, dir,
 	  struct elf_s390_dyn_relocs **pp;
 	  struct elf_s390_dyn_relocs *p;
 
-	  if (ind->root.type == bfd_link_hash_indirect)
-	    abort ();
-
-	  /* Add reloc counts against the weak sym to the strong sym
+	  /* Add reloc counts against the indirect sym to the direct sym
 	     list.  Merge any entries against the same section.  */
 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
 	    {
@@ -918,7 +915,7 @@ elf_s390_copy_indirect_symbol (bed, dir,
       dir->needs_plt |= ind->needs_plt;
     }
   else
-    _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+    _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
 static int
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.130
diff -u -p -r1.130 elf32-sh.c
--- bfd/elf32-sh.c	6 Oct 2005 19:21:14 -0000	1.130
+++ bfd/elf32-sh.c	25 Oct 2005 12:59:35 -0000
@@ -6063,14 +6063,11 @@ sh_elf_gc_sweep_hook (bfd *abfd, struct 
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-sh_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+sh_elf_copy_indirect_symbol (struct bfd_link_info *info,
 			     struct elf_link_hash_entry *dir,
 			     struct elf_link_hash_entry *ind)
 {
   struct elf_sh_link_hash_entry *edir, *eind;
-#ifdef INCLUDE_SHMEDIA
-  bfd_signed_vma tmp;
-#endif
 
   edir = (struct elf_sh_link_hash_entry *) dir;
   eind = (struct elf_sh_link_hash_entry *) ind;
@@ -6082,9 +6079,7 @@ sh_elf_copy_indirect_symbol (const struc
 	  struct elf_sh_dyn_relocs **pp;
 	  struct elf_sh_dyn_relocs *p;
 
-	  BFD_ASSERT (ind->root.type != bfd_link_hash_indirect);
-
-	  /* Add reloc counts against the weak sym to the strong sym
+	  /* Add reloc counts against the indirect sym to the direct sym
 	     list.  Merge any entries against the same section.  */
 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
 	    {
@@ -6110,14 +6105,8 @@ sh_elf_copy_indirect_symbol (const struc
   edir->gotplt_refcount = eind->gotplt_refcount;
   eind->gotplt_refcount = 0;
 #ifdef INCLUDE_SHMEDIA
-  tmp = edir->datalabel_got.refcount;
-  if (tmp < 1)
-    {
-      edir->datalabel_got.refcount = eind->datalabel_got.refcount;
-      eind->datalabel_got.refcount = tmp;
-    }
-  else
-    BFD_ASSERT (eind->datalabel_got.refcount < 1);
+  edir->datalabel_got.refcount += eind->datalabel_got.refcount;
+  eind->datalabel_got.refcount = 0;
 #endif
 
   if (ind->root.type == bfd_link_hash_indirect
@@ -6139,7 +6128,7 @@ sh_elf_copy_indirect_symbol (const struc
       dir->needs_plt |= ind->needs_plt;
     }
   else
-    _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+    _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
 static int
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.224
diff -u -p -r1.224 elf64-ppc.c
--- bfd/elf64-ppc.c	23 Oct 2005 13:12:09 -0000	1.224
+++ bfd/elf64-ppc.c	25 Oct 2005 12:59:41 -0000
@@ -3844,10 +3844,9 @@ move_plt_plist (struct ppc_link_hash_ent
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-ppc64_elf_copy_indirect_symbol
-  (const struct elf_backend_data *bed ATTRIBUTE_UNUSED,
-   struct elf_link_hash_entry *dir,
-   struct elf_link_hash_entry *ind)
+ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info,
+				struct elf_link_hash_entry *dir,
+				struct elf_link_hash_entry *ind)
 {
   struct ppc_link_hash_entry *edir, *eind;
 
@@ -3862,10 +3861,7 @@ ppc64_elf_copy_indirect_symbol
 	  struct ppc_dyn_relocs **pp;
 	  struct ppc_dyn_relocs *p;
 
-	  if (eind->elf.root.type == bfd_link_hash_indirect)
-	    abort ();
-
-	  /* Add reloc counts against the weak sym to the strong sym
+	  /* Add reloc counts against the indirect sym to the direct sym
 	     list.  Merge any entries against the same section.  */
 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
 	    {
@@ -3945,15 +3941,16 @@ ppc64_elf_copy_indirect_symbol
   /* And plt entries.  */
   move_plt_plist (eind, edir);
 
-  if (edir->elf.dynindx == -1)
+  if (eind->elf.dynindx != -1)
     {
+      if (edir->elf.dynindx != -1)
+	_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+				edir->elf.dynstr_index);
       edir->elf.dynindx = eind->elf.dynindx;
       edir->elf.dynstr_index = eind->elf.dynstr_index;
       eind->elf.dynindx = -1;
       eind->elf.dynstr_index = 0;
     }
-  else
-    BFD_ASSERT (eind->elf.dynindx == -1);
 }
 
 /* Find the function descriptor hash entry from the given function code
Index: bfd/elf64-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-s390.c,v
retrieving revision 1.78
diff -u -p -r1.78 elf64-s390.c
--- bfd/elf64-s390.c	6 Oct 2005 19:21:14 -0000	1.78
+++ bfd/elf64-s390.c	25 Oct 2005 12:59:43 -0000
@@ -41,7 +41,7 @@ static bfd_boolean create_got_section
 static bfd_boolean elf_s390_create_dynamic_sections
   PARAMS((bfd *, struct bfd_link_info *));
 static void elf_s390_copy_indirect_symbol
-  PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *,
+  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *,
 	   struct elf_link_hash_entry *));
 static bfd_boolean elf_s390_check_relocs
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
@@ -808,8 +808,8 @@ elf_s390_create_dynamic_sections (dynobj
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-elf_s390_copy_indirect_symbol (bed, dir, ind)
-     const struct elf_backend_data *bed;
+elf_s390_copy_indirect_symbol (info, dir, ind)
+     struct bfd_link_info *info;
      struct elf_link_hash_entry *dir, *ind;
 {
   struct elf_s390_link_hash_entry *edir, *eind;
@@ -824,10 +824,7 @@ elf_s390_copy_indirect_symbol (bed, dir,
 	  struct elf_s390_dyn_relocs **pp;
 	  struct elf_s390_dyn_relocs *p;
 
-	  if (ind->root.type == bfd_link_hash_indirect)
-	    abort ();
-
-	  /* Add reloc counts against the weak sym to the strong sym
+	  /* Add reloc counts against the indirect sym to the direct sym
 	     list.  Merge any entries against the same section.  */
 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
 	    {
@@ -871,7 +868,7 @@ elf_s390_copy_indirect_symbol (bed, dir,
       dir->needs_plt |= ind->needs_plt;
     }
   else
-    _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+    _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
 static int
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.107
diff -u -p -r1.107 elf64-x86-64.c
--- bfd/elf64-x86-64.c	31 Aug 2005 23:45:46 -0000	1.107
+++ bfd/elf64-x86-64.c	25 Oct 2005 12:59:44 -0000
@@ -525,7 +525,7 @@ elf64_x86_64_create_dynamic_sections (bf
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 static void
-elf64_x86_64_copy_indirect_symbol (const struct elf_backend_data *bed,
+elf64_x86_64_copy_indirect_symbol (struct bfd_link_info *info,
 				   struct elf_link_hash_entry *dir,
 				   struct elf_link_hash_entry *ind)
 {
@@ -541,10 +541,7 @@ elf64_x86_64_copy_indirect_symbol (const
 	  struct elf64_x86_64_dyn_relocs **pp;
 	  struct elf64_x86_64_dyn_relocs *p;
 
-	  if (ind->root.type == bfd_link_hash_indirect)
-	    abort ();
-
-	  /* Add reloc counts against the weak sym to the strong sym
+	  /* Add reloc counts against the indirect sym to the direct sym
 	     list.  Merge any entries against the same section.  */
 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
 	    {
@@ -589,7 +586,7 @@ elf64_x86_64_copy_indirect_symbol (const
       dir->pointer_equality_needed |= ind->pointer_equality_needed;
     }
   else
-    _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+    _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
 static bfd_boolean
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.195
diff -u -p -r1.195 elflink.c
--- bfd/elflink.c	24 Oct 2005 11:24:31 -0000	1.195
+++ bfd/elflink.c	25 Oct 2005 12:59:50 -0000
@@ -1283,7 +1283,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
       flip->root.type = h->root.type;
       h->root.type = bfd_link_hash_indirect;
       h->root.u.i.link = (struct bfd_link_hash_entry *) flip;
-      (*bed->elf_backend_copy_indirect_symbol) (bed, flip, h);
+      (*bed->elf_backend_copy_indirect_symbol) (info, flip, h);
       flip->root.u.undef.abfd = h->root.u.undef.abfd;
       if (h->def_dynamic)
 	{
@@ -1437,7 +1437,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
       struct elf_link_hash_entry *ht;
 
       ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
-      (*bed->elf_backend_copy_indirect_symbol) (bed, ht, hi);
+      (*bed->elf_backend_copy_indirect_symbol) (info, ht, hi);
 
       /* See if the new flags lead us to realize that the symbol must
 	 be dynamic.  */
@@ -1506,7 +1506,7 @@ nondefault:
 
       if (hi->root.type == bfd_link_hash_indirect)
 	{
-	  (*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
+	  (*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
 
 	  /* See if the new flags lead us to realize that the symbol
 	     must be dynamic.  */
@@ -2317,7 +2317,7 @@ _bfd_elf_fix_symbol_flags (struct elf_li
 	  const struct elf_backend_data *bed;
 
 	  bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
-	  (*bed->elf_backend_copy_indirect_symbol) (bed, weakdef, h);
+	  (*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, h);
 	}
     }
 
@@ -4139,7 +4139,7 @@ elf_link_add_object_symbols (bfd *abfd, 
 	      (*bed->elf_backend_hide_symbol) (info, hi, TRUE);
 	      hi->root.type = bfd_link_hash_indirect;
 	      hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
-	      (*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
+	      (*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
 	      sym_hash = elf_sym_hashes (abfd);
 	      if (sym_hash)
 		for (symidx = 0; symidx < extsymcount; ++symidx)
Index: bfd/elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.174
diff -u -p -r1.174 elfxx-ia64.c
--- bfd/elfxx-ia64.c	9 Sep 2005 05:11:51 -0000	1.174
+++ bfd/elfxx-ia64.c	25 Oct 2005 12:59:53 -0000
@@ -216,7 +216,7 @@ static struct bfd_hash_entry *elfNN_ia64
   PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
 	   const char *string));
 static void elfNN_ia64_hash_copy_indirect
-  PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *,
+  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *,
 	   struct elf_link_hash_entry *));
 static void elfNN_ia64_hash_hide_symbol
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
@@ -1798,8 +1798,8 @@ elfNN_ia64_new_elf_hash_entry (entry, ta
 }
 
 static void
-elfNN_ia64_hash_copy_indirect (bed, xdir, xind)
-     const struct elf_backend_data *bed ATTRIBUTE_UNUSED;
+elfNN_ia64_hash_copy_indirect (info, xdir, xind)
+     struct bfd_link_info *info;
      struct elf_link_hash_entry *xdir, *xind;
 {
   struct elfNN_ia64_link_hash_entry *dir, *ind;
@@ -1821,29 +1821,34 @@ elfNN_ia64_hash_copy_indirect (bed, xdir
   /* Copy over the got and plt data.  This would have been done
      by check_relocs.  */
 
-  if (dir->info == NULL)
+  if (ind->info != NULL)
     {
       struct elfNN_ia64_dyn_sym_info *dyn_i;
+      struct elfNN_ia64_dyn_sym_info **pdyn;
 
-      dir->info = dyn_i = ind->info;
+      pdyn = &dir->info;
+      while ((dyn_i = *pdyn) != NULL)
+	pdyn = &dyn_i->next;
+      *pdyn = dyn_i = ind->info;
       ind->info = NULL;
 
       /* Fix up the dyn_sym_info pointers to the global symbol.  */
       for (; dyn_i; dyn_i = dyn_i->next)
 	dyn_i->h = &dir->root;
     }
-  BFD_ASSERT (ind->info == NULL);
 
   /* Copy over the dynindx.  */
 
-  if (dir->root.dynindx == -1)
+  if (ind->root.dynindx != -1)
     {
+      if (dir->root.dynindx != -1)
+	_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+				dir->root.dynstr_index);
       dir->root.dynindx = ind->root.dynindx;
       dir->root.dynstr_index = ind->root.dynstr_index;
       ind->root.dynindx = -1;
       ind->root.dynstr_index = 0;
     }
-  BFD_ASSERT (ind->root.dynindx == -1);
 }
 
 static void
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.151
diff -u -p -r1.151 elfxx-mips.c
--- bfd/elfxx-mips.c	6 Oct 2005 19:21:14 -0000	1.151
+++ bfd/elfxx-mips.c	25 Oct 2005 12:59:58 -0000
@@ -8387,13 +8387,13 @@ _bfd_mips_elf_gc_sweep_hook (bfd *abfd A
    _bfd_elf_link_hash_copy_indirect copy the flags for us.  */
 
 void
-_bfd_mips_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+_bfd_mips_elf_copy_indirect_symbol (struct bfd_link_info *info,
 				    struct elf_link_hash_entry *dir,
 				    struct elf_link_hash_entry *ind)
 {
   struct mips_elf_link_hash_entry *dirmips, *indmips;
 
-  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 
   if (ind->root.type != bfd_link_hash_indirect)
     return;
@@ -8408,8 +8408,6 @@ _bfd_mips_elf_copy_indirect_symbol (cons
 
   if (dirmips->tls_type == 0)
     dirmips->tls_type = indmips->tls_type;
-  else
-    BFD_ASSERT (indmips->tls_type == 0);
 }
 
 void
Index: bfd/elfxx-mips.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.h,v
retrieving revision 1.29
diff -u -p -r1.29 elfxx-mips.h
--- bfd/elfxx-mips.h	8 Jul 2005 00:26:53 -0000	1.29
+++ bfd/elfxx-mips.h	25 Oct 2005 12:59:59 -0000
@@ -72,7 +72,7 @@ extern asection * _bfd_mips_elf_gc_mark_
 extern bfd_boolean _bfd_mips_elf_gc_sweep_hook
   (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
 extern void _bfd_mips_elf_copy_indirect_symbol
-  (const struct elf_backend_data *, struct elf_link_hash_entry *,
+  (struct bfd_link_info *, struct elf_link_hash_entry *,
    struct elf_link_hash_entry *);
 extern void _bfd_mips_elf_hide_symbol
   (struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean);
Index: bfd/elfxx-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.c,v
retrieving revision 1.14
diff -u -p -r1.14 elfxx-sparc.c
--- bfd/elfxx-sparc.c	6 Oct 2005 19:21:14 -0000	1.14
+++ bfd/elfxx-sparc.c	25 Oct 2005 13:00:00 -0000
@@ -881,7 +881,7 @@ _bfd_sparc_elf_create_dynamic_sections (
 /* Copy the extra info we tack onto an elf_link_hash_entry.  */
 
 void
-_bfd_sparc_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+_bfd_sparc_elf_copy_indirect_symbol (struct bfd_link_info *info,
 				     struct elf_link_hash_entry *dir,
 				     struct elf_link_hash_entry *ind)
 {
@@ -897,10 +897,7 @@ _bfd_sparc_elf_copy_indirect_symbol (con
 	  struct _bfd_sparc_elf_dyn_relocs **pp;
 	  struct _bfd_sparc_elf_dyn_relocs *p;
 
-	  if (ind->root.type == bfd_link_hash_indirect)
-	    abort ();
-
-	  /* Add reloc counts against the weak sym to the strong sym
+	  /* Add reloc counts against the indirect sym to the direct sym
 	     list.  Merge any entries against the same section.  */
 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
 	    {
@@ -930,7 +927,7 @@ _bfd_sparc_elf_copy_indirect_symbol (con
       edir->tls_type = eind->tls_type;
       eind->tls_type = GOT_UNKNOWN;
     }
-  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+  _bfd_elf_link_hash_copy_indirect (info, dir, ind);
 }
 
 static int
Index: bfd/elfxx-sparc.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.h,v
retrieving revision 1.4
diff -u -p -r1.4 elfxx-sparc.h
--- bfd/elfxx-sparc.h	4 May 2005 15:53:31 -0000	1.4
+++ bfd/elfxx-sparc.h	25 Oct 2005 13:00:00 -0000
@@ -97,7 +97,7 @@ extern struct bfd_link_hash_table *_bfd_
 extern bfd_boolean _bfd_sparc_elf_create_dynamic_sections
   (bfd *, struct bfd_link_info *);
 extern void _bfd_sparc_elf_copy_indirect_symbol
-  (const struct elf_backend_data *,
+  (struct bfd_link_info *,
    struct elf_link_hash_entry *,
    struct elf_link_hash_entry *);
 extern bfd_boolean _bfd_sparc_elf_check_relocs

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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