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]
Other format: [Raw text]

Re: ppc32 linker bug


On Thu, Apr 24, 2003 at 11:14:14PM +0930, Alan Modra wrote:
> Fixed by tweaking copy_indirect_symbol.  I'm taking the opportunity
> to flush a few other minor changes.
> 
> 	* elf32-ppc.c: Formatting and comment fixes.
> 	(ELIMINATE_COPY_RELOCS): Move before ppc_elf_copy_indirect_symbol.
> 	(ppc_elf_copy_indirect_symbol): Copy flags here for weakdefs.

The last ELIMINATE_COPY_RELOCS change for ppc wasn't quite right, as I
missed checking for copy_indirect_symbol being called from
elf_adjust_dynamic_symbol.  Just putting the intention in a comment
doesn't work very well.  :)  I've also enabled the same code for x86
and ppc64.  ppc64 in fact wasn't ever generating copy relocs, which
didn't matter very much as gcc code could always use a dynamic reloc
instead.  However, they might be needed in assembly code.

bfd/ChangeLog
	* elf32-ppc.c (ppc_elf_copy_indirect_symbol): Test whether the
	weakdef sym has already been adjusted before treating it specially.
	* elf32-i386.c (elf_i386_copy_indirect_symbol): Don't copy
	ELF_LINK_NON_GOT_REF for weakdefs when symbol already adjusted.
	* elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
	(ppc64_elf_check_relocs): Set ELF_LINK_NON_GOT_REF.

Applying mainline and branch.

Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.75
diff -u -p -r1.75 elf32-ppc.c
--- bfd/elf32-ppc.c	24 Apr 2003 13:44:10 -0000	1.75
+++ bfd/elf32-ppc.c	1 May 2003 09:48:45 -0000
@@ -374,7 +374,9 @@ ppc_elf_copy_indirect_symbol (bed, dir, 
 
   edir->tls_mask |= eind->tls_mask;
 
-  if (ELIMINATE_COPY_RELOCS && ind->root.type != bfd_link_hash_indirect)
+  if (ELIMINATE_COPY_RELOCS
+      && ind->root.type != bfd_link_hash_indirect
+      && (dir->elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0)
     /* If called to transfer flags for a weakdef during processing
        of elf_adjust_dynamic_symbol, don't copy ELF_LINK_NON_GOT_REF.
        We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.97
diff -u -p -r1.97 elf32-i386.c
--- bfd/elf32-i386.c	23 Apr 2003 05:21:29 -0000	1.97
+++ bfd/elf32-i386.c	1 May 2003 09:48:42 -0000
@@ -838,7 +838,19 @@ elf_i386_copy_indirect_symbol (bed, dir,
       edir->tls_type = eind->tls_type;
       eind->tls_type = GOT_UNKNOWN;
     }
-  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+
+  if (ELIMINATE_COPY_RELOCS
+      && ind->root.type != bfd_link_hash_indirect
+      && (dir->elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0)
+    /* If called to transfer flags for a weakdef during processing
+       of elf_adjust_dynamic_symbol, don't copy ELF_LINK_NON_GOT_REF.
+       We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
+    dir->elf_link_hash_flags |=
+      (ind->elf_link_hash_flags & (ELF_LINK_HASH_REF_DYNAMIC
+				   | ELF_LINK_HASH_REF_REGULAR
+				   | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+  else
+    _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
 }
 
 static int
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.92
diff -u -p -r1.92 elf64-ppc.c
--- bfd/elf64-ppc.c	10 Mar 2003 23:25:13 -0000	1.92
+++ bfd/elf64-ppc.c	1 May 2003 09:48:49 -0000
@@ -3272,6 +3272,7 @@ ppc64_elf_copy_indirect_symbol (bed, dir
      struct elf_link_hash_entry *dir, *ind;
 {
   struct ppc_link_hash_entry *edir, *eind;
+  flagword mask;
 
   edir = (struct ppc_link_hash_entry *) dir;
   eind = (struct ppc_link_hash_entry *) ind;
@@ -3316,20 +3317,24 @@ ppc64_elf_copy_indirect_symbol (bed, dir
   edir->is_entry |= eind->is_entry;
   edir->tls_mask |= eind->tls_mask;
 
-  /* Copy down any references that we may have already seen to the
-     symbol which just became indirect.  */
-  edir->elf.elf_link_hash_flags |=
-    (eind->elf.elf_link_hash_flags
-     & (ELF_LINK_HASH_REF_DYNAMIC
-	| ELF_LINK_HASH_REF_REGULAR
-	| ELF_LINK_HASH_REF_REGULAR_NONWEAK
-	| ELF_LINK_NON_GOT_REF));
+  mask = (ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_HASH_REF_REGULAR
+	  | ELF_LINK_HASH_REF_REGULAR_NONWEAK | ELF_LINK_NON_GOT_REF);
+  /* If called to transfer flags for a weakdef during processing
+     of elf_adjust_dynamic_symbol, don't copy ELF_LINK_NON_GOT_REF.
+     We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
+  if (ELIMINATE_COPY_RELOCS
+      && eind->elf.root.type != bfd_link_hash_indirect
+      && (edir->elf.elf_link_hash_flags & ELF_LINK_HASH_DYNAMIC_ADJUSTED) != 0)
+    mask &= ~ELF_LINK_NON_GOT_REF;
+
+  edir->elf.elf_link_hash_flags |= eind->elf.elf_link_hash_flags & mask;
 
   /* If we were called to copy over info for a weak sym, that's all.  */
   if (eind->elf.root.type != bfd_link_hash_indirect)
     return;
 
-  /* Copy over got entries.  */
+  /* Copy over got entries that we may have already seen to the
+     symbol which just became indirect.  */
   if (eind->elf.got.glist != NULL)
     {
       if (edir->elf.got.glist != NULL)
@@ -3877,6 +3882,10 @@ ppc64_elf_check_relocs (abfd, info, sec,
 	case R_PPC64_UADDR32:
 	case R_PPC64_UADDR64:
 	case R_PPC64_TOC:
+	  if (h != NULL && !info->shared)
+	    /* We may need a copy reloc.  */
+	    h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
+
 	  /* Don't propagate .opd relocs.  */
 	  if (NO_OPD_RELOCS && opd_sym_map != NULL)
 	    break;

-- 
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]