From mboxrd@z Thu Jan 1 00:00:00 1970 From: hjl@varesearch.com (H.J. Lu) To: ian@cygnus.com (Ian Lance Taylor), binutils@sourceware.cygnus.com Cc: geoffk@ozemail.com.au Subject: A weak symbol patch Date: Tue, 06 Jul 1999 13:34:00 -0000 Message-id: <19990706203412.DAA553FC1@varesearch.com> X-SW-Source: 1999-q3/msg00042.html 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