Created attachment 13134 [details] Reproducer code The attached code, when built with gcc -fPIC -o thread.so -shared thread.c (using GCC 8.3.0 and binutils 2.36) produces the following error: ld: thread.so: no symbol version section for versioned symbol `pthread_key_create@GLIBC_2.2.5' I am not sure if .symver is supposed to override .weak, or vice versa. IF the latter, it would appears to me that this is a bug in binutils. Regards, Tom
(In reply to Tom Kacvinsky from comment #0) > Created attachment 13134 [details] > Reproducer code > > The attached code, when built with > > gcc -fPIC -o thread.so -shared thread.c > > (using GCC 8.3.0 and binutils 2.36) produces the following error: > > ld: thread.so: no symbol version section for versioned symbol > `pthread_key_create@GLIBC_2.2.5' This linker message is due to PR 3351.
I know you mentioned this message comes from the referenced PR, but is what I am seeing an unintended consequence of the change made in this PR, or is this expected behavior?
--- __asm__(".symver pthread_key_create,pthread_key_create@GLIBC_2.2.5,remove"); --- A versioned symbol must be defined in an object. Try this [hjl@gnu-cfl-2 pr27206]$ cat libfoo.map GLIBC_2.2.5 { global: pthread_key_create; }; libfoo { global: *; }; [hjl@gnu-cfl-2 pr27206]$ cat foo.c #include <pthread.h> __attribute__ ((weak)) int pthread_key_create (pthread_key_t *key, void (*fun) (void *)) { return 0; } __asm__(".symver pthread_key_create,pthread_key_create@GLIBC_2.2.5"); void destructor(void* arg) { return; } void thread_func() { pthread_key_t key; pthread_key_create(&key, destructor); } [hjl@gnu-cfl-2 pr27206]$ make gcc -B./ -fPIC -c -o foo.o foo.c gcc -B./ -Wl,--version-script=libfoo.map -shared -o libfoo.so foo.o [hjl@gnu-cfl-2 pr27206]$ readelf -rW --dyn-syms libfoo.so | grep pthread_key_create 0000000000004018 0000000600000007 R_X86_64_JUMP_SLOT 0000000000001109 pthread_key_create@GLIBC_2.2.5 + 0 6: 0000000000001109 19 FUNC WEAK DEFAULT 14 pthread_key_create@GLIBC_2.2.5 [hjl@gnu-cfl-2 pr27206]$
This worked for me in my simple reproducer, but unfortunately we are doing "naughty" things with third party code build such that a linker map is not an option, unless we hack that library's build process.
#c0 should be flagged. ld errors for an undefined versioned symbol. If a versioned symbol is defined, it requires a version node defined in a version script (unless not -shared). Whether as should error for `.symver ... local` + `weak`? It is not clear. Personally I'd like a directive which just renames the symbol to a @ form, then such issues would not arise. https://maskray.me/blog/2020-11-26-all-about-symbol-versioning#assembler-behavior Tom, how did you notice .symver ... local and start to use it?
For compatibility reasons, I want to update my automated build machine, but build GCC and auxiliary support libraries in such a fashion that we can target older Linux distributions That is, build on a machine with a newer glibc, but still be able to run the resulting binaries on a system with an older glibc, which is reverse of building on an older system and running on a newer system. So, I first went to build GCC 8.3.0 on a newer system (CentOS 7) using a custom assembly file (one that contains a .symver for each older version symbol we want, to target older versions of glibc). That is injected into compiler generated assembly files via an indirect assembler - named as, which opens any .s/.S files on the command line, inserts the custom assembly file into them, then calls gas, the _real_ assembler. But libgcc.so.1 failed to build with the pthread_key_create error I mentioned in this bug. The reproducer I sent is a stripped down version of the code from libgcc. This is why I am somewhat concerned about the link map trick, etc... It would create many problems while trying to sort out the GCC build configuration and code. The code in GCC that utilizes pthread_key_create marks it as extern and weak, which is different from what is in pthread.h. And the reason for that, as commented in the libgcc code, is so that pthread_key_create is weak, which leads libggc.so.1 not having a run time dependency on libpthread.so.0. Tom
(In reply to Tom Kacvinsky from comment #6) > For compatibility reasons, I want to update my automated build machine, but > build GCC and auxiliary support libraries in such a fashion that we can > target older Linux distributions That is, build on a machine with a newer > glibc, but still be able to run the resulting binaries on a system with an > older glibc, which is reverse of building on an older system and running on > a newer system. > You can use a cross compiler to that. Check scripts/build-many-glibcs.py in glibc source to see how to build a toolchain with a different glibc.