zig icon indicating copy to clipboard operation
zig copied to clipboard

`glibc`: Define `_IO_stdin_used` in start code and reference it in stub asm.

Open alexrp opened this issue 1 year ago • 3 comments

This is necessary to inform the real, non-stub glibc that a program built with Zig is using a modern FILE structure, i.e. glibc 2.1+. This is particularly important on lesser-used architectures where the legacy code is poorly tested; for example, glibc 2.40 introduced a regression for the legacy case in the libio cleanup code, causing all Zig-compiled MIPS binaries to crash on exit.

alexrp avatar Aug 17 '24 10:08 alexrp

FWIW I double checked and since _IO_stdin_used is exposed as global now and libc.so wants to import it (weak-ref), the linker will mark the symbol as export and it will make it into the dynamic symbol table. The bit of functionality responsible for this is indeed what I already pointed at: https://github.com/ziglang/zig/blob/bb70501060a8bfff25818cf1d80491d724f8a634/src/link/Elf/SharedObject.zig#L288

kubkon avatar Aug 17 '24 20:08 kubkon

@kubkon I updated the PR with a more detailed comment explaining why I'm making it unconditionally emit the reference regardless of target arch/ABI.

alexrp avatar Aug 17 '24 21:08 alexrp

I don't get it. The symbol is both provided in the static libc_nonshared.a as well as a dynamic reference to libc.so?

The symbol is defined in Scrt1.o and referenced by libc.so. Note that the stub writing code only emits a (dummy) reference to it, not a definition. This is the moral equivalent of what the real glibc does; it has a weak reference to _IO_stdin_used in libio, and that reference is what actually prevents the symbol from just being discarded by the linker, but instead put into the dynamic symbol table of the executable.

(And yes, it's all very silly, but unfortunately necessary.)

alexrp avatar Aug 23 '24 08:08 alexrp