This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: A weak symbol patch
- To: ian@zembu.com (Ian Lance Taylor)
- Subject: Re: A weak symbol patch
- From: hjl@varesearch.com (H.J. Lu)
- Date: Wed, 7 Jul 1999 13:53:23 -0700 (PDT)
- Cc: binutils@sourceware.cygnus.com
>
> Date: Tue, 6 Jul 1999 13:34:12 -0700 (PDT)
> From: hjl@varesearch.com (H.J. Lu)
>
> 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?
>
> I am about to check in the appended patch, which is based on yours. I
> think this will fix your test case.
>
You missed a piece in mine. If you don't set ELF_LINK_HASH_REF_REGULAR
when clearing ELF_LINK_HASH_DEF_REGULAR, no relocation will be
generated at all and you will get a linker error:
# cc -o wfoo2 -O -g -B./ -DWEAK main.c wbar2.o libfoo.so -Wl,-rpath,.
./ld: /tmp/ccKTop3y.o: warning: unresolvable relocation against symbol `deallocate' from .text section
if deallocate is referenced and defined as weak in main.c.
It should be better to set both ELF_LINK_HASH_REF_REGULAR and
ELF_LINK_HASH_DEF_REGULAR when a symbol is both defined and referenced
in the same object. But I don't think we do it currently.
> Ian
>
> Index: elflink.h
> ===================================================================
> RCS file: /cvs/binutils/binutils/bfd/elflink.h,v
> retrieving revision 1.9
> diff -u -r1.9 elflink.h
> --- elflink.h 1999/07/01 23:20:07 1.9
> +++ elflink.h 1999/07/07 18:18:39
> @@ -492,14 +492,19 @@
> represent variables; this can cause confusion in principle, but
> any such confusion would seem to indicate an erroneous program or
> shared library. We also permit a common symbol in a regular
> - object to override a weak symbol in a shared object. */
> + object to override a weak symbol in a shared object.
>
> + We prefer a non-weak definition in a shared library to a weak
> + definition in the executable. */
> +
> if (newdyn
> && newdef
> && (olddef
> || (h->root.type == bfd_link_hash_common
> && (bind == STB_WEAK
> - || ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
> + || ELF_ST_TYPE (sym->st_info) == STT_FUNC)))
> + && (h->root.type != bfd_link_hash_defweak
> + || bind == STB_WEAK))
> {
> *override = true;
> newdef = false;
> @@ -543,7 +548,10 @@
>
> As above, we again permit a common symbol in a regular object to
> override a definition in a shared object if the shared object
> - symbol is a function or is weak. */
> + symbol is a function or is weak.
> +
> + As above, we permit a non-weak definition in a shared object to
> + override a weak definition in a regular object. */
>
> if (! newdyn
> && (newdef
> @@ -552,7 +560,9 @@
> || h->type == STT_FUNC)))
> && olddyn
> && olddef
> - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
> + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
> + && (bind != STB_WEAK
> + || h->root.type == bfd_link_hash_defweak))
> {
> /* Change the hash table entry to undefined, and let
> _bfd_generic_link_add_one_symbol do the right thing with the
> @@ -626,6 +636,31 @@
> h->verinfo.vertree = NULL;
> }
>
> + /* Handle the special case of a weak definition in a regular object
> + followed by a non-weak definition in a shared object. In this
> + case, we prefer the definition in the shared object. To make
> + this work we have to frob the flags. */
> + if (olddef
> + && ! olddyn
> + && h->root.type == bfd_link_hash_defweak
> + && newdef
> + && newdyn
> + && bind != STB_WEAK)
> + h->elf_link_hash_flags &= ~ ELF_LINK_HASH_DEF_REGULAR;
> +
> + /* Handle the special case of a non-weak definition in a shared
> + object followed by a weak definition in a regular object. In
> + this case we prefer to definition in the shared object. To make
> + this work we have to tell the caller to not treat the new symbol
> + as a definition. */
> + if (olddef
> + && olddyn
> + && h->root.type != bfd_link_hash_defweak
> + && newdef
> + && ! newdyn
> + && bind == STB_WEAK)
> + *override = true;
> +
> return true;
> }
>
>
Here is the patch against yours.
--
H.J. Lu (hjl@gnu.org)
---
--- elflink.h.ian Wed Jul 7 13:46:13 1999
+++ elflink.h Wed Jul 7 13:46:59 1999
@@ -642,7 +642,10 @@ elf_merge_symbol (abfd, info, name, sym,
&& newdef
&& newdyn
&& bind != STB_WEAK)
- 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;
+ }
/* Handle the special case of a non-weak definition in a shared
object followed by a weak definition in a regular object. In