1ABICOMPAT(1) Libabigail ABICOMPAT(1)
2
3
4
6 abicompat - check ABI compatibility
7
8 abicompat checks that an application that links against a given shared
9 library is still ABI compatible with a subsequent version of that li‐
10 brary. If the new version of the library introduces an ABI incompati‐
11 bility, then abicompat hints the user at what exactly that incompati‐
12 bility is.
13
15 abicompat [options] [<application> <shared-library-first-version> <shared-library-second-version>]
16
18 • --help
19
20 Display a short help about the command and exit.
21
22 • –version | -v
23
24 Display the version of the program and exit.
25
26 • --list-undefined-symbols | -u
27
28 Display the list of undefined symbols of the application and exit.
29
30 • --show-base-names | -b
31
32 In the resulting report emitted by the tool, this option makes the
33 application and libraries be referred to by their base names only;
34 not by a full absolute name. This can be useful for use in
35 scripts that wants to compare names of the application and li‐
36 braries independently of what their directory names are.
37
38 • --app-debug-info-dir | --appd <path-to-app-debug-info-directory>
39
40 Set the path to the directory under which the debug information of
41 the application is supposed to be laid out. This is useful for
42 application binaries for which the debug info is in a separate set
43 of files.
44
45 • --lib-debug-info-dir1 | --libd1 <path-to-lib1-debug-info>
46
47 Set the path to the directory under which the debug information of
48 the first version of the shared library is supposed to be laid
49 out. This is useful for shared library binaries for which the de‐
50 bug info is in a separate set of files.
51
52 • --lib-debug-info-dir2 | --libd2 <path-to-lib1-debug-info>
53
54 Set the path to the directory under which the debug information of
55 the second version of the shared library is supposed to be laid
56 out. This is useful for shared library binaries for which the de‐
57 bug info is in a separate set of files.
58
59 • --suppressions | --suppr <path-to-suppressions>
60
61 Use a suppression specification file located at path-to-suppres‐
62 sions. Note that this option can appear multiple times on the
63 command line; all the suppression specification files are then
64 taken into account.
65
66 • --no-show-locs
67 Do not show information about where in the second shared library
68 the respective type was changed.
69
70 • --ctf
71
72 When comparing binaries, extract ABI information from CTF debug
73 information, if present.
74
75 • --fail-no-debug-info
76
77 If no debug info was found, then this option makes the program to
78 fail. Otherwise, without this option, the program will attempt to
79 compare properties of the binaries that are not related to debug
80 info, like pure ELF properties.
81
82 • --ignore-soname
83
84 Ignore differences in the SONAME when doing a comparison
85
86 • --weak-mode
87
88 This triggers the weak mode of abicompat. In this mode, only one
89 version of the library is required. That is, abicompat is invoked
90 like this:
91
92 abicompat --weak-mode <the-application> <the-library>
93
94 Note that the --weak-mode option can even be omitted if only one
95 version of the library is given, along with the application; in
96 that case, abicompat automatically switches to operate in weak
97 mode:
98
99 abicompat <the-application> <the-library>
100
101 In this weak mode, the types of functions and variables exported
102 by the library and consumed by the application (as in, the symbols
103 of the these functions and variables are undefined in the applica‐
104 tion and are defined and exported by the library) are compared to
105 the version of these types as expected by the application. And if
106 these two versions of types are different, abicompat tells the
107 user what the differences are.
108
109 In other words, in this mode, abicompat checks that the types of
110 the functions and variables exported by the library mean the same
111 thing as what the application expects, as far as the ABI is con‐
112 cerned.
113
114 Note that in this mode, abicompat doesn’t detect exported func‐
115 tions or variables (symbols) that are expected by the application
116 but that are removed from the library. That is why it is called
117 weak mode.
118
120 The exit code of the abicompat command is either 0 if the ABI of the
121 binaries being compared are equal, or non-zero if they differ or if the
122 tool encountered an error.
123
124 In the later case, the exit code is a 8-bits-wide bit field in which
125 each bit has a specific meaning.
126
127 The first bit, of value 1, named ABIDIFF_ERROR means there was an er‐
128 ror.
129
130 The second bit, of value 2, named ABIDIFF_USAGE_ERROR means there was
131 an error in the way the user invoked the tool. It might be set, for
132 instance, if the user invoked the tool with an unknown command line
133 switch, with a wrong number or argument, etc. If this bit is set, then
134 the ABIDIFF_ERROR bit must be set as well.
135
136 The third bit, of value 4, named ABIDIFF_ABI_CHANGE means the ABI of
137 the binaries being compared are different.
138
139 The fourth bit, of value 8, named ABIDIFF_ABI_INCOMPATIBLE_CHANGE means
140 the ABI of the binaries compared are different in an incompatible way.
141 If this bit is set, then the ABIDIFF_ABI_CHANGE bit must be set as
142 well. If the ABIDIFF_ABI_CHANGE is set and the ABIDIFF_INCOMPATI‐
143 BLE_CHANGE is NOT set, then it means that the ABIs being compared might
144 or might not be compatible. In that case, a human being needs to re‐
145 view the ABI changes to decide if they are compatible or not.
146
147 The remaining bits are not used for the moment.
148
150 • Detecting a possible ABI incompatibility in a new shared library
151 version:
152
153 $ cat -n test0.h
154 1 struct foo
155 2 {
156 3 int m0;
157 4
158 5 foo()
159 6 : m0()
160 7 {}
161 8 };
162 9
163 10 foo*
164 11 first_func();
165 12
166 13 void
167 14 second_func(foo&);
168 15
169 16 void
170 17 third_func();
171 $
172
173 $ cat -n test-app.cc
174 1 // Compile with:
175 2 // g++ -g -Wall -o test-app -L. -ltest-0 test-app.cc
176 3
177 4 #include "test0.h"
178 5
179 6 int
180 7 main()
181 8 {
182 9 foo* f = first_func();
183 10 second_func(*f);
184 11 return 0;
185 12 }
186 $
187
188 $ cat -n test0.cc
189 1 // Compile this with:
190 2 // g++ -g -Wall -shared -o libtest-0.so test0.cc
191 3
192 4 #include "test0.h"
193 5
194 6 foo*
195 7 first_func()
196 8 {
197 9 foo* f = new foo();
198 10 return f;
199 11 }
200 12
201 13 void
202 14 second_func(foo&)
203 15 {
204 16 }
205 17
206 18 void
207 19 third_func()
208 20 {
209 21 }
210 $
211
212 $ cat -n test1.h
213 1 struct foo
214 2 {
215 3 int m0;
216 4 char m1; /* <-- a new member got added here! */
217 5
218 6 foo()
219 7 : m0(),
220 8 m1()
221 9 {}
222 10 };
223 11
224 12 foo*
225 13 first_func();
226 14
227 15 void
228 16 second_func(foo&);
229 17
230 18 void
231 19 third_func();
232 $
233
234 $ cat -n test1.cc
235 1 // Compile this with:
236 2 // g++ -g -Wall -shared -o libtest-1.so test1.cc
237 3
238 4 #include "test1.h"
239 5
240 6 foo*
241 7 first_func()
242 8 {
243 9 foo* f = new foo();
244 10 return f;
245 11 }
246 12
247 13 void
248 14 second_func(foo&)
249 15 {
250 16 }
251 17
252 18 /* Let's comment out the definition of third_func()
253 19 void
254 20 third_func()
255 21 {
256 22 }
257 23 */
258 $
259
260 • Compile the first and second versions of the libraries:
261 libtest-0.so and libtest-1.so:
262
263 $ g++ -g -Wall -shared -o libtest-0.so test0.cc
264 $ g++ -g -Wall -shared -o libtest-1.so test1.cc
265
266 • Compile the application and link it against the first version of
267 the library, creating the test-app binary:
268
269 $ g++ -g -Wall -o test-app -L. -ltest-0.so test-app.cc
270
271 • Now, use abicompat to see if libtest-1.so is ABI compatible with
272 app, with respect to the ABI of libtest-0.so:
273
274 $ abicompat test-app libtest-0.so libtest-1.so
275 ELF file 'test-app' might not be ABI compatible with 'libtest-1.so' due to differences with 'libtest-0.so' below:
276 Functions changes summary: 0 Removed, 2 Changed, 0 Added functions
277 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
278
279 2 functions with some indirect sub-type change:
280
281 [C]'function foo* first_func()' has some indirect sub-type changes:
282 return type changed:
283 in pointed to type 'struct foo':
284 size changed from 32 to 64 bits
285 1 data member insertion:
286 'char foo::m1', at offset 32 (in bits)
287 [C]'function void second_func(foo&)' has some indirect sub-type changes:
288 parameter 0 of type 'foo&' has sub-type changes:
289 referenced type 'struct foo' changed, as reported earlier
290
291 $
292
293 • Now use the weak mode of abicompat, that is, providing just the
294 application and the new version of the library:
295
296 $ abicompat --weak-mode test-app libtest-1.so
297 functions defined in library
298 'libtest-1.so'
299 have sub-types that are different from what application
300 'test-app'
301 expects:
302
303 function foo* first_func():
304 return type changed:
305 in pointed to type 'struct foo':
306 size changed from 32 to 64 bits
307 1 data member insertion:
308 'char foo::m1', at offset 32 (in bits)
309
310 $
311
313 Dodji Seketeli
314
316 2014-2023, Red Hat, Inc.
317
318
319
320
321 Nov 20, 2023 ABICOMPAT(1)