This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
AS_NEEDED failure
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sources dot redhat dot com
- Cc: Anton Blanchard <anton at samba dot org>,Paul Mackerras <paulus at samba dot org>
- Date: Tue, 12 Apr 2005 00:00:15 +0930
- Subject: AS_NEEDED failure
On powerpc64, I've hit the following during an X11 server build
.../libdl.so.2: undefined reference to _rtld_global@GLIBC_PRIVATE
This symbol is defined in ld64.so.1, and ld64.so.1 is being searched,
but the following conspires to make the link fail:
- libc.so contains AS_NEEDED (ld64.so.1)
- one or more of the X11 libs has DT_NEEDED libdl.so.2
- libdl.so.2 has DT_NEEDED ld64.so.1
The libc.so AS_NEEDED() causes symbols from ld64.so.1 to be loaded, but
no regular object file needs them so all the ld64.so.1 syms are set back
to bfd_link_hash_new, effectively removing them. The X11 lib is loaded,
and its DT_NEEDED entry noted. libdl.so.2 is loaded, but ld decides
that ld64.so.1 has already been looked at, so doesn't load it again.
It should do, because AS_NEEDED lib symbols aren't really loaded.
* emultempl/elf32.em (gld${EMULATION_NAME}_stat_needed): Ignore
as_needed libs that were not needed.
(gld${EMULATION_NAME}_check_needed): Likewise.
Applied mainline. I think this should go on 2.16, but after some more
testing..
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.138
diff -u -p -r1.138 elf32.em
--- ld/emultempl/elf32.em 4 Apr 2005 11:27:15 -0000 1.138
+++ ld/emultempl/elf32.em 11 Apr 2005 14:23:08 -0000
@@ -230,6 +230,9 @@ gld${EMULATION_NAME}_stat_needed (lang_i
return;
if (s->the_bfd == NULL)
return;
+ if (s->as_needed
+ && (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0)
+ return;
if (bfd_stat (s->the_bfd, &st) != 0)
{
@@ -737,6 +740,13 @@ gld${EMULATION_NAME}_check_needed (lang_
if (global_found)
return;
+ /* If this input file was an as-needed entry, and wasn't found to be
+ needed at the stage it was linked, then don't say we have loaded it. */
+ if (s->as_needed
+ && (s->the_bfd == NULL
+ || (bfd_elf_get_dyn_lib_class (s->the_bfd) & DYN_AS_NEEDED) != 0))
+ return;
+
if (s->filename != NULL)
{
const char *f;
--
Alan Modra
IBM OzLabs - Linux Technology Centre