.hidden overrides .symver?

Florian Weimer fweimer@redhat.com
Tue Nov 15 14:08:00 GMT 2016


This question arose during glibc ABI testing on powerpc (32-bit), but I 
can reproduce it on ppc64 as well (which is how I got this example, it 
is not visible with the glibc sources because the powerpc issue is in 
architecture-specific code not shared between 32-bit and 64-bit).

There are three fils: def.s, ref.s, ver.map:

# def.s
         .section        ".text"
         .align 2
         .p2align 4,,15
         .globl symint
         .symver symint,versym@@PUBVER
         .section        ".opd","aw"
         .align 3
symint:
         .quad   .L.symint,.TOC.@tocbase
         .previous
         .type   symint, @function
.L.symint:
         li 3,0
         blr
         .long 0
         .byte 0,0,0,0,0,0,0,0
         .size   symint,.-.L.symint


# ref.s
         .section        ".text"
         .align 2
         .p2align 4,,15
         .globl pubsym
         .section        ".opd","aw"
         .align 3
pubsym:
         .quad   .L.pubsym,.TOC.@tocbase
         .previous
         .type   pubsym, @function
.L.pubsym:
         b versym
         .long 0
         .byte 0,0,0,1,128,0,0,0
         .size   pubsym,.-.L.pubsym
         .hidden versym


# ver.map
BASE {
   local:
     *;
};

PUBVER {
} BASE;

PUBVER2 {
   global:
     pubsym;
} PUBVER;


Once you have these files, run:

as -o def.o def.s
as -o ref.o ref.s
ld -s -shared -o lib-without-ref.so --version-script=ver.map def.o
ld -s -shared -o lib-with-ref.so --version-script=ver.map def.o ref.o

The surprise is that lib-without-ref.so contains a definition of versym:

Symbol table '.dynsym' contains 7 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
      0: 00000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
      1: 000000000002f0     0 SECTION LOCAL  DEFAULT    7
      2: 00000000020000     0 SECTION LOCAL  DEFAULT   10
      3: 00000000000000     0 OBJECT  GLOBAL DEFAULT  ABS BASE
      4: 00000000000000     0 OBJECT  GLOBAL DEFAULT  ABS PUBVER2
      5: 00000000000000     0 OBJECT  GLOBAL DEFAULT  ABS PUBVER
      6: 00000000020000    20 FUNC    GLOBAL DEFAULT   10 versym@@PUBVER

But lib-with-ref.so does not:

Symbol table '.dynsym' contains 7 entries:
    Num:    Value          Size Type    Bind   Vis      Ndx Name
      0: 00000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
      1: 00000000000320     0 SECTION LOCAL  DEFAULT    7
      2: 00000000020000     0 SECTION LOCAL  DEFAULT   10
      3: 00000000020010    16 FUNC    GLOBAL DEFAULT   10 pubsym@@PUBVER2
      4: 00000000000000     0 OBJECT  GLOBAL DEFAULT  ABS BASE
      5: 00000000000000     0 OBJECT  GLOBAL DEFAULT  ABS PUBVER2
      6: 00000000000000     0 OBJECT  GLOBAL DEFAULT  ABS PUBVER

Is this the intended behavior?

In our case, pubsym is defined in a C source file, and versym is 
referenced with a *declaration* with __attribute ((visibility 
("hidden"))).  This means that a mere declaration overrides aspects of 
the definition of the symbol in another translation unit, which is 
extremely surprising.

The ld version is: GNU ld version 2.25.1-22.base.el7

Thanks,
Florian



More information about the Binutils mailing list