This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
elf32-ppc ld bug with symbol versioning
- From: Roland McGrath <roland at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Tue, 22 Apr 2003 16:40:16 -0700
- Subject: elf32-ppc ld bug with symbol versioning
The attached shell archive unpacks a few files and a Makefile that
demonstrates a bug now biting glibc on powerpc-unknown-linux-gnu.
This shows up in mainline of today, as well as other recent versions.
With these files, "make" will give you:
/usr/local/bin/ld: lose.so: undefined versioned symbol name foo@@VERS_1
This boils down to an ld -shared that is resolving against a .so and a .a
with versioned references between them. The crucial factor is probably
that bar.a(bar.o) has a weak defn of bar that should be in force despite
the presence of a bar symbol in foo.so earlier in the link order. foo.so's
defn is ignored because it is a versioned defn with @ rather than @@,
but having done that seems to make ld fail to see bar.a(bar.o)'s own defn.
Thanks,
Roland
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2003-04-22 16:30 PDT by <roland at debian dot sf dot frob dot com>.
# Source directory was `/mnt/home/roland/redhat/ld-bug'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
# This format requires very little intelligence at unshar time.
# "if test", "echo", "mkdir", and "sed" may be needed.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 332 -rw-rw-rw- Makefile
# 122 -rw-rw-rw- foo.c
# 44 -rw-rw-rw- foo.v
# 82 -rw-rw-rw- bar.c
# 25 -rw-rw-rw- lose.c
#
echo=echo
if mkdir _sh01948; then
$echo 'x -' 'creating lock directory'
else
$echo 'failed to create lock directory'
exit 1
fi
# ============= Makefile ==============
if test -f 'Makefile' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'Makefile' '(file already exists)'
else
$echo 'x -' extracting 'Makefile' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
Xlose.so: lose.c foo.so bar.a
X $(CC) -o $@ -shared $^
Xfoo.so: foo.o foo.v
X $(CC) -o $@ -shared -Wl,--version-script=foo.v foo.o
Xbar.a: bar.o
X rm -f $@
X ar cq $@ $^
X
Xfoo.o lose.o: CFLAGS = -fPIC
X
Xbug.tar: Makefile foo.c foo.v bar.c lose.c
X rm -f $@
X tar cf $@ $^
Xbug.shar: Makefile foo.c foo.v bar.c lose.c
X rm -f $@
X shar -V $^ > $@
SHAR_EOF
: || $echo 'restore of' 'Makefile' 'failed'
fi
# ============= foo.c ==============
if test -f 'foo.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'foo.c' '(file already exists)'
else
$echo 'x -' extracting 'foo.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'foo.c' &&
Xvoid __attribute__((weak)) foo () {}
Xvoid __attribute__((weak)) old_bar () { foo (); }
Xasm(".symver old_bar,bar at VERS_1");
SHAR_EOF
: || $echo 'restore of' 'foo.c' 'failed'
fi
# ============= foo.v ==============
if test -f 'foo.v' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'foo.v' '(file already exists)'
else
$echo 'x -' extracting 'foo.v' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'foo.v' &&
XVERS_1 {
X global: foo; bar;
X local: *;
X};
SHAR_EOF
: || $echo 'restore of' 'foo.v' 'failed'
fi
# ============= bar.c ==============
if test -f 'bar.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'bar.c' '(file already exists)'
else
$echo 'x -' extracting 'bar.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'bar.c' &&
Xvoid __attribute__((weak)) foo () {}
Xvoid __attribute__((weak)) bar () { foo(); }
SHAR_EOF
: || $echo 'restore of' 'bar.c' 'failed'
fi
# ============= lose.c ==============
if test -f 'lose.c' && test "$first_param" != -c; then
$echo 'x -' SKIPPING 'lose.c' '(file already exists)'
else
$echo 'x -' extracting 'lose.c' '(text)'
sed 's/^X//' << 'SHAR_EOF' > 'lose.c' &&
Xvoid lose () { bar (); }
SHAR_EOF
: || $echo 'restore of' 'lose.c' 'failed'
fi
rm -fr _sh01948
exit 0