This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
Re: A glibc dynamic linker or gld bug?
> Date: 7 Jul 1999 23:27:28 -0400
> From: Ian Lance Taylor <ian@zembu.com>
> Date: Thu, 8 Jul 1999 13:12:03 +1000
> From: Geoff Keating <geoffk@ozemail.com.au>
> These cases, if fixed by outputting all relevant relocations, would
> lead to incredibly inefficient program loading because it would be
> necessary to have run-time relocs for any weak symbol referenced by the
> executable. It would also cost large amounts of memory because the
> text segment of executables would no longer be sharable between
> invocations.
>
> Does the average executable really reference that many weak symbols?
It does both reference many weak symbols, and make many weak
references, but the last turns out to be a linker bug.
I attach a patch to fix the bug. I'd like to attach a test case too,
but I think it will be better to wait until we've decided how all the
weak symbol stuff should work.
I predict that with this patch, the typical executable will make no
external weak references at all. [I can only 'predict' at present
because the 990706 snapshot is failing too many tests to install.]
The typical executable will still make a few weak definitions,
typically to __gmon_start__, stat, mknod, and related functions
(perhaps more in C++ depending on what wacky things are going on
there). This doesn't attract as great a performance penalty, because
it can only become defined to something else, not NULL.
--
Geoffrey Keating <geoffk@ozemail.com.au>
===File ~/patches/binutils-19.diff==========================
1999-07-08 Geoff Keating <geoffk@cygnus.com>
* elflink.h (elf_link_output_extsym): Don't output a weak
reference to an undefined symbol just because it was
defined weak in a shared object.
--- binutils-990629/bfd/elflink.h~ Thu Jul 8 23:24:49 1999
+++ binutils-990629/bfd/elflink.h Thu Jul 8 23:36:16 1999
@@ -4668,14 +4668,22 @@ elf_link_output_extsym (h, data)
/* If we are marking the symbol as undefined, and there are no
non-weak references to this symbol from a regular object, then
- mark the symbol as weak undefined. We can't do this earlier,
+ mark the symbol as weak undefined; if there are non-weak
+ references, mark the symbol as strong. We can't do this earlier,
because it might not be marked as undefined until the
finish_dynamic_symbol routine gets through with it. */
if (sym.st_shndx == SHN_UNDEF
- && sym.st_info == ELF_ST_INFO (STB_GLOBAL, h->type)
&& (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) != 0
- && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK) == 0)
- sym.st_info = ELF_ST_INFO (STB_WEAK, h->type);
+ && (ELF_ST_BIND(sym.st_info) == STB_GLOBAL
+ || ELF_ST_BIND(sym.st_info) == STB_WEAK))
+ {
+ int bindtype;
+ if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK) != 0)
+ bindtype = STB_GLOBAL;
+ else
+ bindtype = STB_WEAK;
+ sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info));
+ }
/* If this symbol should be put in the .dynsym section, then put it
there now. We have already know the symbol index. We also fill
============================================================