This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
A weak symbol patch
- To: ian@cygnus.com (Ian Lance Taylor), binutils@sourceware.cygnus.com
- Subject: A weak symbol patch
- From: hjl@varesearch.com (H.J. Lu)
- Date: Tue, 6 Jul 1999 13:34:12 -0700 (PDT)
- Cc: geoffk@ozemail.com.au
Hi, Ian,
I believe there is a linker bug regarding the weak symbol handling. I
have sent 2 testcases for the bug. Here is a patch. Could you please
take a look?
Thanks.
--
H.J. Lu (hjl@gnu.org)
---
Tue Jul 6 13:10:00 1998 H.J. Lu (hjl@gnu.org)
* elflink.h (elf_merge_symbol): No type change if the new
definition is weak and the old one is strong or common.
(elf_merge_symbol): Use the the strong definition in a dynamic
object if the old one is weak.
(elf_merge_symbol): Don't override the strong definition in
a dynamic object with a weak one from a regular object.
(elf_link_add_object_symbols): When a definition in a dynamic
object is used, clear ELF_LINK_HASH_DEF_REGULAR and set
ELF_LINK_HASH_REF_REGULAR if ELF_LINK_HASH_DEF_REGULAR is set.
Index: elflink.h
===================================================================
RCS file: /work/cvs/gnu/binutils/bfd/elflink.h,v
retrieving revision 1.1.1.3
diff -u -p -r1.1.1.3 elflink.h
--- elflink.h 1999/06/27 01:02:24 1.1.1.3
+++ elflink.h 1999/07/06 20:17:26
@@ -441,7 +441,9 @@ elf_merge_symbol (abfd, info, name, sym,
if (h->root.type == bfd_link_hash_defweak
|| h->root.type == bfd_link_hash_undefweak
- || bind == STB_WEAK)
+ || (bind == STB_WEAK
+ && h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_common))
*type_change_ok = true;
/* It's OK to change the size if either the existing symbol or the
@@ -497,6 +499,9 @@ elf_merge_symbol (abfd, info, name, sym,
&& (bind == STB_WEAK
|| ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
{
+ if (bind != STB_WEAK && h->root.type == bfd_link_hash_defweak)
+ return true;
+
*override = true;
newdef = false;
newdyncommon = false;
@@ -550,6 +555,12 @@ elf_merge_symbol (abfd, info, name, sym,
&& olddef
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
{
+ if (bind == STB_WEAK)
+ {
+ *override = true;
+ return true;
+ }
+
/* Change the hash table entry to undefined, and let
_bfd_generic_link_add_one_symbol do the right thing with the
new definition. */
@@ -1343,7 +1354,14 @@ elf_link_add_object_symbols (abfd, info)
if (! definition)
new_flag = ELF_LINK_HASH_REF_DYNAMIC;
else
- new_flag = ELF_LINK_HASH_DEF_DYNAMIC;
+ {
+ new_flag = ELF_LINK_HASH_DEF_DYNAMIC;
+ if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
+ {
+ h->elf_link_hash_flags &= ~ELF_LINK_HASH_DEF_REGULAR;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
+ }
+ }
if ((old_flags & (ELF_LINK_HASH_DEF_REGULAR
| ELF_LINK_HASH_REF_REGULAR)) != 0
|| (h->weakdef != NULL