foo (VER_NDX_GLOBAL) and foo@@v1 in one DSO
Fangrui Song
i@maskray.me
Tue Apr 18 04:52:15 GMT 2023
On Thu, Nov 10, 2022 at 7:27 PM Fangrui Song <i@maskray.me> wrote:
>
> Hello, I find a strange use of VER_NDX_GLOBAL and look forward to your thoughts.
>
> cat > a.s <<e
> .globl foo
> .symver foo, foo@@@v1
> foo:
> nop
> ret
>
> .globl foo_compat
> .symver foo_compat, foo@, remove
> foo_compat:
> ret
> e
> cat > a.ver <<e
> v1 {};
> e
> cat > b.c <<e
> extern void foo(void);
> int main(void) { foo(); }
> e
>
> gcc -fuse-ld=bfd -shared -nostdlib -Wl,--version-script=a.ver a.s -o a.so
> gcc -fuse-ld=bfd -g b.c ./a.so -o b
>
> exit
>
> In a.so, we have a default version foo@@v1 as well as a VER_NDX_GLOBAL foo.
> The VER_NDX_GLOBAL foo is unusual.
>
> ```
> % readelf -W --dyn-s -V a.so
>
> Symbol table '.dynsym' contains 4 entries:
> Num: Value Size Type Bind Vis Ndx Name
> 0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
> 1: 0000000000001000 0 NOTYPE GLOBAL DEFAULT 7 foo@@v1
> 2: 0000000000001002 0 NOTYPE GLOBAL DEFAULT 7 foo
> 3: 0000000000000000 0 OBJECT GLOBAL DEFAULT ABS v1
>
> Version symbols section '.gnu.version' contains 4 entries:
> Addr: 0x000000000000028e Offset: 0x00028e Link: 3 (.dynsym)
> 000: 0 (*local*) 2 (v1) 1h 2 (v1)
>
> Version definition section '.gnu.version_d' contains 2 entries:
> Addr: 0x0000000000000298 Offset: 0x000298 Link: 4 (.dynstr)
> 000000: Rev: 1 Flags: BASE Index: 1 Cnt: 1 Name: a.so
> 0x001c: Rev: 1 Flags: none Index: 2 Cnt: 1 Name: v1
> ```
>
> There are two strange things:
>
> * foo is a VER_NDX_GLOBAL VERSYM_HIDDEN symbol (shown as `1h`). Is this an expected use case?
> * foo co-exist with foo@@v1. Is this an expected use case?
>
> In my understanding, when a stem symbol has a @ form, the unversioned VER_NDX_GLOBAL form cannot exist.
> In the example above, `.symver foo_compat, foo@v0, remove` would be fine.
>
> The above is reduced from a real world case of https://github.com/libfuse/libfuse/blob/fuse_2_9_bugfix/lib/fuse.c#L4955
> `FUSE_SYMVER(".symver fuse_new_compat2,fuse_new@");`
>
> % readelf -W --dyn-s /lib/x86_64-linux-gnu/libfuse.so.2 G fuse_new
> 200: 00000000000148b0 72 FUNC GLOBAL DEFAULT 13 fuse_new@FUSE_2.5
> 201: 0000000000014870 16 FUNC GLOBAL DEFAULT 13 fuse_new # this is VERSYM_HIDDEN
> 202: 0000000000014750 8 FUNC GLOBAL DEFAULT 13 fuse_new@@FUSE_2.6
> 203: 0000000000014860 11 FUNC GLOBAL DEFAULT 13 fuse_new@FUSE_2.2
> 216: 0000000000014880 35 FUNC GLOBAL DEFAULT 13 fuse_new_compat1@@FUSE_2.2
> 218: 0000000000014870 16 FUNC GLOBAL DEFAULT 13 fuse_new_compat2@@FUSE_2.2
> 228: 0000000000014860 11 FUNC GLOBAL DEFAULT 13 fuse_new_compat22@@FUSE_2.5
> 230: 00000000000148b0 72 FUNC GLOBAL DEFAULT 13 fuse_new_compat25@@FUSE_2.6
Ping about thoughts:)
More information about the Binutils
mailing list