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.

Reply via email to