Description
There's a rare chance that when using the C:R:Z XS module under Linux (possibly others, like Solaris), there may be a symbol collision depending on your backend environment (perlcc, mod_perl, or other modules).
Zlib.so exports these functions, globally, without any symbol versions (via readelf -s blib/arch/auto/Compress/Raw/Zlib/Zlib.so | egrep flate
)
57: 0000000000012ce0 198 FUNC GLOBAL DEFAULT 14 inflateResetKeep
61: 0000000000015650 80 FUNC GLOBAL DEFAULT 14 inflateCodesUsed
62: 00000000000152d0 75 FUNC GLOBAL DEFAULT 14 inflateSyncPoint
64: 000000000000f310 228 FUNC GLOBAL DEFAULT 14 deflateResetKeep
65: 0000000000012580 62 FUNC GLOBAL DEFAULT 14 inflateBackEnd
66: 0000000000015530 70 FUNC GLOBAL DEFAULT 14 inflateUndermine
67: 0000000000012ee0 192 FUNC GLOBAL DEFAULT 14 inflateInit2_
69: 0000000000014ec0 212 FUNC GLOBAL DEFAULT 14 inflateSetDictionary
70: 0000000000012e10 198 FUNC GLOBAL DEFAULT 14 inflateReset2
77: 000000000000f590 210 FUNC GLOBAL DEFAULT 14 deflatePrime
78: 000000000000f800 4985 FUNC GLOBAL DEFAULT 14 deflate
On ELF based systems (Linux, etc), unversioned symbols preempt versioned ones, so you could run into issues such as what was described in this bug report with CryptX, as well as these upstream reports relating to symbol versions, as well as this
He's what LD_DEBUG=all shows on some test code:
foo.1358336: 1358336: symbol=inflate; lookup in file=/usr/lib/x86_64-linux-gnu/perl/5.30/auto/Compress/Raw/Zlib/Zlib.so [0]
foo.1358336: 1358336: symbol=inflate; lookup in file=/lib/x86_64-linux-gnu/libz.so.1 [0]
Which yields the following:
foo.1358336: 1358336: binding file /usr/lib/x86_64-linux-gnu/perl/5.30/auto/Compress/Raw/Zlib/Zlib.so [0] to /lib/x86_64-linux-gnu/libz.so.1 [0]: normal symbol `inflate'
A small rant: ELF systems (Solaris, Linux) situation is ever worse because they allow runtime symbol interposition (i.e. libraries compete for who wins over symbol names at program startup). There's no telling what symbol you will get, as the flat namespace model shows.
Some ideas to avoid any issues:
- Use zlib.map from upstream when building zlib-src
- -Bsymbolic to the linker/compiler flags? <-- not tested, unsure of how it would work unless you linked libperl.so / libperl.a at link time
- Avoid building zlib-src and just depend on the system libz