https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108969
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |REOPENED Resolution|FIXED |--- --- Comment #20 from Jakub Jelinek <jakub at gcc dot gnu.org> --- So, ( for i in 7.c 7.ver 7a.c 7a.ver 8.c 7.h; do echo $i; cat /tmp/$i; done; gcc -shared -fpic -Wl,--version-script=/tmp/7.ver /tmp/7.c -o /tmp/7.so; gcc -I /tmp/ -o /tmp/8 /tmp/8.c /tmp/7.so; /tmp/8; echo $?; gcc -shared -fpic -Wl,--version-script=/tmp/7a.ver /tmp/7a.c -o /tmp/7.so; /tmp/8; echo $? ) 7.c void _Zwhatever (void) { } void foo (void) { } 7.ver GLIBCXX_3.4.31 { global: foo; local: *; }; GLIBCXX_3.4.32 { global: _Zwhatever; } GLIBCXX_3.4.31; 7a.c void foo (void) { } 7a.ver GLIBCXX_3.4.31 { global: foo; local: *; }; 8.c #include "7.h" int main () { } 7.h asm (".globl _Zwhatever"); 0 /tmp/8: /tmp/7.so: version `GLIBCXX_3.4.32' not found (required by /tmp/8) 1 is one proof-of-concept on what we could do. Another one is /tmp/4.C namespace std { # define _GLIBCXX_IO_GLOBAL(type, X, N) namespace __io { type X __attribute__((__symver__ ("_ZSt" #N #X "@GLIBCXX_3.4"))); } \ extern type X##alias __attribute__((__weak__, __alias__ ("_ZNSt4__io" #N #X "E"), __symver__ ("_ZSt" #N #X "@@GLIBCXX_3.4.31"))); _GLIBCXX_IO_GLOBAL(int, cin, 3) _GLIBCXX_IO_GLOBAL(int, cout, 4) _GLIBCXX_IO_GLOBAL(int, cerr, 4) _GLIBCXX_IO_GLOBAL(int, clog, 4) } /tmp/4.c extern int _ZSt4cerr; int main () { _ZSt4cerr++; } /tmp/4.ver GLIBCXX_3.4 { global: _ZSt3cin; _ZSt4cerr; _ZSt4cout; _ZSt4clog; local: *; }; GLIBCXX_3.4.31 { global: _ZSt3cin; _ZSt4cerr; _ZSt4cout; _ZSt4clog; } GLIBCXX_3.4; gcc -shared -o /tmp/4.so /tmp/4.C -fpic -Wl,--version-script=/tmp/4.ver gcc -o /tmp/4 /tmp/4.c /tmp/4.so eadelf -Wa /tmp/4 2>&1 | grep cerr 000000000040401c 0000000400000005 R_X86_64_COPY 000000000040401c _ZSt4cerr@GLIBCXX_3.4 + 0 3: 000000000040401c 4 OBJECT WEAK DEFAULT 23 _ZSt4cerr@GLIBCXX_3.4.31 (3) 4: 000000000040401c 4 OBJECT GLOBAL DEFAULT 23 _ZSt4cerr@GLIBCXX_3.4 (4) 58: 000000000040401c 4 OBJECT WEAK DEFAULT 23 _ZSt4cerr@GLIBCXX_3.4.31 59: 000000000040401c 4 OBJECT GLOBAL DEFAULT 23 _ZSt4cerr@GLIBCXX_3.4 So, when the @@GLIBCXX_3.4.31 alias is weak, at least the F36 linker puts into the binary not just one but both symbols and so the aliasing isn't broken. We'd need to also arrange for ios_init.o to refer to _ZSt4cerr@GLIBCXX_3.4 rather than _ZSt4cerr, because binaries built against older libstdc++ will have just _ZSt4cerr@GLIBCXX_3.4 symbol on the copy relocation. Or combination of both, do the former on Solaris and the latter on Linux. To be tested with older linkers/assemblers, non-glibc dynamic linkers and the like.