When hiding a versioned common symbol, the wrong address is used: [hjl@gnu-tools-1 xxx]$ cat foo.c char *foo; #ifdef COMPAT asm (".symver foo,foo@VERS.1"); #endif void check (char **p) { if (p != &foo) __builtin_abort (); } [hjl@gnu-tools-1 xxx]$ cat main.c extern void check (); extern char *foo; int main () { check (&foo); return 0; } [hjl@gnu-tools-1 xxx]$ cat foo.v VERS.1 { global: foo; }; [hjl@gnu-tools-1 xxx]$ make gcc -g -fPIC -c -o foo1.o foo.c ./ld -o foo1.so -shared foo1.o --version-script foo.v -soname=foo.so gcc -g -fPIC -DCOMPAT -c -o foo2.o foo.c ./ld -o foo2.so -shared foo2.o --version-script foo.v -soname=foo.so gcc -g -c -o main.o main.c gcc -o x main.o foo1.so -Wl,-R,. readelf -sW foo1.so | grep foo 5: 0000000000201020 8 OBJECT GLOBAL DEFAULT 14 foo@@VERS.1 21: 0000000000000000 0 FILE LOCAL DEFAULT ABS foo.c 29: 0000000000201020 8 OBJECT GLOBAL DEFAULT 14 foo readelf -sW foo2.so | grep foo 2: 0000000000201020 8 OBJECT GLOBAL DEFAULT 12 foo@VERS.1 19: 0000000000000000 0 FILE LOCAL DEFAULT ABS foo.c 22: 0000000000201028 8 OBJECT LOCAL DEFAULT 12 foo foo should have the same address as foo@VERS.1. 25: 0000000000201020 8 OBJECT GLOBAL DEFAULT 12 foo@VERS.1 ln -sf foo1.so foo.so ./x ln -sf foo2.so foo.so ./x Makefile:7: recipe for target 'all' failed make: *** [all] Aborted (core dumped) [hjl@gnu-tools-1 xxx]$
.symver on common symbols shouldn't be allowed: hjl@gnu-tools-1 pr21661]$ cat bad.S .comm foo,8,8 .symver foo,foo@VERS.1 [hjl@gnu-tools-1 pr21661]$ gcc -c bad.S [hjl@gnu-tools-1 pr21661]$ readelf -s bad.o Symbol table '.symtab' contains 6 entries: Num: Value Size Type Bind Vis Ndx Name 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND 1: 0000000000000000 0 SECTION LOCAL DEFAULT 1 2: 0000000000000000 0 SECTION LOCAL DEFAULT 2 3: 0000000000000000 0 SECTION LOCAL DEFAULT 3 4: 0000000000000008 8 OBJECT GLOBAL DEFAULT COM foo 5: 0000000000000008 8 OBJECT GLOBAL DEFAULT COM foo@VERS.1 [hjl@gnu-tools-1 pr21661]$ foo and foo@VERS.1 are 2 different common symbols.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=a3aea05a66ec325ddd19b0c8dbe504958a295cd3 commit a3aea05a66ec325ddd19b0c8dbe504958a295cd3 Author: H.J. Lu <hjl.tools@gmail.com> Date: Mon Jun 26 05:11:07 2017 -0700 Check unsupported .symver with common symbol The .symver directive on common symbol creates a new common symbol, which shouldn't be allowed, similar to alias on common symbol: $ cat y.S .comm bar,8,8 .set bar1,bar $ as -o y.o y.S y.S: Assembler messages: y.S:2: Error: `bar1' can't be equated to common symbol 'bar' $ PR gas/21661 * config/obj-elf.c (obj_elf_symver): Don't allow .symver with common symbol. (elf_frob_symbol): Likewise. * testsuite/gas/elf/elf.exp: Run pr21661. * testsuite/gas/elf/pr21661.d: New file. * testsuite/gas/elf/pr21661.s: Likewise.
Fixed for 2.29.