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 between two input shared li‐
17 braries that includes changes about function and variable sub-types,
18 abidiff uses by default, debug information in DWARF format, if present,
19 otherwise it compares interfaces using debug information in CTF or BTF
20 formats, if present. Finally, if no debug info in these formats is
21 found, it only considers ELF symbols and report about their addition or
22 removal.
23
24 This tool uses the libabigail library to analyze the binary as well as
25 its associated debug information. Here is its general mode of opera‐
26 tion.
27
28 When instructed to do so, a binary and its associated debug information
29 is read and analyzed. To that effect, libabigail analyzes by default
30 the descriptions of the types reachable by the interfaces (functions
31 and variables) that are visible outside of their translation unit.
32 Once that analysis is done, an Application Binary Interface Corpus is
33 constructed by only considering the subset of types reachable from in‐
34 terfaces associated to ELF symbols that are defined and exported by the
35 binary. It’s that final ABI corpus which libabigail considers as rep‐
36 resenting the ABI of the analyzed binary.
37
38 Libabigail then has capabilities to generate textual representations of
39 ABI Corpora, compare them, analyze their changes and report about them.
40
42 abidiff [options] <first-shared-library> <second-shared-library>
43
45 abidiff loads two default suppression specifications files, merges
46 their content and use it to filter out ABI change reports that might be
47 considered as false positives to users.
48
49 • Default system-wide suppression specification file
50
51 It’s located by the optional environment variable LIBABIGAIL_DE‐
52 FAULT_SYSTEM_SUPPRESSION_FILE. If that environment variable is not
53 set, then abidiff tries to load the suppression file $libdir/libabi‐
54 gail/libabigail-default.abignore. If that file is not present, then
55 no default system-wide suppression specification file is loaded.
56
57 • Default user suppression specification file.
58
59 It’s located by the optional environment LIBABIGAIL_DEFAULT_USER_SUP‐
60 PRESSION_FILE. If that environment variable is not set, then abidiff
61 tries to load the suppression file $HOME/.abignore. If that file is
62 not present, then no default user suppression specification is
63 loaded.
64
66 • --help | -h
67
68 Display a short help about the command and exit.
69
70 • --debug-self-comparison
71
72 In this mode, error messages are emitted for types which fail type
73 canonicalization, in some circumstances, when comparing a binary
74 against itself.
75
76 When comparing a binary against itself, canonical types of the
77 second binary should be equal (as much as possible) to canonical
78 types of the first binary. When some discrepancies are detected
79 in this mode, an abort signal is emitted and execution is halted.
80 This option should be used while executing the tool in a debugger,
81 for troubleshooting purposes.
82
83 This is an optional debugging and sanity check option. To enable
84 it the libabigail package needs to be configured with the –en‐
85 able-debug-self-comparison configure option.
86
87 • --debug-tc
88
89 In this mode, the process of type canonicalization is put under
90 heavy scrutiny. Basically, during type canonicalization, each
91 type comparison is performed twice: once in a structural mode
92 (comparing every sub-type member-wise), and once using canonical
93 comparison. The two comparisons should yield the same result.
94 Otherwise, an abort signal is emitted and the process can be de‐
95 bugged to understand why the two kinds of comparison yield differ‐
96 ent results.
97
98 This is an optional debugging and sanity check option. To enable
99 it the libabigail package needs to be configured with the –en‐
100 able-debug-type-canonicalization configure option.
101
102 • --version | -v
103
104 Display the version of the program and exit.
105
106 • --debug-info-dir1 | --d1 <di-path1>
107
108 For cases where the debug information for first-shared-library is
109 split out into a separate file, tells abidiff where to find that
110 separate debug information file.
111
112 Note that di-path must point to the root directory under which the
113 debug information is arranged in a tree-like manner. Under Red
114 Hat based systems, that directory is usually <root>/usr/lib/debug.
115
116 This option can be provided several times with different root di‐
117 rectories. In that case, abidiff will potentially look into all
118 those root directories to find the split debug info for
119 first-shared-library.
120
121 Note also that this option is not mandatory for split debug infor‐
122 mation installed by your system’s package manager because then
123 abidiff knows where to find it.
124
125 • --debug-info-dir2 | --d2 <di-path2>
126
127 Like --debug-info-dir1, this options tells abidiff where to find
128 the split debug information for the second-shared-library file.
129
130 This option can be provided several times with different root di‐
131 rectories. In that case, abidiff will potentially look into all
132 those root directories to find the split debug info for sec‐
133 ond-shared-library.
134
135 • --headers-dir1 | --hd1 <headers-directory-path-1>
136
137 Specifies where to find the public headers of the first shared li‐
138 brary (or binary in general) that the tool has to consider. The
139 tool will thus filter out ABI changes on types that are not de‐
140 fined in public headers.
141
142 Note that several public header directories can be specified for
143 the first shared library. In that case the --headers-dir1 option
144 should be present several times on the command line, like in the
145 following example:
146
147 $ abidiff --headers-dir1 /some/path \
148 --headers-dir1 /some/other/path \
149 binary-version-1 binary-version-2
150
151 • --header-file1 | --hf1 <header-file-path-1>
152
153 Specifies where to find one public header of the first shared li‐
154 brary that the tool has to consider. The tool will thus filter
155 out ABI changes on types that are not defined in public headers.
156
157 • --headers-dir2 | --hd2 <headers-directory-path-2>
158
159 Specifies where to find the public headers of the second shared
160 library that the tool has to consider. The tool will thus filter
161 out ABI changes on types that are not defined in public headers.
162
163 Note that several public header directories can be specified for
164 the second shared library. In that case the --headers-dir2 option
165 should be present several times like in the following example:
166
167 $ abidiff --headers-dir2 /some/path \
168 --headers-dir2 /some/other/path \
169 binary-version-1 binary-version-2
170
171 • --header-file2 | --hf2 <header-file-path-2>
172
173 Specifies where to find one public header of the second shared li‐
174 brary that the tool has to consider. The tool will thus filter
175 out ABI changes on types that are not defined in public headers.
176
177 • --add-binaries1 <bin1,bin2,bin3,..>
178
179 For each of the comma-separated binaries given in argument to this
180 option, if the binary is found in the directory specified by the
181 --added-binaries-dir1 option, then abidiff loads the ABI corpus of
182 the binary and adds it to a set of corpora (called an ABI Corpus
183 Group) that includes the first argument of abidiff.
184
185 That ABI corpus group is then compared against the second corpus
186 group given in argument to abidiff.
187
188 • --add-binaries2 <bin1,bin2,bin3,..>
189
190 For each of the comma-separated binaries given in argument to this
191 option, if the binary is found in the directory specified by the
192 --added-binaries-dir2 option, then abidiff loads the ABI corpus of
193 the binary and adds it to a set of corpora(called an ABI Corpus
194 Group) that includes the second argument of abidiff.
195
196 That ABI corpus group is then compared against the first corpus
197 group given in argument to abidiff.
198
199 • --follow-dependencies | --fdeps
200
201 For each dependency of the first argument of abidiff, if it’s
202 found in the directory specified by the --added-binaries-dir1 op‐
203 tion, then construct an ABI corpus out of the dependency, add it
204 to a set of corpora (called an ABI Corpus Group) that includes the
205 first argument of abidiff.
206
207 Similarly, for each dependency of the second argument of abidiff,
208 if it’s found in the directory specified by the --added-bina‐
209 ries-dir2 option, then construct an ABI corpus out of the depen‐
210 dency, add it to an ABI corpus group that includes the second ar‐
211 gument of abidiff.
212
213 These two ABI corpus groups are then compared against each other.
214
215 Said otherwise, this makes abidiff compare the set of its first
216 input and its dependencies against the set of its second input and
217 its dependencies.
218
219 • list-dependencies | --ldeps
220
221 This option lists all the dependencies of the input arguments of
222 abidiff that are found in the directories specified by the options
223 --added-binaries-dir1 and --added-binaries-dir2
224
225 • --added-binaries-dir1 | --abd1 <added-binaries-directory-1>
226
227 This option is to be used in conjunction with the --add-binaries1,
228 --follow-dependencies and --list-dependencies options. Binaries
229 referred to by these options, if found in the directory added-bi‐
230 naries-directory-1, are loaded as ABI corpus and are added to the
231 first ABI corpus group that is to be used in the comparison.
232
233 • --added-binaries-dir2 | --abd2 <added-binaries-directory-2>
234
235 This option is to be used in conjunction with the --add-binaries2,
236 --follow-dependencies and --list-dependencies options. Binaries
237 referred to by these options, if found in the directory added-bi‐
238 naries-directory-2, are loaded as ABI corpus and are added to the
239 second ABI corpus group to be used in the comparison.
240
241 • --no-linux-kernel-mode
242
243 Without this option, if abidiff detects that the binaries it is
244 looking at are Linux Kernel binaries (either vmlinux or modules)
245 then it only considers functions and variables which ELF symbols
246 are listed in the __ksymtab and __ksymtab_gpl sections.
247
248 With this option, abidiff considers the binary as a non-special
249 ELF binary. It thus considers functions and variables which are
250 defined and exported in the ELF sense.
251
252 • --kmi-whitelist | -kaw <path-to-whitelist>
253
254 When analyzing a Linux kernel binary, this option points to the
255 white list of names of ELF symbols of functions and variables
256 which ABI must be considered. That white list is called a “Kernel
257 Module Interface white list”. This is because for the Kernel, we
258 don’t talk about ABI; we rather talk about the interface between
259 the Kernel and its module. Hence the term KMI rather than ABI.
260
261 Any other function or variable which ELF symbol are not present in
262 that white list will not be considered by this tool.
263
264 If this option is not provided – thus if no white list is provided
265 – then the entire KMI, that is, the set of all publicly defined
266 and exported functions and global variables by the Linux Kernel
267 binaries, is considered.
268
269 • --drop-private-types
270
271 This option is to be used with the --headers-dir1, header-file1,
272 header-file2 and --headers-dir2 options. With this option, types
273 that are NOT defined in the headers are entirely dropped from the
274 internal representation build by Libabigail to represent the ABI.
275 They thus don’t have to be filtered out from the final ABI change
276 report because they are not even present in Libabigail’s represen‐
277 tation.
278
279 Without this option however, those private types are kept in the
280 internal representation and later filtered out from the report.
281
282 This options thus potentially makes Libabigail consume less mem‐
283 ory. It’s meant to be mainly used to optimize the memory consump‐
284 tion of the tool on binaries with a lot of publicly defined and
285 exported types.
286
287 • --exported-interfaces-only
288
289 By default, when looking at the debug information accompanying a
290 binary, this tool analyzes the descriptions of the types reachable
291 by the interfaces (functions and variables) that are visible out‐
292 side of their translation unit. Once that analysis is done, an
293 ABI corpus is constructed by only considering the subset of types
294 reachable from interfaces associated to ELF symbols that are de‐
295 fined and exported by the binary. It’s those final ABI Corpora
296 that are compared by this tool.
297
298 The problem with that approach however is that analyzing all the
299 interfaces that are visible from outside their translation unit
300 can amount to a lot of data, especially when those binaries are
301 applications, as opposed to shared libraries. One example of such
302 applications is the Linux Kernel. Analyzing massive ABI corpora
303 like these can be extremely slow.
304
305 To mitigate that performance issue, this option allows libabigail
306 to only analyze types that are reachable from interfaces associ‐
307 ated with defined and exported ELF symbols.
308
309 Note that this option is turned on by default when analyzing the
310 Linux Kernel. Otherwise, it’s turned off by default.
311
312 • --allow-non-exported-interfaces
313
314 When looking at the debug information accompanying a binary, this
315 tool analyzes the descriptions of the types reachable by the in‐
316 terfaces (functions and variables) that are visible outside of
317 their translation unit. Once that analysis is done, an ABI corpus
318 is constructed by only considering the subset of types reachable
319 from interfaces associated to ELF symbols that are defined and ex‐
320 ported by the binary. It’s those final ABI Corpora that are com‐
321 pared by this tool.
322
323 The problem with that approach however is that analyzing all the
324 interfaces that are visible from outside their translation unit
325 can amount to a lot of data, especially when those binaries are
326 applications, as opposed to shared libraries. One example of such
327 applications is the Linux Kernel. Analyzing massive ABI Corpora
328 like these can be extremely slow.
329
330 In the presence of an “average sized” binary however one can af‐
331 ford having libabigail analyze all interfaces that are visible
332 outside of their translation unit, using this option.
333
334 Note that this option is turned on by default, unless we are in
335 the presence of the Linux Kernel.
336
337 • --stat
338
339 Rather than displaying the detailed ABI differences between
340 first-shared-library and second-shared-library, just display some
341 summary statistics about these differences.
342
343 • --symtabs
344
345 Only display the symbol tables of the first-shared-library and
346 second-shared-library.
347
348 • --deleted-fns
349
350 In the resulting report about the differences between
351 first-shared-library and second-shared-library, only display the
352 globally defined functions that got deleted from first-shared-li‐
353 brary.
354
355 • --changed-fns
356
357 In the resulting report about the differences between
358 first-shared-library and second-shared-library, only display the
359 changes in sub-types of the global functions defined in
360 first-shared-library.
361
362 • --added-fns
363
364 In the resulting report about the differences between
365 first-shared-library and second-shared-library, only display the
366 globally defined functions that were added to second-shared-li‐
367 brary.
368
369 • --deleted-vars
370
371 In the resulting report about the differences between
372 first-shared-library and second-shared-library, only display the
373 globally defined variables that were deleted from first-shared-li‐
374 brary.
375
376 • --changed-vars
377
378 In the resulting report about the differences between
379 first-shared-library and second-shared-library, only display the
380 changes in the sub-types of the global variables defined in
381 first-shared-library
382
383 • --added-vars
384
385 In the resulting report about the differences between
386 first-shared-library and second-shared-library, only display the
387 global variables that were added (defined) to second-shared-li‐
388 brary.
389
390 • --non-reachable-types|-t
391
392 Analyze and emit change reports for all the types of the binary,
393 including those that are not reachable from global functions and
394 variables.
395
396 This option might incur some serious performance degradation as
397 the number of types analyzed can be huge. However, if paired with
398 the --headers-dir{1,2} and/or header-file{1,2} options, the addi‐
399 tional non-reachable types analyzed are restricted to those de‐
400 fined in public headers files, thus hopefully making the perfor‐
401 mance hit acceptable.
402
403 Also, using this option alongside suppression specifications (by
404 also using the --suppressions option) might help keep the number
405 of analyzed types (and the potential performance degradation) in
406 control.
407
408 Note that without this option, only types that are reachable from
409 global functions and variables are analyzed, so the tool detects
410 and reports changes on these reachable types only.
411
412 • --no-added-syms
413
414 In the resulting report about the differences between
415 first-shared-library and second-shared-library, do not display
416 added functions or variables. Do not display added functions or
417 variables ELF symbols either. All other kinds of changes are dis‐
418 played unless they are explicitely forbidden by other options on
419 the command line.
420
421 • --no-linkage-name
422
423 In the resulting report, do not display the linkage names of the
424 added, removed, or changed functions or variables.
425
426 • --no-show-locs
427 Do not show information about where in the second shared library
428 the respective type was changed.
429
430 • --show-bytes
431
432 Show sizes and offsets in bytes, not bits. By default, sizes and
433 offsets are shown in bits.
434
435 • --show-bits
436
437 Show sizes and offsets in bits, not bytes. This option is acti‐
438 vated by default.
439
440 • --show-hex
441
442 Show sizes and offsets in hexadecimal base.
443
444 • --show-dec
445
446 Show sizes and offsets in decimal base. This option is activated
447 by default.
448
449 • --ignore-soname
450
451 Ignore differences in the SONAME when doing a comparison
452
453 • --no-show-relative-offset-changes
454
455 Without this option, when the offset of a data member changes, the
456 change report not only mentions the older and newer offset, but it
457 also mentions by how many bits the data member changes. With this
458 option, the latter is not shown.
459
460 • --no-unreferenced-symbols
461
462 In the resulting report, do not display change information about
463 function and variable symbols that are not referenced by any debug
464 information. Note that for these symbols not referenced by any
465 debug information, the change information displayed is either
466 added or removed symbols.
467
468 • --no-default-suppression
469
470 Do not load the default suppression specification files.
471
472 • --suppressions | --suppr <path-to-suppressions>
473
474 Use a suppression specification file located at path-to-suppres‐
475 sions. Note that this option can appear multiple times on the
476 command line. In that case, all of the provided suppression spec‐
477 ification files are taken into account.
478
479 Please note that, by default, if this option is not provided, then
480 the default suppression specification files are loaded .
481
482 • --drop <regex>
483
484 When reading the first-shared-library and second-shared-library
485 ELF input files, drop the globally defined functions and variables
486 which name match the regular expression regex. As a result, no
487 change involving these functions or variables will be emitted in
488 the diff report.
489
490 • --drop-fn <regex>
491
492 When reading the first-shared-library and second-shared-library
493 ELF input files, drop the globally defined functions which name
494 match the regular expression regex. As a result, no change in‐
495 volving these functions will be emitted in the diff report.
496
497 • --drop-var <regex>
498
499 When reading the first-shared-library and second-shared-library
500 ELF input files, drop the globally defined variables matching a
501 the regular expression regex.
502
503 • --keep <regex>
504
505 When reading the first-shared-library and second-shared-library
506 ELF input files, keep the globally defined functions and variables
507 which names match the regular expression regex. All other func‐
508 tions and variables are dropped on the floor and will thus not ap‐
509 pear in the resulting diff report.
510
511 • --keep-fn <regex>
512
513 When reading the first-shared-library and second-shared-library
514 ELF input files, keep the globally defined functions which name
515 match the regular expression regex. All other functions are
516 dropped on the floor and will thus not appear in the resulting
517 diff report.
518
519 • --keep-var <regex>
520
521 When reading the first-shared-library and second-shared-library
522 ELF input files, keep the globally defined which names match the
523 regular expression regex. All other variables are dropped on the
524 floor and will thus not appear in the resulting diff report.
525
526 • --harmless
527
528 In the diff report, display only the harmless changes. By de‐
529 fault, the harmless changes are filtered out of the diff report
530 keep the clutter to a minimum and have a greater chance to spot
531 real ABI issues.
532
533 • --no-harmful
534
535 In the diff report, do not display the harmful changes. By de‐
536 fault, only the harmful changes are displayed in diff report.
537
538 • --redundant
539
540 In the diff report, do display redundant changes. A redundant
541 change is a change that has been displayed elsewhere in the re‐
542 port.
543
544 • --no-redundant
545
546 In the diff report, do NOT display redundant changes. A redundant
547 change is a change that has been displayed elsewhere in the re‐
548 port. This option is switched on by default.
549
550 • --no-architecture
551
552 Do not take architecture in account when comparing ABIs.
553
554 • --no-corpus-path
555
556 Do not emit the path attribute for the ABI corpus.
557
558 • --fail-no-debug-info
559
560 If no debug info was found, then this option makes the program to
561 fail. Otherwise, without this option, the program will attempt to
562 compare properties of the binaries that are not related to debug
563 info, like pure ELF properties.
564
565 • --leaf-changes-only|-l only show leaf changes, so don’t show im‐
566 pact analysis report. This option implies --redundant.
567
568 The typical output of abidiff when comparing two binaries looks
569 like this
570
571 $ abidiff libtest-v0.so libtest-v1.so
572 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
573 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
574
575 1 function with some indirect sub-type change:
576
577 [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
578 parameter 1 of type 'C&' has sub-type changes:
579 in referenced type 'struct C' at test-v1.cc:7:1:
580 type size hasn't changed
581 1 data member change:
582 type of 'leaf* C::m0' changed:
583 in pointed to type 'struct leaf' at test-v1.cc:1:1:
584 type size changed from 32 to 64 bits
585 1 data member insertion:
586 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
587
588 $
589
590 So in that example the report emits information about how the data
591 member insertion change of “struct leaf” is reachable from func‐
592 tion “void fn(C&)”. In other words, the report not only shows the
593 data member change on “struct leaf”, but it also shows the impact
594 of that change on the function “void fn(C&)”.
595
596 In abidiff parlance, the change on “struct leaf” is called a leaf
597 change. So the --leaf-changes-only --impacted-interfaces options
598 show, well, only the leaf change. And it goes like this:
599
600 $ abidiff -l libtest-v0.so libtest-v1.so
601 'struct leaf' changed:
602 type size changed from 32 to 64 bits
603 1 data member insertion:
604 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
605
606 one impacted interface:
607 function void fn(C&)
608 $
609
610 Note how the report ends by showing the list of interfaces im‐
611 pacted by the leaf change.
612
613 Now if you don’t want to see that list of impacted interfaces,
614 then you can just avoid using the --impacted-interface option.
615 You can learn about that option below, in any case.
616
617 • --impacted-interfaces
618
619 When showing leaf changes, this option instructs abidiff to show
620 the list of impacted interfaces. This option is thus to be used
621 in addition the --leaf-changes-only option, otherwise, it’s ig‐
622 nored.
623
624 • --dump-diff-tree
625 After the diff report, emit a textual representation of the diff
626 nodes tree used by the comparison engine to represent the
627 changed functions and variables. That representation is emitted
628 to the error output for debugging purposes. Note that this diff
629 tree is relevant only to functions and variables that have some
630 sub-type changes. Added or removed functions and variables do
631 not have any diff nodes tree associated to them.
632
633 • --no-assume-odr-for-cplusplus
634
635 When analysing a binary originating from C++ code using DWARF de‐
636 bug information, libabigail assumes the One Definition Rule to
637 speed-up the analysis. In that case, when several types have the
638 same name in the binary, they are assumed to all be equal.
639
640 This option disables that assumption and instructs libabigail to
641 actually actually compare the types to determine if they are
642 equal.
643
644 • --no-leverage-dwarf-factorization
645
646 When analysing a binary which DWARF debug information was pro‐
647 cessed with the DWZ tool, the type information is supposed to be
648 already factorized. That context is used by libabigail to perform
649 some speed optimizations.
650
651 This option disables those optimizations.
652
653 • --no-change-categorization | -x
654
655 This option disables the categorization of changes into harmless
656 and harmful changes. Note that this categorization is a pre-req‐
657 uisite for the filtering of changes so this option disables that
658 filtering. The goal of this option is to speed-up the execution
659 of the program for cases where the graph of changes is huge and
660 where the user is just interested in looking at, for instance,
661 leaf node changes without caring about their possible impact on
662 interfaces. In that case, this option would be used along with
663 the --leaf-changes-only one.
664
665 • --ctf
666
667 When comparing binaries, extract ABI information from CTF debug
668 information, if present.
669
670 • --btf
671
672 When comparing binaries, extract ABI information from BTF debug
673 information, if present.
674
675 • --stats
676
677 Emit statistics about various internal things.
678
679 • --verbose
680
681 Emit verbose logs about the progress of miscellaneous internal
682 things.
683
685 The exit code of the abidiff command is either 0 if the ABI of the bi‐
686 naries being compared are equal, or non-zero if they differ or if the
687 tool encountered an error.
688
689 In the later case, the exit code is a 8-bits-wide bit field in which
690 each bit has a specific meaning.
691
692 The first bit, of value 1, named ABIDIFF_ERROR means there was an er‐
693 ror.
694
695 The second bit, of value 2, named ABIDIFF_USAGE_ERROR means there was
696 an error in the way the user invoked the tool. It might be set, for
697 instance, if the user invoked the tool with an unknown command line
698 switch, with a wrong number or argument, etc. If this bit is set, then
699 the ABIDIFF_ERROR bit must be set as well.
700
701 The third bit, of value 4, named ABIDIFF_ABI_CHANGE means the ABI of
702 the binaries being compared are different.
703
704 The fourth bit, of value 8, named ABIDIFF_ABI_INCOMPATIBLE_CHANGE means
705 the ABI of the binaries compared are different in an incompatible way.
706 If this bit is set, then the ABIDIFF_ABI_CHANGE bit must be set as
707 well. If the ABIDIFF_ABI_CHANGE is set and the ABIDIFF_INCOMPATI‐
708 BLE_CHANGE is NOT set, then it means that the ABIs being compared might
709 or might not be compatible. In that case, a human being needs to re‐
710 view the ABI changes to decide if they are compatible or not.
711
712 Note that, at the moment, there are only a few kinds of ABI changes
713 that would result in setting the flag ABIDIFF_ABI_INCOMPATIBLE_CHANGE.
714 Those ABI changes are either:
715
716 • the removal of the symbol of a function or variable that has been
717 defined and exported.
718
719 • the modification of the index of a member of a virtual function
720 table (for C++ programs and libraries).
721
722 With time, when more ABI change patterns are found to always constitute
723 incompatible ABI changes, we will adapt the code to recognize those
724 cases and set the ABIDIFF_ABI_INCOMPATIBLE_CHANGE accordingly. So, if
725 you find such patterns, please let us know.
726
727 The remaining bits are not used for the moment.
728
730 1. Detecting a change in a sub-type of a function:
731
732 $ cat -n test-v0.cc
733 1 // Compile this with:
734 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
735 3
736 4 struct S0
737 5 {
738 6 int m0;
739 7 };
740 8
741 9 void
742 10 foo(S0* /*parameter_name*/)
743 11 {
744 12 // do something with parameter_name.
745 13 }
746 $
747 $ cat -n test-v1.cc
748 1 // Compile this with:
749 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
750 3
751 4 struct type_base
752 5 {
753 6 int inserted;
754 7 };
755 8
756 9 struct S0 : public type_base
757 10 {
758 11 int m0;
759 12 };
760 13
761 14 void
762 15 foo(S0* /*parameter_name*/)
763 16 {
764 17 // do something with parameter_name.
765 18 }
766 $
767 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
768 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
769 $
770 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
771 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
772 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
773
774 1 function with some indirect sub-type change:
775
776 [C]'function void foo(S0*)' has some indirect sub-type changes:
777 parameter 0 of type 'S0*' has sub-type changes:
778 in pointed to type 'struct S0':
779 size changed from 32 to 64 bits
780 1 base class insertion:
781 struct type_base
782 1 data member change:
783 'int S0::m0' offset changed from 0 to 32
784 $
785
786 2. Detecting another change in a sub-type of a function:
787
788 $ cat -n test-v0.cc
789 1 // Compile this with:
790 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
791 3
792 4 struct S0
793 5 {
794 6 int m0;
795 7 };
796 8
797 9 void
798 10 foo(S0& /*parameter_name*/)
799 11 {
800 12 // do something with parameter_name.
801 13 }
802 $
803 $ cat -n test-v1.cc
804 1 // Compile this with:
805 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
806 3
807 4 struct S0
808 5 {
809 6 char inserted_member;
810 7 int m0;
811 8 };
812 9
813 10 void
814 11 foo(S0& /*parameter_name*/)
815 12 {
816 13 // do something with parameter_name.
817 14 }
818 $
819 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
820 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
821 $
822 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
823 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
824 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
825
826 1 function with some indirect sub-type change:
827
828 [C]'function void foo(S0&)' has some indirect sub-type changes:
829 parameter 0 of type 'S0&' has sub-type changes:
830 in referenced type 'struct S0':
831 size changed from 32 to 64 bits
832 1 data member insertion:
833 'char S0::inserted_member', at offset 0 (in bits)
834 1 data member change:
835 'int S0::m0' offset changed from 0 to 32
836
837
838 $
839
840 3. Detecting that functions got removed or added to a library:
841
842 $ cat -n test-v0.cc
843 1 // Compile this with:
844 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
845 3
846 4 struct S0
847 5 {
848 6 int m0;
849 7 };
850 8
851 9 void
852 10 foo(S0& /*parameter_name*/)
853 11 {
854 12 // do something with parameter_name.
855 13 }
856 $
857 $ cat -n test-v1.cc
858 1 // Compile this with:
859 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
860 3
861 4 struct S0
862 5 {
863 6 char inserted_member;
864 7 int m0;
865 8 };
866 9
867 10 void
868 11 bar(S0& /*parameter_name*/)
869 12 {
870 13 // do something with parameter_name.
871 14 }
872 $
873 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
874 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
875 $
876 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
877 Functions changes summary: 1 Removed, 0 Changed, 1 Added functions
878 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
879
880 1 Removed function:
881 'function void foo(S0&)' {_Z3fooR2S0}
882
883 1 Added function:
884 'function void bar(S0&)' {_Z3barR2S0}
885
886 $
887
888 4. Comparing two sets of binaries that are passed on the command
889 line:
890
891 $ abidiff --add-binaries1=file2-v1 \
892 --add-binaries2=file2-v2,file2-v1 \
893 --added-binaries-dir1 dir1 \
894 --added-binaries-dir2 dir2 \
895 file1-v1 file1-v2
896
897 Note that the files file2-v1, and file2-v2 are to be found in
898 dir1 and dir2 or in the current directory.
899
900 5. Compare two libraries and their dependencies:
901
902 $ abidiff --follow-dependencies \
903 --added-binaries-dir1 /some/where \
904 --added-binaries-dir2 /some/where/else \
905 foo bar
906
907 This compares the set of binaries comprised by foo and its depen‐
908 dencies against the set of binaries comprised by bar and its de‐
909 pendencies.
910
912 Dodji Seketeli
913
915 2014-2023, Red Hat, Inc.
916
917
918
919
920 Nov 20, 2023 ABIDIFF(1)