https://sourceware.org/bugzilla/show_bug.cgi?id=24718

--- Comment #20 from Fangrui Song <i at maskray dot me> ---
(In reply to Sam James from comment #19)
> This came up recently in the context of CPython and RPM:
> https://lists.fedoraproject.org/archives/list/[email protected]/
> message/NLAFVQYXKRU7UQVF3M6SPCVPHLHZXNFY/
> (https://discuss.python.org/t/moving-expat-version-or-symbol-checks-from-
> buildtime-to-runtime/105769)

https://maskray.me/blog/2020-11-26-all-about-symbol-versioning describes this
example. I've now enhanced it after checking the latest glibc rtld behavior.


[glibc 2.30 ld.so: Support moving versioned symbols between sonames [BZ
#24741]](https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=f0b2132b35248c1f4a80f62a2c38cddcc802aa8c)
has a side benefit for weak references.
Previously, if `b.so` had a versioned weak reference `foo@v1` (where `v1`
referenced `c.so`), rtld would error with `symbol %s version %s not defined in
file %s with link time reference` when `c.so` lacked `foo@@v1` or
`foo@v1`—contrary to weak reference semantics.
Newer rtld tolerates this as long as the runtime `c.so` defines version `v1`:

```sh
echo '#include <stdio.h>\nvoid fb(); int main() { fb(); puts("a"); }' > a.c
echo '__attribute__((weak)) void foo(); void fb() { if (foo) foo(); }' > b.c
echo 'v1 { foo; };' > c-link.ver
echo '#include <stdio.h>\nvoid foo() { puts("foo"); }' > c.c
echo 'v1 { };' > c.ver
echo 'v2 { };' > c2.ver
sed 's/^        /\t/' > Makefile <<'eof'
.MAKE.MODE := meta curdirOk=1
CFLAGS := -fpic

a: a.c b.so c-link.so c.so c2.so
        $(LINK.c) a.c b.so -Wl,-rpath=$$PWD -o $@
b.so: b.c c-link.so
        $(LINK.c) -shared $> -Wl,-rpath=$$PWD -o $@
c-link.so: c.c c.ver
        $(LINK.c) -shared -Wl,-soname=c.so,--version-script=c-link.ver c.c -o
$@
c.so: c.c c.ver
        $(LINK.c) -shared -Wl,-soname=c.so,--version-script=c.ver -Dfoo=foo1
c.c -o $@
c2.so: c.c c2.ver
        $(LINK.c) -shared -Wl,-soname=c.so,--version-script=c2.ver -Dfoo=foo1
c.c -o $@
clean:
        rm -f a *.so *.o *.meta
eof
```

If `c.so` lacks the required version entirely, rtld still reports a fatal
error:
```
% ./a
a
% cp c2.so c.so
% ./a
./a: /tmp/t/v2/c.so: version `v1' not found (required by /tmp/t/v2/b.so)
```

The [BZ24718#319
comment](https://sourceware.org/bugzilla/show_bug.cgi?id=24718#c19) in 2026
asked `VER_FLG_WEAK` in `Vernaux::vna_flags` extension, allowing rtld to
continue execution (with a verbose-mode warning `weak version ... not found`)
instead of failing.

-- 
You are receiving this mail because:
You are on the CC list for the bug.

Reply via email to