Fix symbol mangling and prefix gz_error#2097
Conversation
mtl1979
commented
Jan 12, 2026
- We need to mangle symbols in the map file, otherwise none of the symbols are exported
WalkthroughGenerate version-script maps from templates into the build directory, reference generated maps in linker flags, ignore generated maps in Git, add map cleanup to distclean, and route internal gz_error calls through the Changes
Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (2)
zlib-ng.mapis excluded by!**/*.mapzlib.mapis excluded by!**/*.map
📒 Files selected for processing (6)
.gitignoreCMakeLists.txtMakefile.inconfigurezlib-ng.map.inzlib.map.in
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
Learnt from: mtl1979
Repo: zlib-ng/zlib-ng PR: 1925
File: arch/loongarch/lasxintrin_ext.h:38-65
Timestamp: 2025-07-04T16:59:44.725Z
Learning: In zlib-ng, the policy for supporting old compilers is to maintain compatibility for up to two years after GitHub removes support for them in CI, or when there is no long-time contributor left testing for the architecture if the architecture was not supported by GitHub Actions at all.
Learnt from: Dead2
Repo: zlib-ng/zlib-ng PR: 2001
File: test/CMakeLists.txt:10-12
Timestamp: 2025-11-15T12:43:50.353Z
Learning: In zlib-ng, the TEST_STOCK_ZLIB CMake variable is intentionally not defined as a CMake option. It's meant to be set manually via command-line (e.g., -DTEST_STOCK_ZLIB=ON) when testing against stock zlib. The testing workflow for stock zlib requires undocumented manual steps and is considered experimental/incomplete.
📚 Learning: 2025-11-15T12:43:50.353Z
Learnt from: Dead2
Repo: zlib-ng/zlib-ng PR: 2001
File: test/CMakeLists.txt:10-12
Timestamp: 2025-11-15T12:43:50.353Z
Learning: In zlib-ng, the TEST_STOCK_ZLIB CMake variable is intentionally not defined as a CMake option. It's meant to be set manually via command-line (e.g., -DTEST_STOCK_ZLIB=ON) when testing against stock zlib. The testing workflow for stock zlib requires undocumented manual steps and is considered experimental/incomplete.
Applied to files:
.gitignoreCMakeLists.txtzlib-ng.map.in
📚 Learning: 2025-12-05T19:54:22.258Z
Learnt from: Dead2
Repo: zlib-ng/zlib-ng PR: 2039
File: CMakeLists.txt:121-121
Timestamp: 2025-12-05T19:54:22.258Z
Learning: In zlib-ng CMakeLists.txt, for cmake_dependent_option calls with single variable dependencies (e.g., ARCH_32BIT, ARCH_64BIT), quotes around the dependency variable are optional and not required by CMake. Quotes are only necessary for complex conditions with operators or spaces.
Applied to files:
.gitignoreCMakeLists.txt
📚 Learning: 2025-07-04T16:59:44.725Z
Learnt from: mtl1979
Repo: zlib-ng/zlib-ng PR: 1925
File: arch/loongarch/lasxintrin_ext.h:38-65
Timestamp: 2025-07-04T16:59:44.725Z
Learning: In zlib-ng, the policy for supporting old compilers is to maintain compatibility for up to two years after GitHub removes support for them in CI, or when there is no long-time contributor left testing for the architecture if the architecture was not supported by GitHub Actions at all.
Applied to files:
.gitignoreCMakeLists.txtzlib-ng.map.inzlib.map.in
📚 Learning: 2025-10-12T17:01:13.630Z
Learnt from: mtl1979
Repo: zlib-ng/zlib-ng PR: 1980
File: compress.c:31-33
Timestamp: 2025-10-12T17:01:13.630Z
Learning: In zlib-ng, when ZLIB_COMPAT is defined, z_int32_t is typedef'd as `int` (not int32_t), and zlib.h is included (which uses `int` in function signatures). This allows the implementation to use z_int32_t while maintaining backwards compatibility with the original zlib API that uses `int`. When ZLIB_COMPAT is not defined, z_int32_t is typedef'd as int32_t and zlib-ng.h is used instead.
Applied to files:
CMakeLists.txtzlib-ng.map.inzlib.map.in
📚 Learning: 2025-08-20T14:34:15.867Z
Learnt from: Dead2
Repo: zlib-ng/zlib-ng PR: 1928
File: gzwrite.c:0-0
Timestamp: 2025-08-20T14:34:15.867Z
Learning: Z_VERSION_ERROR is used by zlib but not by zlib-ng, so it should not be included in error handling for zlib-ng deflateInit2() calls.
Applied to files:
zlib-ng.map.inzlib.map.in
📚 Learning: 2025-07-04T20:17:58.531Z
Learnt from: Dead2
Repo: zlib-ng/zlib-ng PR: 1928
File: gzlib.c:90-90
Timestamp: 2025-07-04T20:17:58.531Z
Learning: In zlib-ng's gz_buffer_alloc() function, the condition `(out_mult >= 1 && state->out == NULL)` is necessary because state->out is intentionally left as NULL when out_mult == 0 (write + direct mode), but should be allocated when out_mult >= 1. The condition properly distinguishes between intentionally NULL buffers and allocation failures.
Applied to files:
zlib-ng.map.in
📚 Learning: 2025-05-13T06:56:12.407Z
Learnt from: samrussell
Repo: zlib-ng/zlib-ng PR: 1914
File: arch/generic/crc32_chorba_c.c:30-32
Timestamp: 2025-05-13T06:56:12.407Z
Learning: In zlib-ng, pointer casts between z_word_t* and uint64_t* are safe because: 1) On 64-bit platforms, z_word_t is defined as uint64_t, making the cast a no-op; 2) On 32-bit platforms where z_word_t is uint32_t, the code paths using uint64_t* are skipped in favor of 32-bit specific implementations.
Applied to files:
zlib-ng.map.in
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (102)
- GitHub Check: macOS GCC UBSAN (ARM64)
- GitHub Check: Windows MSVC 2022 v141 Win32
- GitHub Check: macOS Clang Native Instructions (Intel)
- GitHub Check: EL10 Clang S390X DFLTCC MSAN
- GitHub Check: Windows MSVC 2022 v143 Win64
- GitHub Check: Windows MSVC ARM64 No Test
- GitHub Check: Windows GCC
- GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
- GitHub Check: Ubuntu GCC No CTZLL
- GitHub Check: macOS GCC UBSAN (ARM64)
- GitHub Check: Windows MSVC 2022 v141 Win32
- GitHub Check: macOS Clang Native Instructions (Intel)
- GitHub Check: EL10 Clang S390X DFLTCC MSAN
- GitHub Check: Windows MSVC 2022 v143 Win64
- GitHub Check: Windows MSVC ARM64 No Test
- GitHub Check: Windows GCC
- GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
- GitHub Check: Ubuntu GCC No CTZLL
- GitHub Check: macOS GCC UBSAN (ARM64)
- GitHub Check: Windows MSVC 2022 v141 Win32
- GitHub Check: macOS Clang Native Instructions (Intel)
- GitHub Check: EL10 Clang S390X DFLTCC MSAN
- GitHub Check: Windows MSVC 2022 v143 Win64
- GitHub Check: Windows MSVC ARM64 No Test
- GitHub Check: Windows GCC
- GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
- GitHub Check: Ubuntu GCC No CTZLL
- GitHub Check: macOS GCC UBSAN (ARM64)
- GitHub Check: Windows MSVC 2022 v141 Win32
- GitHub Check: macOS Clang Native Instructions (Intel)
- GitHub Check: EL10 Clang S390X DFLTCC MSAN
- GitHub Check: Windows MSVC 2022 v143 Win64
- GitHub Check: Windows MSVC ARM64 No Test
- GitHub Check: Windows GCC
- GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
- GitHub Check: Ubuntu GCC No CTZLL
- GitHub Check: macOS GCC Symbol Prefix (ARM64)
- GitHub Check: macOS GCC UBSAN (ARM64)
- GitHub Check: Windows MSVC 2022 v141 Win32
- GitHub Check: macOS Clang Native Instructions (Intel)
- GitHub Check: EL10 Clang S390X DFLTCC MSAN
- GitHub Check: Windows MSVC 2022 v143 Win64
- GitHub Check: Windows MSVC ARM64 No Test
- GitHub Check: Windows GCC
- GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
- GitHub Check: Ubuntu GCC No CTZLL
- GitHub Check: macOS GCC Symbol Prefix (ARM64)
- GitHub Check: macOS GCC UBSAN (ARM64)
- GitHub Check: Windows MSVC 2022 v141 Win32
- GitHub Check: macOS Clang Native Instructions (Intel)
- GitHub Check: EL10 Clang S390X DFLTCC MSAN
- GitHub Check: Windows MSVC 2022 v143 Win64
- GitHub Check: Windows MSVC ARM64 No Test
- GitHub Check: Windows GCC
- GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
- GitHub Check: Ubuntu GCC No CTZLL
- GitHub Check: macOS GCC Symbol Prefix (ARM64)
- GitHub Check: macOS GCC UBSAN (ARM64)
- GitHub Check: Windows MSVC 2022 v141 Win32
- GitHub Check: macOS Clang Native Instructions (Intel)
- GitHub Check: EL10 Clang S390X DFLTCC MSAN
- GitHub Check: Windows MSVC 2022 v143 Win64
- GitHub Check: Windows MSVC ARM64 No Test
- GitHub Check: Windows GCC
- GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
- GitHub Check: Ubuntu GCC No CTZLL
- GitHub Check: macOS GCC Symbol Prefix (ARM64)
- GitHub Check: macOS GCC UBSAN (ARM64)
- GitHub Check: Windows MSVC 2022 v141 Win32
- GitHub Check: macOS Clang Native Instructions (Intel)
- GitHub Check: EL10 Clang S390X DFLTCC MSAN
- GitHub Check: Windows MSVC 2022 v143 Win64
- GitHub Check: Windows MSVC ARM64 No Test
- GitHub Check: Windows GCC
- GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
- GitHub Check: Ubuntu GCC No CTZLL
- GitHub Check: macOS GCC Symbol Prefix (ARM64)
- GitHub Check: macOS GCC UBSAN (ARM64)
- GitHub Check: Windows MSVC 2022 v141 Win32
- GitHub Check: macOS Clang Native Instructions (Intel)
- GitHub Check: EL10 Clang S390X DFLTCC MSAN
- GitHub Check: Windows ClangCl Win64 Native Instructions (AVX)
- GitHub Check: Windows MSVC 2022 v143 Win64
- GitHub Check: Windows MSVC ARM64 No Test
- GitHub Check: Windows GCC
- GitHub Check: Ubuntu MinGW i686
- GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
- GitHub Check: Ubuntu GCC No CTZLL
- GitHub Check: macOS GCC Symbol Prefix (ARM64)
- GitHub Check: macOS GCC UBSAN (ARM64)
- GitHub Check: Windows MSVC 2022 v141 Win32
- GitHub Check: macOS Clang Native Instructions (Intel)
- GitHub Check: EL10 Clang S390X DFLTCC MSAN
- GitHub Check: Windows MSVC 2022 v141 Win64
- GitHub Check: Windows ClangCl Win64 Native Instructions (AVX)
- GitHub Check: Windows MSVC 2022 v143 Win64
- GitHub Check: Windows MSVC ARM64 No Test
- GitHub Check: Windows GCC
- GitHub Check: Ubuntu MinGW i686
- GitHub Check: Ubuntu GCC AARCH64 No ARMv8 UBSAN
- GitHub Check: Ubuntu GCC No CTZLL
- GitHub Check: macOS GCC Symbol Prefix (ARM64)
🔇 Additional comments (7)
.gitignore (1)
28-34: LGTM!The ignore entries correctly match the generated map files (
zlib.mapfor compat mode andzlib-ng.mapfor zlib-ng mode) that are produced by the configure script from the corresponding.map.intemplates.Makefile.in (1)
384-384: LGTM!The distclean target correctly removes the generated
zlib${SUFFIX}.mapfile, consistent with how other generated files using the${SUFFIX}pattern are handled.configure (1)
744-745: LGTM!The map file generation correctly:
- Uses
sedto substitute@ZLIB_SYMBOL_PREFIX@with the configuredsymbol_prefix- Generates the map in the build directory (
zlib${SUFFIX}.map)- References the generated map via
BUILDDIR/$MAPNAMEin the linker flagsThis ensures symbols are properly mangled in the version script, fixing the export issue described in the PR.
zlib-ng.map.in (2)
1-9: Version blocks are not chained.Unlike
zlib.map.inwhere version blocks chain to parent versions (e.g.,} ZLIB_1.2.0;), the blocks here are standalone. This is likely intentional for zlib-ng since it doesn't need to maintain symbol versioning compatibility with older zlib versions, but please confirm this is the intended behavior.
109-111: FAIL block correctly hides unlisted symbols.The
FAIL { local: *; };block ensures any symbol not explicitly listed in the global sections is hidden. This is a good catch-all safety mechanism for symbol visibility.zlib.map.in (1)
1-98: LGTM - Symbol versioning map for zlib compatibility mode.The version script correctly:
- Uses proper version chaining from ZLIB_1.2.0 through ZLIB_1.2.12
- Lists symbols introduced in each version
- Marks internal symbols as local in the base ZLIB_1.2.0 block
- Uses the
@ZLIB_SYMBOL_PREFIX@placeholder consistently for symbol manglingThe symbol additions per version align with the historical zlib API evolution.
CMakeLists.txt (1)
1561-1564: LGTM! Correct approach for generating version-script with symbol mangling.Using
configure_file()to process the.map.intemplate allows@VARIABLE@placeholders (e.g., symbol prefix) to be substituted at configure time. Placing the generated map inCMAKE_CURRENT_BINARY_DIRfollows CMake best practices for build artifacts.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #2097 +/- ##
===========================================
- Coverage 83.93% 83.56% -0.38%
===========================================
Files 156 156
Lines 13184 13184
Branches 3211 3214 +3
===========================================
- Hits 11066 11017 -49
- Misses 1061 1130 +69
+ Partials 1057 1037 -20 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
CodeCov failures are partially because runner didn't have AVX512 support and partially because we don't test most error conditions in gzip support code. |
|
If we want to prefix gz_error, the new one ahould go into a new group 'ZLIB_NG_2.3.3'. We don't have many Z_INTERNAL symbols in the map at all. Take for example According to what I can find online, linkers use the local list to exclude those symbols from being exported, and usually don't include information about them in the binary, unless extra symbol debugging info is specifically enabled. But normal debuginfo also includes this and more, possibly this would be useful for closed-source debugging where you don't want to export the full debuginfo. My suggestion: Remove gz_error from at least the zlib-ng.map file, possibly from zlib.map as well. Nothing should have linked against it, so it should also not be possible to break anything. AFAICT: None of the internal symbols should need symbol prefixing, and likely not prefixing either. Am I wrong? Since I was worried I was missing something, I did confer with Google's AI and ChatGPT in case they had some further insight, but they both concluded pretty much the same, with Google being the more concise:
That has to be the shortest most concise AI reply I have ever gotten to something like this. 👀 So, perhaps drop the gz_error prefixing changes and instead add a commit removing gz_error from the .map and mangling files? |
|
@Dead2 We still need the mangling for static builds. I didn't check when the catch all local was added but the default is global for any unlisted symbols as is still case for zlib-compat Because static builds don't have symbol versioning, we can't introduce |
Since we use Z_INTERNAL for all internal functions, that already makes the symbols unreachable and invisible from the outside. This is something zlib does not do though, but we have done so since before our first release and we have had no complaints about that. This is also why the catch all local is named FAIL, so that we can in effect grep for it (I guess we should have added a CI test for that actually). It contains no symbols because they are all marked as internal in the source code.
To avoid introducing new things to the ABI, I am suggesting removing gz_error entirely from map. |
|
Z_INTERNAL has no effect in static builds as linker handles it for shared builds. Static builds also don't use the map file so catch all local doesn't work. Only on Windows exported symbols need to be explicitly marked as such. |
In that case static builds won't work anyway, because we have lots of Z_INTERNAL functions that do not get mangled or prefixed. |
The point (of this PR) is to gradually make both shared and static builds work with all options enabled. Removing |
I think that is something that should be done in a separate PR, and to avoid ABI churn, either don't PREFIX gz_error in this PR, or remove it from map entirely. In any case, whether the names need mangling or not for static builds, Z_INTERNAL symbols should not be in the map file. The symbols that need to be marked as local in .map files should be tagged as hidden, not internal. Marking things internal removes them from the symbol table entirely, making the library smaller and enables more optimizations. Adding them to the map file however conflicts with that. |
I'm not against removing it from the The entry was needed for validating this PR, but now I know what had to be done, so I think it's safe to remove. |
* We need to mangle symbols in the map file, otherwise none of the symbols are exported * Fix gz_error name conflict with zlib-ng API