Your bfd & ld patch breaks --as-needed on SPARC (and some other targets)

Nix nix@esperi.org.uk
Fri Aug 12 09:18:00 GMT 2005


Specifically, this patch from late January:

revision 1.2862
date: 2005/01/25 01:39:58;  author: amodra;  state: Exp;  lines: +13 -0
bfd/
        * elflink.c (elf_link_add_object_symbols): Don't create link dynamic
        sections immediately when linking shared libs.  Instead, wait until
        we know a lib is needed.
        (_bfd_elf_link_create_dynstrtab): Extract from..
        (_bfd_elf_link_create_dynamic_sections_): ..here.
        (elf_add_dt_needed_tag): Call _bfd_elf_link_create_dynstrtab and
        _bfd_elf_link_create_dynamic_sections.  Add abfd param.  Allow
        for non-existent .dynamic.
        (elf_link_output_extsym): Don't complain about undefined symbols
        in as-needed dynamic libs that aren't actually linked.
ld/
        * emultempl/elf32.em (gld${EMULATION_NAME}_try_needed): Formatting.
        (gld${EMULATION_NAME}_after_open): Ignore needed libs if they were
        only needed by an as-needed lib that didn't get linked.

makes links against one or more shared libraries (discounting libc) with
--as-needed fail:

cat > hello.c << EOF
#include <stdio.h>

int main() {
        printf("hello world!\n");
}
EOF
gcc -Wl,--as-needed -o hello hello.c -lssl
ld: Disabling relaxation: it will not work with multiple definitions
/usr/lib/../lib/crt1.o:(.plt+0x0): multiple definition of `_PROCEDURE_LINKAGE_TABLE_'
collect2: ld returned 1 exit status

Obviously this error is silly: every shared library can be expected
to have a PLT, and on want_plt_sym targets like SPARC they'll all have
duplicate copies of this symbol. It's pretty trivial to reproduce
the error with _DYNAMIC, too:

nix@amaterasu 525 /tmp% nm -D /usr/lib/libImlib.so | grep ' A '
0003a014 A _DYNAMIC
0003a124 A _GLOBAL_OFFSET_TABLE_
0003a500 A _PROCEDURE_LINKAGE_TABLE_
0003b101 A __bss_start
0003b101 A _edata
0003b120 A _end

nix@amaterasu 526 /tmp% /usr/bin/gcc -B/usr/packages/binutils/sparc-amaterasu/ld -o hello hello.c -L. -lImlib
/usr/lib/../lib/crt1.o:(.dynamic+0x0): multiple definition of `_DYNAMIC'
lt-ld-new: Disabling relaxation: it will not work with multiple definitions
/usr/lib/../lib/crt1.o:(.plt+0x0): multiple definition of `_PROCEDURE_LINKAGE_TABLE_'

And voila, there are multiple references to those symbols in the
library's transitive dependencies:

nix@amaterasu 538 /tmp% ldd /usr/lib/libImlib.so | awk '{print $3;}' | sort -u | xargs nm -D | grep -E '_DYNAMIC|_GLOBAL_OFFSET_TABLE_|_PROCEDURE_LINKAGE_TABLE_'
000248c4 A _DYNAMIC
00024cd0 A _PROCEDURE_LINKAGE_TABLE_
000180ec A _DYNAMIC
000182dc A _PROCEDURE_LINKAGE_TABLE_
000e2378 A _DYNAMIC
000e3760 A _PROCEDURE_LINKAGE_TABLE_
0001eddc A _DYNAMIC
0001f008 A _PROCEDURE_LINKAGE_TABLE_
000413f0 A _DYNAMIC
000417e8 A _PROCEDURE_LINKAGE_TABLE_
0003c86c A _DYNAMIC
0003cfa4 A _PROCEDURE_LINKAGE_TABLE_
00062f28 A _DYNAMIC
00064000 A _PROCEDURE_LINKAGE_TABLE_
00017130 A _DYNAMIC
000174d0 A _GLOBAL_OFFSET_TABLE_
00017214 A _PROCEDURE_LINKAGE_TABLE_
0002172c A _DYNAMIC
00021924 A _PROCEDURE_LINKAGE_TABLE_

__bss_start, _edata and _end seem to not trip this bug. I also can't make
it happen with _GLOBAL_OFFSET_TABLE_.


This is Debian bug #320697 and Ubuntu bug #12822: reports there indicate
that MIPS is broken similarly. I suspect that all want_plt_sym targets
are broken, but haven't tested that yet. (I hope to get to it this
lunchtime, but as this isn't my day job other things must supervene
until then.)


(Let me add my voice to the chorus praising Janis for reghunt. Simple
yet elegant and so, so useful.)

-- 
`I work in computers so, of course, I'm an expert on everything.'
                                                     --- Simon Rumble



More information about the Binutils mailing list