2 # SPDX-License-Identifier: 0BSD
4 ###############################################################################
6 # Check liblzma_*.map for certain types of errors.
8 # liblzma_generic.map is for FreeBSD and Solaris and possibly others
11 # liblzma_linux.map is for GNU/Linux only. This and the matching extra code
12 # in the .c files make liblzma >= 5.2.7 compatible with binaries that were
13 # linked against ill-patched liblzma in RHEL/CentOS 7. By providing the
14 # compatibility in official XZ Utils release will hopefully prevent people
15 # from further copying the broken patch to other places when they want
16 # compatibility with binaries linked on RHEL/CentOS 7. The long version
19 # RHEL/CentOS 7 shipped with 5.1.2alpha, including the threaded
20 # encoder that is behind #ifdef LZMA_UNSTABLE in the API headers.
21 # In 5.1.2alpha these symbols are under XZ_5.1.2alpha in liblzma.map.
22 # API/ABI compatibility tracking isn't done between development
23 # releases so newer releases didn't have XZ_5.1.2alpha anymore.
25 # Later RHEL/CentOS 7 updated xz to 5.2.2 but they wanted to keep
26 # the exported symbols compatible with 5.1.2alpha. After checking
27 # the ABI changes it turned out that >= 5.2.0 ABI is backward
28 # compatible with the threaded encoder functions from 5.1.2alpha
29 # (but not vice versa as fixes and extensions to these functions
30 # were made between 5.1.2alpha and 5.2.0).
32 # In RHEL/CentOS 7, XZ Utils 5.2.2 was patched with
33 # xz-5.2.2-compat-libs.patch to modify liblzma.map:
35 # - XZ_5.1.2alpha was added with lzma_stream_encoder_mt and
36 # lzma_stream_encoder_mt_memusage. This matched XZ Utils 5.1.2alpha.
38 # - XZ_5.2 was replaced with XZ_5.2.2. It is clear that this was
39 # an error; the intention was to keep using XZ_5.2 (XZ_5.2.2
40 # has never been used in XZ Utils). So XZ_5.2.2 lists all
41 # symbols that were listed under XZ_5.2 before the patch.
42 # lzma_stream_encoder_mt and _mt_memusage are included too so
43 # they are listed both here and under XZ_5.1.2alpha.
45 # The patch didn't add any __asm__(".symver ...") lines to the .c
46 # files. Thus the resulting liblzma.so exports the threaded encoder
47 # functions under XZ_5.1.2alpha only. Listing the two functions
48 # also under XZ_5.2.2 in liblzma.map has no effect without
49 # matching .symver lines.
51 # The lack of XZ_5.2 in RHEL/CentOS 7 means that binaries linked
52 # against unpatched XZ Utils 5.2.x won't run on RHEL/CentOS 7.
53 # This is unfortunate but this alone isn't too bad as the problem
54 # is contained within RHEL/CentOS 7 and doesn't affect users
55 # of other distributions. It could also be fixed internally in
58 # The second problem is more serious: In XZ Utils 5.2.2 the API
59 # headers don't have #ifdef LZMA_UNSTABLE for obvious reasons.
60 # This is true in RHEL/CentOS 7 version too. Thus now programs
61 # using new APIs can be compiled without an extra #define. However,
62 # the programs end up depending on symbol version XZ_5.1.2alpha
63 # (and possibly also XZ_5.2.2) instead of XZ_5.2 as they would
64 # with an unpatched XZ Utils 5.2.2. This means that such binaries
65 # won't run on other distributions shipping XZ Utils >= 5.2.0 as
66 # they don't provide XZ_5.1.2alpha or XZ_5.2.2; they only provide
67 # XZ_5.2 (and XZ_5.0). (This includes RHEL/CentOS 8 as the patch
68 # luckily isn't included there anymore with XZ Utils 5.2.4.)
70 # Binaries built by RHEL/CentOS 7 users get distributed and then
71 # people wonder why they don't run on some other distribution.
72 # Seems that people have found out about the patch and been copying
73 # it to some build scripts, seemingly curing the symptoms but
74 # actually spreading the illness further and outside RHEL/CentOS 7.
75 # Adding compatibility in an official XZ Utils release should work
76 # as a vaccine against this ill patch and stop it from spreading.
77 # The vaccine is kept GNU/Linux-only as other OSes should be immune
78 # (hopefully it hasn't spread via some build script to other OSes).
80 # Author: Lasse Collin
82 ###############################################################################
91 # Get the list of symbols that aren't defined in liblzma_generic.map.
92 SYMS
=$
(sed -n 's/^extern LZMA_API([^)]*) \([a-z0-9_]*\)(.*$/\1;/p' \
95 |
grep -Fve "$(sed '/[{}:*]/d;/^$/d;s/^ //' liblzma_generic.map)")
97 # Check that there are no old alpha or beta versions listed.
98 VER
=$
(cd ..
/..
&& sh build-aux
/version.sh
)
102 NAMES
=$
(sed -n 's/^.*XZ_\([^ ]*\)\(alpha\|beta\) .*$/\1\2/p' \
103 liblzma_generic.map |
grep -Fv "$VER")
107 # Check for duplicate lines. It can catch missing dependencies.
108 DUPS
=$
(sort liblzma_generic.map |
sed '/^$/d;/^global:$/d' |
uniq -d)
110 # Check that liblzma_linux.map is in sync with liblzma_generic.map.
111 # The RHEL/CentOS 7 compatibility symbols are in a fixed location
112 # so it makes it easy to remove them for comparison with liblzma_generic.map.
114 # NOTE: Putting XZ_5.2 before the compatibility symbols XZ_5.1.2alpha
115 # and XZ_5.2.2 in liblzma_linux.map is important: If liblzma_linux.map is
116 # incorrectly used without #define HAVE_SYMBOL_VERSIONS_LINUX, only the first
117 # occurrence of each function name will be used from liblzma_linux.map;
118 # the rest are ignored by the linker. Thus having XZ_5.2 before the
119 # compatibility symbols means that @@XZ_5.2 will be used for the symbols
120 # listed under XZ_5.2 {...} and the same function names later in
121 # the file under XZ_5.1.2alpha {...} and XZ_5.2.2 {...} will be
122 # ignored (@XZ_5.1.2alpha or @XZ_5.2.2 won't be added at all when
123 # the #define HAVE_SYMBOL_VERSIONS_LINUX isn't used).
125 if ! sed '111,125d' liblzma_linux.map \
126 |
cmp -s - liblzma_generic.map
; then
130 # Print error messages if needed.
131 if test -n "$SYMS$NAMES$DUPS$IN_SYNC"; then
133 echo 'validate_map.sh found problems from liblzma_*.map:'
136 if test -n "$SYMS"; then
137 echo 'liblzma_generic.map lacks the following symbols:'
142 if test -n "$NAMES"; then
143 echo 'Obsolete alpha or beta version names:'
148 if test -n "$DUPS"; then
149 echo 'Duplicate lines:'
154 if test -n "$IN_SYNC"; then
155 echo "liblzma_generic.map and liblzma_linux.map aren't in sync"
162 # Exit status is 1 if problems were found, 0 otherwise.