This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: php5: probably binutils bug
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Cc: Michael Matz <matz at suse dot de>
- Date: Sun, 8 Dec 2013 15:25:11 +1030
- Subject: Re: php5: probably binutils bug
- Authentication-results: sourceware.org; auth=none
- References: <alpine dot LNX dot 2 dot 00 dot 1312051717420 dot 2204 at wotan dot suse dot de>
Michael sent me this testcase showing a linker bug, cunningly claiming
it was a powerpc64le failure. I tried at first to shirk all
responsibility since I didn't reproduce the problem. He wouldn't let
that go, pointing out that I simply had to add -Wl,--as-needed. Oh
well, let's have a look then.. Hey! It's a generic problem!
Here's the testcase, showing the failure on x64_64-linux using a 2.24
linker. It's a little nasty in that libx.so isn't linked against
liby.so, but we do allow shared libraries to be built with undefined
references.
cat > libx.c <<EOF
extern void pam_end (void);
void dumpme (void)
{
pam_end ();
}
EOF
cat > liby.c <<EOF
extern void pam_end (void);
void pam_end (void) {}
EOF
cat > appx.c <<EOF
extern void dumpme (void);
int main (void)
{
dumpme();
return 0;
}
EOF
cat > liby.ver <<EOF
BLAFOO {
global: pam_end;
local: *;
};
EOF
gcc -fPIC -shared -o libx.so libx.c
gcc -fPIC -shared -o liby.so liby.c -Wl,--version-script,liby.ver
ln -s ~/build/gas-virgin/x86_64-linux/ld/ld-new ld
gcc -B. -o appx appx.c -L. -Wl,--as-needed -lx -ly
./libx.so: undefined reference to `pam_end'
collect2: ld returned 1 exit status
What's happening is that liby.so isn't being seen as needed in appx,
because the reference in libx.so is to an unversioned symbol while
liby.so provides a versioned symbol. Fixed as follows.
* elf64-ppc.c (_bfd_elf_add_default_symbol): Set dynamic_def
and ref_dynamic_nonweak when chaining together indirect
symbols.
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 1e6abd9..6fa62f9 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -1702,6 +1702,12 @@ _bfd_elf_add_default_symbol (bfd *abfd,
ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
(*bed->elf_backend_copy_indirect_symbol) (info, ht, hi);
+ /* A reference to the SHORTNAME symbol from a dynamic library
+ will be satisfied by the versioned symbol at runtime. In
+ effect, we have a reference to the versioned symbol. */
+ ht->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak;
+ hi->dynamic_def |= ht->dynamic_def;
+
/* See if the new flags lead us to realize that the symbol must
be dynamic. */
if (! *dynsym)
@@ -1771,6 +1777,8 @@ nondefault:
if (hi->root.type == bfd_link_hash_indirect)
{
(*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
+ h->ref_dynamic_nonweak |= hi->ref_dynamic_nonweak;
+ hi->dynamic_def |= h->dynamic_def;
/* See if the new flags lead us to realize that the symbol
must be dynamic. */
--
Alan Modra
Australia Development Lab, IBM