1ABIDIFF(1) Libabigail ABIDIFF(1)
2
3
4
6 abidiff - compare ABIs of ELF files
7
8 abidiff compares the Application Binary Interfaces (ABI) of two shared
9 libraries in ELF format. It emits a meaningful report describing the
10 differences between the two ABIs.
11
12 This tool can also compare the textual representations of the ABI of
13 two ELF binaries (as emitted by abidw) or an ELF binary against a tex‐
14 tual representation of another ELF binary.
15
16 For a comprehensive ABI change report that includes changes about func‐
17 tion and variable sub-types, the two input shared libraries must be
18 accompanied with their debug information in DWARF format. Otherwise,
19 only ELF symbols that were added or removed are reported.
20
22 abidiff [options] <first-shared-library> <second-shared-library>
23
25 abidiff loads two default suppression specifications files, merges
26 their content and use it to filter out ABI change reports that might be
27 considered as false positives to users.
28
29 · Default system-wide suppression specification file
30
31 It’s located by the optional environment variable LIBABI‐
32 GAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE. If that environment variable
33 is not set, then abidiff tries to load the suppression file $lib‐
34 dir/libabigail/libabigail-default.abignore. If that file is not
35 present, then no default system-wide suppression specification file
36 is loaded.
37
38 · Default user suppression specification file.
39
40 It’s located by the optional environment LIBABIGAIL_DEFAULT_USER_SUP‐
41 PRESSION_FILE. If that environment variable is not set, then abidiff
42 tries to load the suppression file $HOME/.abignore. If that file is
43 not present, then no default user suppression specification is
44 loaded.
45
47 · --help | -h
48
49 Display a short help about the command and exit.
50
51 · --version | -v
52
53 Display the version of the program and exit.
54
55 · --debug-info-dir1 | --d1 <di-path1>
56
57 For cases where the debug information for first-shared-library is
58 split out into a separate file, tells abidiff where to find that
59 separate debug information file.
60
61 Note that di-path must point to the root directory under which the
62 debug information is arranged in a tree-like manner. Under Red
63 Hat based systems, that directory is usually <root>/usr/lib/debug.
64
65 This option can be provided several times with different root
66 directories. In that case, abidiff will potentially look into all
67 those root directories to find the split debug info for
68 first-shared-library.
69
70 Note also that this option is not mandatory for split debug infor‐
71 mation installed by your system’s package manager because then
72 abidiff knows where to find it.
73
74 · --debug-info-dir2 | --d2 <di-path2>
75
76 Like --debug-info-dir1, this options tells abidiff where to find
77 the split debug information for the second-shared-library file.
78
79 This option can be provided several times with different root
80 directories. In that case, abidiff will potentially look into all
81 those root directories to find the split debug info for sec‐
82 ond-shared-library.
83
84 · --headers-dir1 | --hd1 <headers-directory-path-1>
85
86 Specifies where to find the public headers of the first shared
87 library that the tool has to consider. The tool will thus filter
88 out ABI changes on types that are not defined in public headers.
89
90 · --headers-dir2 | --hd2 <headers-directory-path-1>
91
92 Specifies where to find the public headers of the second shared
93 library that the tool has to consider. The tool will thus filter
94 out ABI changes on types that are not defined in public headers.
95
96 · --no-linux-kernel-mode
97
98 Without this option, if abidiff detects that the binaries it is
99 looking at are Linux Kernel binaries (either vmlinux or modules)
100 then it only considers functions and variables which ELF symbols
101 are listed in the __ksymtab and __ksymtab_gpl sections.
102
103 With this option, abidiff considers the binary as a non-special
104 ELF binary. It thus considers functions and variables which are
105 defined and exported in the ELF sense.
106
107 · --kmi-whitelist | -kaw <path-to-whitelist>
108
109 When analyzing a Linux kernel binary, this option points to the
110 white list of names of ELF symbols of functions and variables
111 which ABI must be considered. That white list is called a “Kernel
112 Module Interface white list”. This is because for the Kernel, we
113 don’t talk about ABI; we rather talk about the interface between
114 the Kernel and its module. Hence the term KMI rather than ABI.
115
116 Any other function or variable which ELF symbol are not present in
117 that white list will not be considered by this tool.
118
119 If this option is not provided – thus if no white list is provided
120 – then the entire KMI, that is, the set of all publicly defined
121 and exported functions and global variables by the Linux Kernel
122 binaries, is considered.
123
124 · --drop-private-types
125
126 This option is to be used with the --headers-dir1 and --head‐
127 ers-dir2 options. With this option, types that are NOT defined in
128 the headers are entirely dropped from the internal representation
129 build by Libabigail to represent the ABI. They thus don’t have to
130 be filtered out from the final ABI change report because they are
131 not even present in Libabigail’s representation.
132
133 Without this option however, those private types are kept in the
134 internal representation and later filtered out from the report.
135
136 This options thus potentially makes Libabigail consume less mem‐
137 ory. It’s meant to be mainly used to optimize the memory consump‐
138 tion of the tool on binaries with a lot of publicly defined and
139 exported types.
140
141 · --stat
142
143 Rather than displaying the detailed ABI differences between
144 first-shared-library and second-shared-library, just display some
145 summary statistics about these differences.
146
147 · --symtabs
148
149 Only display the symbol tables of the first-shared-library and
150 second-shared-library.
151
152 · --deleted-fns
153
154 In the resulting report about the differences between
155 first-shared-library and second-shared-library, only display the
156 globally defined functions that got deleted from
157 first-shared-library.
158
159 · --changed-fns
160
161 In the resulting report about the differences between
162 first-shared-library and second-shared-library, only display the
163 changes in sub-types of the global functions defined in
164 first-shared-library.
165
166 · --added-fns
167
168 In the resulting report about the differences between
169 first-shared-library and second-shared-library, only display the
170 globally defined functions that were added to sec‐
171 ond-shared-library.
172
173 · --deleted-vars
174
175 In the resulting report about the differences between
176 first-shared-library and second-shared-library, only display the
177 globally defined variables that were deleted from
178 first-shared-library.
179
180 · --changed-vars
181
182 In the resulting report about the differences between
183 first-shared-library and second-shared-library, only display the
184 changes in the sub-types of the global variables defined in
185 first-shared-library
186
187 · --added-vars
188
189 In the resulting report about the differences between
190 first-shared-library and second-shared-library, only display the
191 global variables that were added (defined) to sec‐
192 ond-shared-library.
193
194 · --non-reachable-types|-t
195
196 Analyze and emit change reports for all the types of the binary,
197 including those that are not reachable from global functions and
198 variables.
199
200 This option might incur some serious performance degradation as
201 the number of types analyzed can be huge. However, if paired with
202 the --headers-dir{1,2} options, the additional non-reachable types
203 analyzed are restricted to those defined in public headers files,
204 thus hopefully making the performance hit acceptable.
205
206 Also, using this option alongside suppression specifications (by
207 also using the --suppressions option) might help keep the number
208 of analyzed types (and the potential performance degradation) in
209 control.
210
211 Note that without this option, only types that are reachable from
212 global functions and variables are analyzed, so the tool detects
213 and reports changes on these reachable types only.
214
215 · --no-added-syms
216
217 In the resulting report about the differences between
218 first-shared-library and second-shared-library, do not display
219 added functions or variables. Do not display added functions or
220 variables ELF symbols either. All other kinds of changes are dis‐
221 played unless they are explicitely forbidden by other options on
222 the command line.
223
224 · --no-linkage-name
225
226 In the resulting report, do not display the linkage names of the
227 added, removed, or changed functions or variables.
228
229 · --no-show-locs
230 Do not show information about where in the second shared library
231 the respective type was changed.
232
233 · --show-bytes
234
235 Show sizes and offsets in bytes, not bits. By default, sizes and
236 offsets are shown in bits.
237
238 · --show-bits
239
240 Show sizes and offsets in bits, not bytes. This option is acti‐
241 vated by default.
242
243 · --show-hex
244
245 Show sizes and offsets in hexadecimal base.
246
247 · --show-dec
248
249 Show sizes and offsets in decimal base. This option is activated
250 by default.
251
252 · --no-show-relative-offset-changes
253
254 Without this option, when the offset of a data member changes, the
255 change report not only mentions the older and newer offset, but it
256 also mentions by how many bits the data member changes. With this
257 option, the latter is not shown.
258
259 · --no-unreferenced-symbols
260
261 In the resulting report, do not display change information about
262 function and variable symbols that are not referenced by any debug
263 information. Note that for these symbols not referenced by any
264 debug information, the change information displayed is either
265 added or removed symbols.
266
267 · --no-default-suppression
268
269 Do not load the default suppression specification files.
270
271 · --suppressions | --suppr <path-to-suppressions>
272
273 Use a suppression specification file located at path-to-suppres‐
274 sions. Note that this option can appear multiple times on the
275 command line. In that case, all of the provided suppression spec‐
276 ification files are taken into account.
277
278 Please note that, by default, if this option is not provided, then
279 the default suppression specification files are loaded .
280
281 · --drop <regex>
282
283 When reading the first-shared-library and second-shared-library
284 ELF input files, drop the globally defined functions and variables
285 which name match the regular expression regex. As a result, no
286 change involving these functions or variables will be emitted in
287 the diff report.
288
289 · --drop-fn <regex>
290
291 When reading the first-shared-library and second-shared-library
292 ELF input files, drop the globally defined functions which name
293 match the regular expression regex. As a result, no change
294 involving these functions will be emitted in the diff report.
295
296 · --drop-var <regex>
297
298 When reading the first-shared-library and second-shared-library
299 ELF input files, drop the globally defined variables matching a
300 the regular expression regex.
301
302 · --keep <regex>
303
304 When reading the first-shared-library and second-shared-library
305 ELF input files, keep the globally defined functions and variables
306 which names match the regular expression regex. All other func‐
307 tions and variables are dropped on the floor and will thus not
308 appear in the resulting diff report.
309
310 · --keep-fn <regex>
311
312 When reading the first-shared-library and second-shared-library
313 ELF input files, keep the globally defined functions which name
314 match the regular expression regex. All other functions are
315 dropped on the floor and will thus not appear in the resulting
316 diff report.
317
318 · --keep-var <regex>
319
320 When reading the first-shared-library and second-shared-library
321 ELF input files, keep the globally defined which names match the
322 regular expression regex. All other variables are dropped on the
323 floor and will thus not appear in the resulting diff report.
324
325 · --harmless
326
327 In the diff report, display only the harmless changes. By
328 default, the harmless changes are filtered out of the diff report
329 keep the clutter to a minimum and have a greater chance to spot
330 real ABI issues.
331
332 · --no-harmful
333
334 In the diff report, do not display the harmful changes. By
335 default, only the harmful changes are displayed in diff report.
336
337 · --redundant
338
339 In the diff report, do display redundant changes. A redundant
340 change is a change that has been displayed elsewhere in the
341 report.
342
343 · --no-redundant
344
345 In the diff report, do NOT display redundant changes. A redundant
346 change is a change that has been displayed elsewhere in the
347 report. This option is switched on by default.
348
349 · --no-architecture
350
351 Do not take architecture in account when comparing ABIs.
352
353 · --no-corpus-path
354
355 Do not emit the path attribute for the ABI corpus.
356
357 · --fail-no-debug-info
358
359 If no debug info was found, then this option makes the program to
360 fail. Otherwise, without this option, the program will attempt to
361 compare properties of the binaries that are not related to debug
362 info, like pure ELF properties.
363
364 · --leaf-changes-only|-l only show leaf changes, so don’t show
365 impact analysis report.
366
367 The typical output of abidiff when comparing two binaries looks
368 like this
369
370 $ abidiff libtest-v0.so libtest-v1.so
371 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
372 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
373
374 1 function with some indirect sub-type change:
375
376 [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
377 parameter 1 of type 'C&' has sub-type changes:
378 in referenced type 'struct C' at test-v1.cc:7:1:
379 type size hasn't changed
380 1 data member change:
381 type of 'leaf* C::m0' changed:
382 in pointed to type 'struct leaf' at test-v1.cc:1:1:
383 type size changed from 32 to 64 bits
384 1 data member insertion:
385 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
386
387 $
388
389 So in that example the report emits information about how the data
390 member insertion change of “struct leaf” is reachable from func‐
391 tion “void fn(C&)”. In other words, the report not only shows the
392 data member change on “struct leaf”, but it also shows the impact
393 of that change on the function “void fn(C&)”.
394
395 In abidiff parlance, the change on “struct leaf” is called a leaf
396 change. So the --leaf-changes-only --impacted-interfaces options
397 show, well, only the leaf change. And it goes like this:
398
399 $ abidiff -l libtest-v0.so libtest-v1.so
400 'struct leaf' changed:
401 type size changed from 32 to 64 bits
402 1 data member insertion:
403 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
404
405 one impacted interface:
406 function void fn(C&)
407 $
408
409 Note how the report ends by showing the list of interfaces
410 impacted by the leaf change.
411
412 Now if you don’t want to see that list of impacted interfaces,
413 then you can just avoid using the --impacted-interface option.
414 You can learn about that option below, in any case.
415
416 · --impacted-interfaces
417
418 When showing leaf changes, this option instructs abidiff to show
419 the list of impacted interfaces. This option is thus to be used
420 in addition the --leaf-changes-only option, otherwise, it’s
421 ignored.
422
423 · --dump-diff-tree
424 After the diff report, emit a textual representation of the diff
425 nodes tree used by the comparison engine to represent the
426 changed functions and variables. That representation is emitted
427 to the error output for debugging purposes. Note that this diff
428 tree is relevant only to functions and variables that have some
429 sub-type changes. Added or removed functions and variables do
430 not have any diff nodes tree associated to them.
431
432 · --stats
433
434 Emit statistics about various internal things.
435
436 · --verbose
437
438 Emit verbose logs about the progress of miscellaneous internal
439 things.
440
442 The exit code of the abidiff command is either 0 if the ABI of the
443 binaries being compared are equal, or non-zero if they differ or if the
444 tool encountered an error.
445
446 In the later case, the exit code is a 8-bits-wide bit field in which
447 each bit has a specific meaning.
448
449 The first bit, of value 1, named ABIDIFF_ERROR means there was an
450 error.
451
452 The second bit, of value 2, named ABIDIFF_USAGE_ERROR means there was
453 an error in the way the user invoked the tool. It might be set, for
454 instance, if the user invoked the tool with an unknown command line
455 switch, with a wrong number or argument, etc. If this bit is set, then
456 the ABIDIFF_ERROR bit must be set as well.
457
458 The third bit, of value 4, named ABIDIFF_ABI_CHANGE means the ABI of
459 the binaries being compared are different.
460
461 The fourth bit, of value 8, named ABIDIFF_ABI_INCOMPATIBLE_CHANGE means
462 the ABI of the binaries compared are different in an incompatible way.
463 If this bit is set, then the ABIDIFF_ABI_CHANGE bit must be set as
464 well. If the ABIDIFF_ABI_CHANGE is set and the ABIDIFF_INCOMPATI‐
465 BLE_CHANGE is NOT set, then it means that the ABIs being compared might
466 or might not be compatible. In that case, a human being needs to
467 review the ABI changes to decide if they are compatible or not.
468
469 Note that, at the moment, there are only a few kinds of ABI changes
470 that would result in setting the flag ABIDIFF_ABI_INCOMPATIBLE_CHANGE.
471 Those ABI changes are either:
472
473 · the removal of the symbol of a function or variable that has been
474 defined and exported.
475
476 · the modification of the index of a member of a virtual function
477 table (for C++ programs and libraries).
478
479 With time, when more ABI change patterns are found to always constitute
480 incompatible ABI changes, we will adapt the code to recognize those
481 cases and set the ABIDIFF_ABI_INCOMPATIBLE_CHANGE accordingly. So, if
482 you find such patterns, please let us know.
483
484 The remaining bits are not used for the moment.
485
487 1. Detecting a change in a sub-type of a function:
488
489 $ cat -n test-v0.cc
490 1 // Compile this with:
491 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
492 3
493 4 struct S0
494 5 {
495 6 int m0;
496 7 };
497 8
498 9 void
499 10 foo(S0* /*parameter_name*/)
500 11 {
501 12 // do something with parameter_name.
502 13 }
503 $
504 $ cat -n test-v1.cc
505 1 // Compile this with:
506 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
507 3
508 4 struct type_base
509 5 {
510 6 int inserted;
511 7 };
512 8
513 9 struct S0 : public type_base
514 10 {
515 11 int m0;
516 12 };
517 13
518 14 void
519 15 foo(S0* /*parameter_name*/)
520 16 {
521 17 // do something with parameter_name.
522 18 }
523 $
524 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
525 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
526 $
527 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
528 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
529 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
530
531 1 function with some indirect sub-type change:
532
533 [C]'function void foo(S0*)' has some indirect sub-type changes:
534 parameter 0 of type 'S0*' has sub-type changes:
535 in pointed to type 'struct S0':
536 size changed from 32 to 64 bits
537 1 base class insertion:
538 struct type_base
539 1 data member change:
540 'int S0::m0' offset changed from 0 to 32
541 $
542
543 2. Detecting another change in a sub-type of a function:
544
545 $ cat -n test-v0.cc
546 1 // Compile this with:
547 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
548 3
549 4 struct S0
550 5 {
551 6 int m0;
552 7 };
553 8
554 9 void
555 10 foo(S0& /*parameter_name*/)
556 11 {
557 12 // do something with parameter_name.
558 13 }
559 $
560 $ cat -n test-v1.cc
561 1 // Compile this with:
562 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
563 3
564 4 struct S0
565 5 {
566 6 char inserted_member;
567 7 int m0;
568 8 };
569 9
570 10 void
571 11 foo(S0& /*parameter_name*/)
572 12 {
573 13 // do something with parameter_name.
574 14 }
575 $
576 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
577 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
578 $
579 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
580 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
581 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
582
583 1 function with some indirect sub-type change:
584
585 [C]'function void foo(S0&)' has some indirect sub-type changes:
586 parameter 0 of type 'S0&' has sub-type changes:
587 in referenced type 'struct S0':
588 size changed from 32 to 64 bits
589 1 data member insertion:
590 'char S0::inserted_member', at offset 0 (in bits)
591 1 data member change:
592 'int S0::m0' offset changed from 0 to 32
593
594
595 $
596
597 3. Detecting that functions got removed or added to a library:
598
599 $ cat -n test-v0.cc
600 1 // Compile this with:
601 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
602 3
603 4 struct S0
604 5 {
605 6 int m0;
606 7 };
607 8
608 9 void
609 10 foo(S0& /*parameter_name*/)
610 11 {
611 12 // do something with parameter_name.
612 13 }
613 $
614 $ cat -n test-v1.cc
615 1 // Compile this with:
616 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
617 3
618 4 struct S0
619 5 {
620 6 char inserted_member;
621 7 int m0;
622 8 };
623 9
624 10 void
625 11 bar(S0& /*parameter_name*/)
626 12 {
627 13 // do something with parameter_name.
628 14 }
629 $
630 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
631 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
632 $
633 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
634 Functions changes summary: 1 Removed, 0 Changed, 1 Added functions
635 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
636
637 1 Removed function:
638 'function void foo(S0&)' {_Z3fooR2S0}
639
640 1 Added function:
641 'function void bar(S0&)' {_Z3barR2S0}
642
643 $
644
646 Dodji Seketeli
647
649 2014-2020, Red Hat, Inc.
650
651
652
653
654 Feb 25, 2020 ABIDIFF(1)