diff options
Diffstat (limited to '')
-rw-r--r-- | src/liblzma/validate_map.sh | 113 |
1 files changed, 105 insertions, 8 deletions
diff --git a/src/liblzma/validate_map.sh b/src/liblzma/validate_map.sh index 3aee4668..2bf6f8b9 100644 --- a/src/liblzma/validate_map.sh +++ b/src/liblzma/validate_map.sh @@ -2,7 +2,79 @@ ############################################################################### # -# Check liblzma.map for certain types of errors +# Check liblzma_*.map for certain types of errors. +# +# liblzma_generic.map is for FreeBSD and Solaris and possibly others +# except GNU/Linux. +# +# liblzma_linux.map is for GNU/Linux only. This and the matching extra code +# in the .c files make liblzma >= 5.2.7 compatible with binaries that were +# linked against ill-patched liblzma in RHEL/CentOS 7. By providing the +# compatibility in official XZ Utils release will hopefully prevent people +# from further copying the broken patch to other places when they want +# compatibility with binaries linked on RHEL/CentOS 7. The long version +# of the story: +# +# RHEL/CentOS 7 shipped with 5.1.2alpha, including the threaded +# encoder that is behind #ifdef LZMA_UNSTABLE in the API headers. +# In 5.1.2alpha these symbols are under XZ_5.1.2alpha in liblzma.map. +# API/ABI compatibility tracking isn't done between development +# releases so newer releases didn't have XZ_5.1.2alpha anymore. +# +# Later RHEL/CentOS 7 updated xz to 5.2.2 but they wanted to keep +# the exported symbols compatible with 5.1.2alpha. After checking +# the ABI changes it turned out that >= 5.2.0 ABI is backward +# compatible with the threaded encoder functions from 5.1.2alpha +# (but not vice versa as fixes and extensions to these functions +# were made between 5.1.2alpha and 5.2.0). +# +# In RHEL/CentOS 7, XZ Utils 5.2.2 was patched with +# xz-5.2.2-compat-libs.patch to modify liblzma.map: +# +# - XZ_5.1.2alpha was added with lzma_stream_encoder_mt and +# lzma_stream_encoder_mt_memusage. This matched XZ Utils 5.1.2alpha. +# +# - XZ_5.2 was replaced with XZ_5.2.2. It is clear that this was +# an error; the intention was to keep using XZ_5.2 (XZ_5.2.2 +# has never been used in XZ Utils). So XZ_5.2.2 lists all +# symbols that were listed under XZ_5.2 before the patch. +# lzma_stream_encoder_mt and _mt_memusage are included too so +# they are listed both here and under XZ_5.1.2alpha. +# +# The patch didn't add any __asm__(".symver ...") lines to the .c +# files. Thus the resulting liblzma.so exports the threaded encoder +# functions under XZ_5.1.2alpha only. Listing the two functions +# also under XZ_5.2.2 in liblzma.map has no effect without +# matching .symver lines. +# +# The lack of XZ_5.2 in RHEL/CentOS 7 means that binaries linked +# against unpatched XZ Utils 5.2.x won't run on RHEL/CentOS 7. +# This is unfortunate but this alone isn't too bad as the problem +# is contained within RHEL/CentOS 7 and doesn't affect users +# of other distributions. It could also be fixed internally in +# RHEL/CentOS 7. +# +# The second problem is more serious: In XZ Utils 5.2.2 the API +# headers don't have #ifdef LZMA_UNSTABLE for obvious reasons. +# This is true in RHEL/CentOS 7 version too. Thus now programs +# using new APIs can be compiled without an extra #define. However, +# the programs end up depending on symbol version XZ_5.1.2alpha +# (and possibly also XZ_5.2.2) instead of XZ_5.2 as they would +# with an unpatched XZ Utils 5.2.2. This means that such binaries +# won't run on other distributions shipping XZ Utils >= 5.2.0 as +# they don't provide XZ_5.1.2alpha or XZ_5.2.2; they only provide +# XZ_5.2 (and XZ_5.0). (This includes RHEL/CentOS 8 as the patch +# luckily isn't included there anymore with XZ Utils 5.2.4.) +# +# Binaries built by RHEL/CentOS 7 users get distributed and then +# people wonder why they don't run on some other distribution. +# Seems that people have found out about the patch and been copying +# it to some build scripts, seemingly curing the symptoms but +# actually spreading the illness further and outside RHEL/CentOS 7. +# Adding compatibility in an official XZ Utils release should work +# as a vaccine against this ill patch and stop it from spreading. +# The vaccine is kept GNU/Linux-only as other OSes should be immune +# (hopefully it hasn't spread via some build script to other OSes). # # Author: Lasse Collin # @@ -18,11 +90,11 @@ STATUS=0 cd "$(dirname "$0")" -# Get the list of symbols that aren't defined in liblzma.map. +# Get the list of symbols that aren't defined in liblzma_generic.map. SYMS=$(sed -n 's/^extern LZMA_API([^)]*) \([a-z0-9_]*\)(.*$/\1;/p' \ api/lzma/*.h \ | sort \ - | grep -Fve "$(sed '/[{}:*]/d;/^$/d;s/^ //' liblzma.map)") + | grep -Fve "$(sed '/[{}:*]/d;/^$/d;s/^ //' liblzma_generic.map)") # Check that there are no old alpha or beta versions listed. VER=$(cd ../.. && sh build-aux/version.sh) @@ -30,21 +102,41 @@ NAMES= case $VER in *alpha | *beta) NAMES=$(sed -n 's/^.*XZ_\([^ ]*\)\(alpha\|beta\) .*$/\1\2/p' \ - liblzma.map | grep -Fv "$VER") + liblzma_generic.map | grep -Fv "$VER") ;; esac # Check for duplicate lines. It can catch missing dependencies. -DUPS=$(sort liblzma.map | sed '/^$/d;/^global:$/d' | uniq -d) +DUPS=$(sort liblzma_generic.map | sed '/^$/d;/^global:$/d' | uniq -d) + +# Check that liblzma_linux.map is in sync with liblzma_generic.map. +# The RHEL/CentOS 7 compatibility symbols are in a fixed location +# so it makes it easy to remove them for comparison with liblzma_generic.map. +# +# NOTE: Putting XZ_5.2 before the compatibility symbols XZ_5.1.2alpha +# and XZ_5.2.2 in liblzma_linux.map is important: If liblzma_linux.map is +# incorrectly used without #define HAVE_SYMBOL_VERSIONS_LINUX, only the first +# occurrence of each function name will be used from liblzma_linux.map; +# the rest are ignored by the linker. Thus having XZ_5.2 before the +# compatibility symbols means that @@XZ_5.2 will be used for the symbols +# listed under XZ_5.2 {...} and the same function names later in +# the file under XZ_5.1.2alpha {...} and XZ_5.2.2 {...} will be +# ignored (@XZ_5.1.2alpha or @XZ_5.2.2 won't be added at all when +# the #define HAVE_SYMBOL_VERSIONS_LINUX isn't used). +IN_SYNC= +if ! sed '109,123d' liblzma_linux.map \ + | cmp -s - liblzma_generic.map; then + IN_SYNC=no +fi # Print error messages if needed. -if test -n "$SYMS$NAMES$DUPS"; then +if test -n "$SYMS$NAMES$DUPS$IN_SYNC"; then echo - echo 'validate_map.sh found problems from liblzma.map:' + echo 'validate_map.sh found problems from liblzma_*.map:' echo if test -n "$SYMS"; then - echo 'liblzma.map lacks the following symbols:' + echo 'liblzma_generic.map lacks the following symbols:' echo "$SYMS" echo fi @@ -61,6 +153,11 @@ if test -n "$SYMS$NAMES$DUPS"; then echo fi + if test -n "$IN_SYNC"; then + echo "liblzma_generic.map and liblzma_linux.map aren't in sync" + echo + fi + STATUS=1 fi |