Bug 21661

Summary: .symver shouldn't be allowed on common symbol
Product: binutils Reporter: H.J. Lu <hjl.tools>
Component: gasAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal    
Priority: P2    
Version: 2.29   
Target Milestone: 2.29   
Host: Target:
Build: Last reconfirmed:

Description H.J. Lu 2017-06-23 12:14:48 UTC
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]$
Comment 1 H.J. Lu 2017-06-23 12:44:26 UTC
.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.
Comment 2 Sourceware Commits 2017-06-26 12:12:43 UTC
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.
Comment 3 H.J. Lu 2017-06-26 12:18:29 UTC
Fixed for 2.29.