This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: binutils is broken
Here's what I'm about to commit to fix the problem.
* elflink.h (elf_fix_symbol_flags): Copy flags to weakdef using
elf_backend_copy_indirect_symbol so that backend has a chance to
copy other necessary fields.
* elf-bfd.h (struct elf_backend_data): Update description of
elf_backend_copy_indirect_symbol.
* elf.c (_bfd_elf_link_hash_copy_indirect): Bail out after
copying flags if this is a weakdef.
* elfxx-ia64.c (elfNN_ia64_hash_copy_indirect): Likewise.
(elfNN_ia64_aix_add_symbol_hook): Use elf_link_hash_lookup rather
than bfd_link_hash_lookup.
* elf32-i386 (elf_i386_adjust_dynamic_symbol): Don't do copy
reloc processing for weakdefs.
* elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol): Likewise.
* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol): Likewise.
--
Alan Modra
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.96
diff -u -p -r1.96 elf.c
--- elf.c 2001/09/30 03:03:11 1.96
+++ elf.c 2001/10/03 07:48:19
@@ -986,7 +986,7 @@ _bfd_elf_link_hash_newfunc (entry, table
}
/* Copy data from an indirect symbol to its direct symbol, hiding the
- old indirect symbol. */
+ old indirect symbol. Also used for copying flags to a weakdef. */
void
_bfd_elf_link_hash_copy_indirect (dir, ind)
@@ -1003,6 +1003,9 @@ _bfd_elf_link_hash_copy_indirect (dir, i
| ELF_LINK_HASH_REF_REGULAR
| ELF_LINK_HASH_REF_REGULAR_NONWEAK
| ELF_LINK_NON_GOT_REF));
+
+ if (dir == ind->weakdef)
+ return;
/* Copy over the global and procedure linkage table refcount entries.
These may have been already set up by a check_relocs routine. */
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.51
diff -u -p -r1.51 elf32-hppa.c
--- elf32-hppa.c 2001/09/29 06:21:59 1.51
+++ elf32-hppa.c 2001/10/03 07:48:22
@@ -1855,6 +1855,7 @@ elf32_hppa_adjust_dynamic_symbol (info,
abort ();
h->root.u.def.section = h->weakdef->root.u.def.section;
h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
}
/* This is a reference to a symbol defined by a dynamic object which
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.52
diff -u -p -r1.52 elf32-i386.c
--- elf32-i386.c 2001/09/29 06:21:59 1.52
+++ elf32-i386.c 2001/10/03 07:48:24
@@ -1109,6 +1109,7 @@ elf_i386_adjust_dynamic_symbol (info, h)
|| h->weakdef->root.type == bfd_link_hash_defweak);
h->root.u.def.section = h->weakdef->root.u.def.section;
h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
}
/* This is a reference to a symbol defined by a dynamic object which
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.6
diff -u -p -r1.6 elf64-ppc.c
--- elf64-ppc.c 2001/10/02 09:22:46 1.6
+++ elf64-ppc.c 2001/10/03 07:48:27
@@ -2376,6 +2376,7 @@ ppc64_elf_adjust_dynamic_symbol (info, h
|| h->weakdef->root.type == bfd_link_hash_defweak);
h->root.u.def.section = h->weakdef->root.u.def.section;
h->root.u.def.value = h->weakdef->root.u.def.value;
+ return true;
}
/* This is a reference to a symbol defined by a dynamic object which
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.110
diff -u -p -r1.110 elflink.h
--- elflink.h 2001/09/29 12:07:00 1.110
+++ elflink.h 2001/10/03 07:48:31
@@ -3615,11 +3615,12 @@ elf_fix_symbol_flags (h, eif)
if ((weakdef->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
h->weakdef = NULL;
else
- weakdef->elf_link_hash_flags |=
- (h->elf_link_hash_flags
- & (ELF_LINK_HASH_REF_REGULAR
- | ELF_LINK_HASH_REF_REGULAR_NONWEAK
- | ELF_LINK_NON_GOT_REF));
+ {
+ struct elf_backend_data *bed;
+
+ bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
+ (*bed->elf_backend_copy_indirect_symbol) (weakdef, h);
+ }
}
return true;
Index: bfd/elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.26
diff -u -p -r1.26 elfxx-ia64.c
--- elfxx-ia64.c 2001/09/24 01:38:31 1.26
+++ elfxx-ia64.c 2001/10/03 07:48:35
@@ -1190,7 +1190,8 @@ elfNN_ia64_aix_add_symbol_hook (abfd, in
no one else should use it b/c it is undocumented. */
struct elf_link_hash_entry *h;
- h = (struct elf_link_hash_entry *) bfd_link_hash_lookup (info->hash, *namep, false, false, false);
+ h = elf_link_hash_lookup (elf_hash_table (info), *namep,
+ false, false, false);
if (h == NULL)
{
struct elf_backend_data *bed;
@@ -1522,6 +1523,9 @@ elfNN_ia64_hash_copy_indirect (xdir, xin
& (ELF_LINK_HASH_REF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
| ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+
+ if (dir == ind->weakdef)
+ return;
/* Copy over the got and plt data. This would have been done
by check_relocs. */
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.48
diff -u -p -r1.48 elf-bfd.h
--- elf-bfd.h 2001/10/02 05:58:41 1.48
+++ elf-bfd.h 2001/10/03 08:09:42
@@ -649,7 +649,10 @@ struct elf_backend_data
boolean (*) (PTR, const char *, Elf_Internal_Sym *, asection *)));
/* Copy any information related to dynamic linking from a pre-existing
- symbol IND to a newly created symbol DIR. */
+ symbol to a newly created symbol. Also called to copy flags and
+ other back-end info to a weakdef, in which case the symbol is not newly
+ created and plt/got refcounts and dynamic indices should not be
+ copied. */
void (*elf_backend_copy_indirect_symbol)
PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));