This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: ppc32 linker bug
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sources dot redhat dot com
- Date: Thu, 1 May 2003 19:53:44 +0930
- Subject: Re: ppc32 linker bug
- References: <20030424103700.GA16629@sunsite.ms.mff.cuni.cz> <20030424134414.GW1189@bubble.sa.bigpond.net.au>
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