1LIBABIGAIL(7) Libabigail LIBABIGAIL(7)
2
3
4
6 libabigail - Library to analyze and compare ELF ABIs
7
9 ABIGAIL stands for the Application Binary Interface Generic Analysis
10 and Instrumentation Library.
11
12 It’s a framework which aims at helping developers and software distrib‐
13 utors to spot some ABI-related issues like interface incompatibility in
14 ELF shared libraries by performing a static analysis of the ELF bina‐
15 ries at hand.
16
17 The type of interface incompatibilities that Abigail focuses on is
18 related to changes on the exported ELF functions and variables symbols,
19 as well as layout and size changes of data types of the functions and
20 variables exported by shared libraries.
21
22 In other words, if the return type of a function exported by a shared
23 library changes in an incompatible way from one version of a given
24 shared library to another, we want Abigail to help people catch that.
25
26 In more concrete terms, the Abigail framwork provides a shared library
27 named libabigail which exposes an API to parse a shared library in ELF
28 format (accompanied with its associated debug information in DWARF for‐
29 mat) build an internal representation of all the functions and vari‐
30 ables it exports, along with their types. Libabigail also builds an
31 internal representation of the ELF symbols of these functions and vari‐
32 ables. That information about these exported functions and variables
33 is roughly what we consider as being the ABI of the shared library, at
34 least, in the scope of Libabigail.
35
36 Aside of this internal representation, libabigail provides facilities
37 to perform deep comparisons of two ABIs. That is, it can compare the
38 types of two sets of functions or variables and represents the result
39 in a way that allows it to emit textual reports about the differences.
40
41 This allows us to write tools like abidiff that can compare the ABI of
42 two shared libraries and represent the result in a meaningful enough
43 way to help us spot ABI incompatibilities. There are several other
44 tools that are built using the Abigail framwork.
45
47 Overview
48 The upstream code repository of Libabigail contains several tools writ‐
49 ten using the library. They are maintained and released as part of the
50 project. All tools come with a bash-completion script.
51
52 Tools manuals
53 abidiff
54 abidiff compares the Application Binary Interfaces (ABI) of two shared
55 libraries in ELF format. It emits a meaningful report describing the
56 differences between the two ABIs.
57
58 This tool can also compare the textual representations of the ABI of
59 two ELF binaries (as emitted by abidw) or an ELF binary against a tex‐
60 tual representation of another ELF binary.
61
62 For a comprehensive ABI change report that includes changes about func‐
63 tion and variable sub-types, the two input shared libraries must be
64 accompanied with their debug information in DWARF format. Otherwise,
65 only ELF symbols that were added or removed are reported.
66
67 Invocation
68 abidiff [options] <first-shared-library> <second-shared-library>
69
70 Environment
71 abidiff loads two default suppression specifications files, merges
72 their content and use it to filter out ABI change reports that might be
73 considered as false positives to users.
74
75 · Default system-wide suppression specification file
76
77 It’s located by the optional environment variable LIBABI‐
78 GAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE. If that environment variable
79 is not set, then abidiff tries to load the suppression file $lib‐
80 dir/libabigail/libabigail-default.abignore. If that file is not
81 present, then no default system-wide suppression specification file
82 is loaded.
83
84 · Default user suppression specification file.
85
86 It’s located by the optional environment LIBABIGAIL_DEFAULT_USER_SUP‐
87 PRESSION_FILE. If that environment variable is not set, then abidiff
88 tries to load the suppression file $HOME/.abignore. If that file is
89 not present, then no default user suppression specification is
90 loaded.
91
92 Options
93 · --help | -h
94
95 Display a short help about the command and exit.
96
97 · --version | -v
98
99 Display the version of the program and exit.
100
101 · --debug-info-dir1 | --d1 <di-path1>
102
103 For cases where the debug information for first-shared-library is
104 split out into a separate file, tells abidiff where to find that
105 separate debug information file.
106
107 Note that di-path must point to the root directory under which the
108 debug information is arranged in a tree-like manner. Under Red
109 Hat based systems, that directory is usually <root>/usr/lib/debug.
110
111 This option can be provided several times with different root
112 directories. In that case, abidiff will potentially look into all
113 those root directories to find the split debug info for
114 first-shared-library.
115
116 Note also that this option is not mandatory for split debug infor‐
117 mation installed by your system’s package manager because then
118 abidiff knows where to find it.
119
120 · --debug-info-dir2 | --d2 <di-path2>
121
122 Like --debug-info-dir1, this options tells abidiff where to find
123 the split debug information for the second-shared-library file.
124
125 This option can be provided several times with different root
126 directories. In that case, abidiff will potentially look into all
127 those root directories to find the split debug info for sec‐
128 ond-shared-library.
129
130 · --headers-dir1 | --hd1 <headers-directory-path-1>
131
132 Specifies where to find the public headers of the first shared
133 library that the tool has to consider. The tool will thus filter
134 out ABI changes on types that are not defined in public headers.
135
136 · --headers-dir2 | --hd2 <headers-directory-path-1>
137
138 Specifies where to find the public headers of the second shared
139 library that the tool has to consider. The tool will thus filter
140 out ABI changes on types that are not defined in public headers.
141
142 · --no-linux-kernel-mode
143
144 Without this option, if abidiff detects that the binaries it is
145 looking at are Linux Kernel binaries (either vmlinux or modules)
146 then it only considers functions and variables which ELF symbols
147 are listed in the __ksymtab and __ksymtab_gpl sections.
148
149 With this option, abidiff considers the binary as a non-special
150 ELF binary. It thus considers functions and variables which are
151 defined and exported in the ELF sense.
152
153 · --kmi-whitelist | -kaw <path-to-whitelist>
154
155 When analyzing a Linux kernel binary, this option points to the
156 white list of names of ELF symbols of functions and variables
157 which ABI must be considered. That white list is called a “Kernel
158 Module Interface white list”. This is because for the Kernel, we
159 don’t talk about ABI; we rather talk about the interface between
160 the Kernel and its module. Hence the term KMI rather than ABI.
161
162 Any other function or variable which ELF symbol are not present in
163 that white list will not be considered by this tool.
164
165 If this option is not provided – thus if no white list is provided
166 – then the entire KMI, that is, the set of all publicly defined
167 and exported functions and global variables by the Linux Kernel
168 binaries, is considered.
169
170 · --drop-private-types
171
172 This option is to be used with the --headers-dir1 and --head‐
173 ers-dir2 options. With this option, types that are NOT defined in
174 the headers are entirely dropped from the internal representation
175 build by Libabigail to represent the ABI. They thus don’t have to
176 be filtered out from the final ABI change report because they are
177 not even present in Libabigail’s representation.
178
179 Without this option however, those private types are kept in the
180 internal representation and later filtered out from the report.
181
182 This options thus potentially makes Libabigail consume less mem‐
183 ory. It’s meant to be mainly used to optimize the memory consump‐
184 tion of the tool on binaries with a lot of publicly defined and
185 exported types.
186
187 · --stat
188
189 Rather than displaying the detailed ABI differences between
190 first-shared-library and second-shared-library, just display some
191 summary statistics about these differences.
192
193 · --symtabs
194
195 Only display the symbol tables of the first-shared-library and
196 second-shared-library.
197
198 · --deleted-fns
199
200 In the resulting report about the differences between
201 first-shared-library and second-shared-library, only display the
202 globally defined functions that got deleted from
203 first-shared-library.
204
205 · --changed-fns
206
207 In the resulting report about the differences between
208 first-shared-library and second-shared-library, only display the
209 changes in sub-types of the global functions defined in
210 first-shared-library.
211
212 · --added-fns
213
214 In the resulting report about the differences between
215 first-shared-library and second-shared-library, only display the
216 globally defined functions that were added to sec‐
217 ond-shared-library.
218
219 · --deleted-vars
220
221 In the resulting report about the differences between
222 first-shared-library and second-shared-library, only display the
223 globally defined variables that were deleted from
224 first-shared-library.
225
226 · --changed-vars
227
228 In the resulting report about the differences between
229 first-shared-library and second-shared-library, only display the
230 changes in the sub-types of the global variables defined in
231 first-shared-library
232
233 · --added-vars
234
235 In the resulting report about the differences between
236 first-shared-library and second-shared-library, only display the
237 global variables that were added (defined) to sec‐
238 ond-shared-library.
239
240 · --non-reachable-types|-t
241
242 Analyze and emit change reports for all the types of the binary,
243 including those that are not reachable from global functions and
244 variables.
245
246 This option might incur some serious performance degradation as
247 the number of types analyzed can be huge. However, if paired with
248 the --headers-dir{1,2} options, the additional non-reachable types
249 analyzed are restricted to those defined in public headers files,
250 thus hopefully making the performance hit acceptable.
251
252 Also, using this option alongside suppression specifications (by
253 also using the --suppressions option) might help keep the number
254 of analyzed types (and the potential performance degradation) in
255 control.
256
257 Note that without this option, only types that are reachable from
258 global functions and variables are analyzed, so the tool detects
259 and reports changes on these reachable types only.
260
261 · --no-added-syms
262
263 In the resulting report about the differences between
264 first-shared-library and second-shared-library, do not display
265 added functions or variables. Do not display added functions or
266 variables ELF symbols either. All other kinds of changes are dis‐
267 played unless they are explicitely forbidden by other options on
268 the command line.
269
270 · --no-linkage-name
271
272 In the resulting report, do not display the linkage names of the
273 added, removed, or changed functions or variables.
274
275 · --no-show-locs
276 Do not show information about where in the second shared library
277 the respective type was changed.
278
279 · --show-bytes
280
281 Show sizes and offsets in bytes, not bits. By default, sizes and
282 offsets are shown in bits.
283
284 · --show-bits
285
286 Show sizes and offsets in bits, not bytes. This option is acti‐
287 vated by default.
288
289 · --show-hex
290
291 Show sizes and offsets in hexadecimal base.
292
293 · --show-dec
294
295 Show sizes and offsets in decimal base. This option is activated
296 by default.
297
298 · --no-show-relative-offset-changes
299
300 Without this option, when the offset of a data member changes, the
301 change report not only mentions the older and newer offset, but it
302 also mentions by how many bits the data member changes. With this
303 option, the latter is not shown.
304
305 · --no-unreferenced-symbols
306
307 In the resulting report, do not display change information about
308 function and variable symbols that are not referenced by any debug
309 information. Note that for these symbols not referenced by any
310 debug information, the change information displayed is either
311 added or removed symbols.
312
313 · --no-default-suppression
314
315 Do not load the default suppression specification files.
316
317 · --suppressions | --suppr <path-to-suppressions>
318
319 Use a suppression specification file located at path-to-suppres‐
320 sions. Note that this option can appear multiple times on the
321 command line. In that case, all of the provided suppression spec‐
322 ification files are taken into account.
323
324 Please note that, by default, if this option is not provided, then
325 the default suppression specification files are loaded .
326
327 · --drop <regex>
328
329 When reading the first-shared-library and second-shared-library
330 ELF input files, drop the globally defined functions and variables
331 which name match the regular expression regex. As a result, no
332 change involving these functions or variables will be emitted in
333 the diff report.
334
335 · --drop-fn <regex>
336
337 When reading the first-shared-library and second-shared-library
338 ELF input files, drop the globally defined functions which name
339 match the regular expression regex. As a result, no change
340 involving these functions will be emitted in the diff report.
341
342 · --drop-var <regex>
343
344 When reading the first-shared-library and second-shared-library
345 ELF input files, drop the globally defined variables matching a
346 the regular expression regex.
347
348 · --keep <regex>
349
350 When reading the first-shared-library and second-shared-library
351 ELF input files, keep the globally defined functions and variables
352 which names match the regular expression regex. All other func‐
353 tions and variables are dropped on the floor and will thus not
354 appear in the resulting diff report.
355
356 · --keep-fn <regex>
357
358 When reading the first-shared-library and second-shared-library
359 ELF input files, keep the globally defined functions which name
360 match the regular expression regex. All other functions are
361 dropped on the floor and will thus not appear in the resulting
362 diff report.
363
364 · --keep-var <regex>
365
366 When reading the first-shared-library and second-shared-library
367 ELF input files, keep the globally defined which names match the
368 regular expression regex. All other variables are dropped on the
369 floor and will thus not appear in the resulting diff report.
370
371 · --harmless
372
373 In the diff report, display only the harmless changes. By
374 default, the harmless changes are filtered out of the diff report
375 keep the clutter to a minimum and have a greater chance to spot
376 real ABI issues.
377
378 · --no-harmful
379
380 In the diff report, do not display the harmful changes. By
381 default, only the harmful changes are displayed in diff report.
382
383 · --redundant
384
385 In the diff report, do display redundant changes. A redundant
386 change is a change that has been displayed elsewhere in the
387 report.
388
389 · --no-redundant
390
391 In the diff report, do NOT display redundant changes. A redundant
392 change is a change that has been displayed elsewhere in the
393 report. This option is switched on by default.
394
395 · --no-architecture
396
397 Do not take architecture in account when comparing ABIs.
398
399 · --no-corpus-path
400
401 Do not emit the path attribute for the ABI corpus.
402
403 · --fail-no-debug-info
404
405 If no debug info was found, then this option makes the program to
406 fail. Otherwise, without this option, the program will attempt to
407 compare properties of the binaries that are not related to debug
408 info, like pure ELF properties.
409
410 · --leaf-changes-only|-l only show leaf changes, so don’t show
411 impact analysis report.
412
413 The typical output of abidiff when comparing two binaries looks
414 like this
415
416 $ abidiff libtest-v0.so libtest-v1.so
417 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
418 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
419
420 1 function with some indirect sub-type change:
421
422 [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
423 parameter 1 of type 'C&' has sub-type changes:
424 in referenced type 'struct C' at test-v1.cc:7:1:
425 type size hasn't changed
426 1 data member change:
427 type of 'leaf* C::m0' changed:
428 in pointed to type 'struct leaf' at test-v1.cc:1:1:
429 type size changed from 32 to 64 bits
430 1 data member insertion:
431 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
432
433 $
434
435 So in that example the report emits information about how the data
436 member insertion change of “struct leaf” is reachable from func‐
437 tion “void fn(C&)”. In other words, the report not only shows the
438 data member change on “struct leaf”, but it also shows the impact
439 of that change on the function “void fn(C&)”.
440
441 In abidiff parlance, the change on “struct leaf” is called a leaf
442 change. So the --leaf-changes-only --impacted-interfaces options
443 show, well, only the leaf change. And it goes like this:
444
445 $ abidiff -l libtest-v0.so libtest-v1.so
446 'struct leaf' changed:
447 type size changed from 32 to 64 bits
448 1 data member insertion:
449 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
450
451 one impacted interface:
452 function void fn(C&)
453 $
454
455 Note how the report ends by showing the list of interfaces
456 impacted by the leaf change.
457
458 Now if you don’t want to see that list of impacted interfaces,
459 then you can just avoid using the --impacted-interface option.
460 You can learn about that option below, in any case.
461
462 · --impacted-interfaces
463
464 When showing leaf changes, this option instructs abidiff to show
465 the list of impacted interfaces. This option is thus to be used
466 in addition the --leaf-changes-only option, otherwise, it’s
467 ignored.
468
469 · --dump-diff-tree
470 After the diff report, emit a textual representation of the diff
471 nodes tree used by the comparison engine to represent the
472 changed functions and variables. That representation is emitted
473 to the error output for debugging purposes. Note that this diff
474 tree is relevant only to functions and variables that have some
475 sub-type changes. Added or removed functions and variables do
476 not have any diff nodes tree associated to them.
477
478 · --stats
479
480 Emit statistics about various internal things.
481
482 · --verbose
483
484 Emit verbose logs about the progress of miscellaneous internal
485 things.
486
487 Return values
488 The exit code of the abidiff command is either 0 if the ABI of the
489 binaries being compared are equal, or non-zero if they differ or if the
490 tool encountered an error.
491
492 In the later case, the exit code is a 8-bits-wide bit field in which
493 each bit has a specific meaning.
494
495 The first bit, of value 1, named ABIDIFF_ERROR means there was an
496 error.
497
498 The second bit, of value 2, named ABIDIFF_USAGE_ERROR means there was
499 an error in the way the user invoked the tool. It might be set, for
500 instance, if the user invoked the tool with an unknown command line
501 switch, with a wrong number or argument, etc. If this bit is set, then
502 the ABIDIFF_ERROR bit must be set as well.
503
504 The third bit, of value 4, named ABIDIFF_ABI_CHANGE means the ABI of
505 the binaries being compared are different.
506
507 The fourth bit, of value 8, named ABIDIFF_ABI_INCOMPATIBLE_CHANGE means
508 the ABI of the binaries compared are different in an incompatible way.
509 If this bit is set, then the ABIDIFF_ABI_CHANGE bit must be set as
510 well. If the ABIDIFF_ABI_CHANGE is set and the ABIDIFF_INCOMPATI‐
511 BLE_CHANGE is NOT set, then it means that the ABIs being compared might
512 or might not be compatible. In that case, a human being needs to
513 review the ABI changes to decide if they are compatible or not.
514
515 Note that, at the moment, there are only a few kinds of ABI changes
516 that would result in setting the flag ABIDIFF_ABI_INCOMPATIBLE_CHANGE.
517 Those ABI changes are either:
518
519 · the removal of the symbol of a function or variable that has been
520 defined and exported.
521
522 · the modification of the index of a member of a virtual function
523 table (for C++ programs and libraries).
524
525 With time, when more ABI change patterns are found to always constitute
526 incompatible ABI changes, we will adapt the code to recognize those
527 cases and set the ABIDIFF_ABI_INCOMPATIBLE_CHANGE accordingly. So, if
528 you find such patterns, please let us know.
529
530 The remaining bits are not used for the moment.
531
532 Usage examples
533 1. Detecting a change in a sub-type of a function:
534
535 $ cat -n test-v0.cc
536 1 // Compile this with:
537 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
538 3
539 4 struct S0
540 5 {
541 6 int m0;
542 7 };
543 8
544 9 void
545 10 foo(S0* /*parameter_name*/)
546 11 {
547 12 // do something with parameter_name.
548 13 }
549 $
550 $ cat -n test-v1.cc
551 1 // Compile this with:
552 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
553 3
554 4 struct type_base
555 5 {
556 6 int inserted;
557 7 };
558 8
559 9 struct S0 : public type_base
560 10 {
561 11 int m0;
562 12 };
563 13
564 14 void
565 15 foo(S0* /*parameter_name*/)
566 16 {
567 17 // do something with parameter_name.
568 18 }
569 $
570 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
571 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
572 $
573 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
574 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
575 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
576
577 1 function with some indirect sub-type change:
578
579 [C]'function void foo(S0*)' has some indirect sub-type changes:
580 parameter 0 of type 'S0*' has sub-type changes:
581 in pointed to type 'struct S0':
582 size changed from 32 to 64 bits
583 1 base class insertion:
584 struct type_base
585 1 data member change:
586 'int S0::m0' offset changed from 0 to 32
587 $
588
589 2. Detecting another change in a sub-type of a function:
590
591 $ cat -n test-v0.cc
592 1 // Compile this with:
593 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
594 3
595 4 struct S0
596 5 {
597 6 int m0;
598 7 };
599 8
600 9 void
601 10 foo(S0& /*parameter_name*/)
602 11 {
603 12 // do something with parameter_name.
604 13 }
605 $
606 $ cat -n test-v1.cc
607 1 // Compile this with:
608 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
609 3
610 4 struct S0
611 5 {
612 6 char inserted_member;
613 7 int m0;
614 8 };
615 9
616 10 void
617 11 foo(S0& /*parameter_name*/)
618 12 {
619 13 // do something with parameter_name.
620 14 }
621 $
622 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
623 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
624 $
625 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
626 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
627 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
628
629 1 function with some indirect sub-type change:
630
631 [C]'function void foo(S0&)' has some indirect sub-type changes:
632 parameter 0 of type 'S0&' has sub-type changes:
633 in referenced type 'struct S0':
634 size changed from 32 to 64 bits
635 1 data member insertion:
636 'char S0::inserted_member', at offset 0 (in bits)
637 1 data member change:
638 'int S0::m0' offset changed from 0 to 32
639
640
641 $
642
643 3. Detecting that functions got removed or added to a library:
644
645 $ cat -n test-v0.cc
646 1 // Compile this with:
647 2 // g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
648 3
649 4 struct S0
650 5 {
651 6 int m0;
652 7 };
653 8
654 9 void
655 10 foo(S0& /*parameter_name*/)
656 11 {
657 12 // do something with parameter_name.
658 13 }
659 $
660 $ cat -n test-v1.cc
661 1 // Compile this with:
662 2 // g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
663 3
664 4 struct S0
665 5 {
666 6 char inserted_member;
667 7 int m0;
668 8 };
669 9
670 10 void
671 11 bar(S0& /*parameter_name*/)
672 12 {
673 13 // do something with parameter_name.
674 14 }
675 $
676 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
677 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
678 $
679 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
680 Functions changes summary: 1 Removed, 0 Changed, 1 Added functions
681 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
682
683 1 Removed function:
684 'function void foo(S0&)' {_Z3fooR2S0}
685
686 1 Added function:
687 'function void bar(S0&)' {_Z3barR2S0}
688
689 $
690
691 abipkgdiff
692 abipkgdiff compares the Application Binary Interfaces (ABI) of the ELF
693 binaries contained in two software packages. The software package for‐
694 mats currently supported are Deb, RPM, tar archives (either compressed
695 or not) and plain directories that contain binaries.
696
697 For a comprehensive ABI change report that includes changes about func‐
698 tion and variable sub-types, the two input packages must be accompanied
699 with their debug information packages that contain debug information in
700 DWARF format.
701
702 Invocation
703 abipkgdiff [option] <package1> <package2>
704
705 package1 and package2 are the packages that contain the binaries to be
706 compared.
707
708 Environment
709 abipkgdiff loads two default suppression specifications files, merges
710 their content and use it to filter out ABI change reports that might be
711 considered as false positives to users.
712
713 · Default system-wide suppression specification file
714
715 It’s located by the optional environment variable LIBABI‐
716 GAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE. If that environment variable
717 is not set, then abipkgdiff tries to load the suppression file $lib‐
718 dir/libabigail/libabigail-default.abignore. If that file is not
719 present, then no default system-wide suppression specification file
720 is loaded.
721
722 · Default user suppression specification file.
723
724 It’s located by the optional environment LIBABIGAIL_DEFAULT_USER_SUP‐
725 PRESSION_FILE. If that environment variable is not set, then abip‐
726 kgdiff tries to load the suppression file $HOME/.abignore. If that
727 file is not present, then no default user suppression specification
728 is loaded.
729
730 In addition to those default suppression specification files, abip‐
731 kgdiff will also look inside the packages being compared and if it sees
732 a file that ends with the extension .abignore, then it will consider it
733 as a suppression specification and it will combine it to the default
734 suppression specification that might be already loaded.
735
736 The user might as well use the --suppressions option (that is docu‐
737 mented further below) to provide a suppression specification.
738
739 Options
740 · --help | -h
741
742 Display a short help about the command and exit.
743
744 · –version | -v
745
746 Display the version of the program and exit.
747
748 · --debug-info-pkg1 | --d1 <path>
749
750 For cases where the debug information for package1 is split out
751 into a separate file, tells abipkgdiff where to find that separate
752 debug information package.
753
754 Note that the debug info for package1 can have been split into
755 several different debug info packages. In that case, several
756 instances of this options can be provided, along with those sev‐
757 eral different debug info packages.
758
759 · --debug-info-pkg2 | --d2 <path>
760
761 For cases where the debug information for package2 is split out
762 into a separate file, tells abipkgdiff where to find that separate
763 debug information package.
764
765 Note that the debug info for package2 can have been split into
766 several different debug info packages. In that case, several
767 instances of this options can be provided, along with those sev‐
768 eral different debug info packages.
769
770 · --devel-pkg1 | --devel1 <path>
771
772 Specifies where to find the Development Package associated with
773 the first package to be compared. That Development Package at
774 path should at least contain header files in which public types
775 exposed by the libraries (of the first package to be compared) are
776 defined. When this option is provided, the tool filters out
777 reports about ABI changes to types that are NOT defined in these
778 header files.
779
780 · --devel-pkg2 | --devel2 <path>
781
782 Specifies where to find the Development Package associated with
783 the second package to be compared. That Development Package at
784 path should at least contains header files in which public types
785 exposed by the libraries (of the second package to be compared)
786 are defined. When this option is provided, the tool filters out
787 reports about ABI changes to types that are NOT defined in these
788 header files.
789
790 · --drop-private-types
791
792 This option is to be used with the --devel-pkg1 and --devel-pkg2
793 options. With this option, types that are NOT defined in the
794 headers are entirely dropped from the internal representation
795 build by Libabigail to represent the ABI. They thus don’t have to
796 be filtered out from the final ABI change report because they are
797 not even present in Libabigail’s representation.
798
799 Without this option however, those private types are kept in the
800 internal representation and later filtered out from the report.
801
802 This options thus potentially makes Libabigail consume less mem‐
803 ory. It’s meant to be mainly used to optimize the memory consump‐
804 tion of the tool on binaries with a lot of publicly defined and
805 exported types.
806
807 · --dso-only
808
809 Compare ELF files that are shared libraries, only. Do not compare
810 executable files, for instance.
811
812 · --private-dso
813
814 By default, abipkgdiff does not compare DSOs that are private to
815 the RPM package. A private DSO is a DSO which SONAME is NOT
816 advertised in the “provides” property of the RPM.
817
818 This option instructs abipkgdiff to also compare DSOs that are NOT
819 advertised in the “provides” property of the RPM.
820
821 Please note that the fact that (by default) abipkgdiff skips pri‐
822 vate DSO is a feature that is available only for RPMs, at the
823 moment. We would happily accept patches adding that feature for
824 other package formats.
825
826 · --leaf-changes-only|-l only show leaf changes, so don’t show
827 impact analysis report.
828
829 The typical output of abipkgdiff and abidiff when comparing two
830 binaries, that we shall call full impact report, looks like this
831
832 $ abidiff libtest-v0.so libtest-v1.so
833 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
834 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
835
836 1 function with some indirect sub-type change:
837
838 [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
839 parameter 1 of type 'C&' has sub-type changes:
840 in referenced type 'struct C' at test-v1.cc:7:1:
841 type size hasn't changed
842 1 data member change:
843 type of 'leaf* C::m0' changed:
844 in pointed to type 'struct leaf' at test-v1.cc:1:1:
845 type size changed from 32 to 64 bits
846 1 data member insertion:
847 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
848
849 $
850
851 So in that example the report emits information about how the data
852 member insertion change of “struct leaf” is reachable from func‐
853 tion “void fn(C&)”. In other words, the report not only shows the
854 data member change on “struct leaf”, but it also shows the impact
855 of that change on the function “void fn(C&)”.
856
857 In abidiff (and abipkgdiff) parlance, the change on “struct leaf”
858 is called a leaf change. So the --leaf-changes-only
859 --impacted-interfaces options show, well, only the leaf change.
860 And it goes like this:
861
862 $ abidiff -l libtest-v0.so libtest-v1.so
863 'struct leaf' changed:
864 type size changed from 32 to 64 bits
865 1 data member insertion:
866 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
867
868 one impacted interface:
869 function void fn(C&)
870 $
871
872 Note how the report ends up by showing the list of interfaces
873 impacted by the leaf change. That’s the effect of the additional
874 --impacted-interfaces option.
875
876 Now if you don’t want to see that list of impacted interfaces,
877 then you can just avoid using the --impacted-interface option.
878 You can learn about that option below, in any case.
879
880 Please note that when comparing two Linux Kernel packages, it’s
881 this leaf changes report that is emitted, by default. The normal
882 so-called full impact report can be emitted with the option
883 --full-impact which is documented later below.
884
885 · --impacted-interfaces
886
887 When showing leaf changes, this option instructs abipkgdiff to
888 show the list of impacted interfaces. This option is thus to be
889 used in addition to the --leaf-changes-only option, or, when com‐
890 paring two Linux Kernel packages. Otherwise, it’s simply ignored.
891
892 · --full-impact|-f
893
894 When comparing two Linux Kernel packages, this function instructs
895 abipkgdiff to emit the so-called full impact report, which is the
896 default report kind emitted by the abidiff tool:
897
898 $ abidiff libtest-v0.so libtest-v1.so
899 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
900 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
901
902 1 function with some indirect sub-type change:
903
904 [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
905 parameter 1 of type 'C&' has sub-type changes:
906 in referenced type 'struct C' at test-v1.cc:7:1:
907 type size hasn't changed
908 1 data member change:
909 type of 'leaf* C::m0' changed:
910 in pointed to type 'struct leaf' at test-v1.cc:1:1:
911 type size changed from 32 to 64 bits
912 1 data member insertion:
913 'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
914
915 $
916
917 · --non-reachable-types|-t
918
919 Analyze and emit change reports for all the types of the binary,
920 including those that are not reachable from global functions and
921 variables.
922
923 This option might incur some serious performance degradation as
924 the number of types analyzed can be huge. However, if paired with
925 the --devel-pkg{1,2} options, the additional non-reachable types
926 analyzed are restricted to those defined in the public headers
927 files carried by the referenced development packages, thus hope‐
928 fully making the performance hit acceptable.
929
930 Also, using this option alongside suppression specifications (by
931 also using the --suppressions option) might help keep the number
932 of analyzed types (and the potential performance degradation) in
933 control.
934
935 Note that without this option, only types that are reachable from
936 global functions and variables are analyzed, so the tool detects
937 and reports changes on these reachable types only.
938
939 · --redundant
940 In the diff reports, do display redundant changes. A redundant
941 change is a change that has been displayed elsewhere in a given
942 report.
943
944 · --harmless
945
946 In the diff report, display only the harmless changes. By
947 default, the harmless changes are filtered out of the diff report
948 keep the clutter to a minimum and have a greater chance to spot
949 real ABI issues.
950
951 · --no-linkage-name
952
953 In the resulting report, do not display the linkage names of the
954 added, removed, or changed functions or variables.
955
956 · --no-added-syms
957
958 Do not show the list of functions, variables, or any symbol that
959 was added.
960
961 · --no-added-binaries
962
963 Do not show the list of binaries that got added to the second
964 package.
965
966 Please note that the presence of such added binaries is not con‐
967 sidered like an ABI change by this tool; as such, it doesn’t have
968 any impact on the exit code of the tool. It does only have an
969 informational value. Removed binaries are, however, considered as
970 an ABI change.
971
972 · --no-abignore
973
974 Do not search the package for the presence of suppression files.
975
976 · --no-parallel
977
978 By default, abipkgdiff will use all the processors it has avail‐
979 able to execute concurrently. This option tells it not to extract
980 packages or run comparisons in parallel.
981
982 · --no-default-suppression
983
984 Do not load the default suppression specification files.
985
986 · --suppressions | --suppr <path-to-suppressions>
987
988 Use a suppression specification file located at path-to-suppres‐
989 sions. Note that this option can appear multiple times on the
990 command line. In that case, all of the suppression specification
991 files are taken into account.
992
993 Please note that, by default, if this option is not provided, then
994 the default suppression specification files are loaded .
995
996 · --linux-kernel-abi-whitelist | -w <path-to-whitelist>
997
998 When comparing two Linux kernel RPM packages, this option points
999 to the white list of names of ELF symbols of functions and vari‐
1000 ables that must be compared for ABI changes. That white list is
1001 called a “Linux kernel ABI white list”.
1002
1003 Any other function or variable which ELF symbol are not present in
1004 that white list will not be considered by the ABI comparison
1005 process.
1006
1007 If this option is not provided – thus if no white list is provided
1008 – then the ABI of all publicly defined and exported functions and
1009 global variables by the Linux Kernel binaries are compared.
1010
1011 Please note that if a white list package is given in parameter,
1012 this option handles it just fine, like if the –wp option was used.
1013
1014 · --wp <path-to-whitelist-package>
1015
1016 When comparing two Linux kernel RPM packages, this option points
1017 an RPM package containining several white lists of names of ELF
1018 symbols of functions and variables that must be compared for ABI
1019 changes. Those white lists are called “Linux kernel ABI white
1020 lists”.
1021
1022 From the content of that white list package, this program then
1023 chooses the appropriate Linux kernel ABI white list to consider
1024 when comparing the ABI of Linux kernel binaries contained in the
1025 Linux kernel packages provided on the command line.
1026
1027 That choosen Linux kernel ABI white list contains the list of
1028 names of ELF symbols of functions and variables that must be com‐
1029 pared for ABI changes.
1030
1031 Any other function or variable which ELF symbol are not present in
1032 that white list will not be considered by the ABI comparison
1033 process.
1034
1035 Note that this option can be provided twice (not mor than twice),
1036 specifying one white list package for each Linux Kernel package
1037 that is provided on the command line.
1038
1039 If this option is not provided – thus if no white list is provided
1040 – then the ABI of all publicly defined and exported functions and
1041 global variables by the Linux Kernel binaries are compared.
1042
1043 · --no-unreferenced-symbols
1044
1045 In the resulting report, do not display change information about
1046 function and variable symbols that are not referenced by any debug
1047 information. Note that for these symbols not referenced by any
1048 debug information, the change information displayed is either
1049 added or removed symbols.
1050
1051 · --no-show-locs
1052 Do not show information about where in the second shared library
1053 the respective type was changed.
1054
1055 · --show-bytes
1056
1057 Show sizes and offsets in bytes, not bits. By default, sizes and
1058 offsets are shown in bits.
1059
1060 · --show-bits
1061
1062 Show sizes and offsets in bits, not bytes. This option is acti‐
1063 vated by default.
1064
1065 · --show-hex
1066
1067 Show sizes and offsets in hexadecimal base.
1068
1069 · --show-dec
1070
1071 Show sizes and offsets in decimal base. This option is activated
1072 by default.
1073
1074 · --no-show-relative-offset-changes
1075
1076 Without this option, when the offset of a data member changes, the
1077 change report not only mentions the older and newer offset, but it
1078 also mentions by how many bits the data member changes. With this
1079 option, the latter is not shown.
1080
1081 · --show-identical-binaries
1082 Show the names of the all binaries compared, including the bina‐
1083 ries whose ABI compare equal. By default, when this option is
1084 not provided, only binaries with ABI changes are mentionned in
1085 the output.
1086
1087 · --fail-no-dbg
1088
1089 Make the program fail and return a non-zero exit code if couldn’t
1090 read any of the debug information that comes from the debug info
1091 packages that were given on the command line. If no debug info
1092 package were provided on the command line then this option is not
1093 active.
1094
1095 Note that the non-zero exit code returned by the program as a
1096 result of this option is the constant ABIDIFF_ERROR. To know the
1097 numerical value of that constant, please refer to the exit code
1098 documentation.
1099
1100 · --keep-tmp-files
1101
1102 Do not erase the temporary directory files that are created during
1103 the execution of the tool.
1104
1105 · --verbose
1106
1107 Emit verbose progress messages.
1108
1109 Return value
1110 The exit code of the abipkgdiff command is either 0 if the ABI of the
1111 binaries compared are equal, or non-zero if they differ or if the tool
1112 encountered an error.
1113
1114 In the later case, the value of the exit code is the same as for the
1115 abidiff tool.
1116
1117 kmidiff
1118 kmidiff compares the binary Kernel Module Interfaces of two Linux Ker‐
1119 nel trees. The binary KMI is the interface that the Linux Kernel
1120 exposes to its modules. The trees we are interested in here are the
1121 result of the build of the Linux Kernel source tree.
1122
1123 General approach
1124 And example of how to build your kernel if you want to compare it to
1125 another one using kmidiff is:
1126
1127 git clone -b v4.5 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux/v4.5
1128 cd linux/v4.5
1129 make allyesconfig all
1130
1131 Then install the modules into a directory, for instance, the build/mod‐
1132 ules sub-directory of the your kernel source tree:
1133
1134 mkdir build/modules
1135 make modules_install INSTALL_MOD_DIR=build/modules
1136
1137 Then construct a list of interfaces exported by the kernel, that you
1138 want to compare:
1139
1140 cat > kmi-whitelist << EOF
1141 [kernel_4.5_kmi_whitelist]
1142 init_task
1143 schedule
1144 dev_queue_xmit
1145 __kmalloc
1146 printk
1147 EOF
1148
1149 Suppose you’ve done something similar for the v4.6 branch of the Linux
1150 kernel, you now have these two directories: linux/v4.5 and linux/v4.6.
1151 Their modules are present under the directories linux/v4.5/build/mod‐
1152 ules and linux/v4.6/build/modules.
1153
1154 To Comparing their KMI kmidiff needs to know where to find the vmlinux
1155 binaries and their associated modules. Here would be what the command
1156 line looks like:
1157
1158 kmidiff \
1159 --kmi-whitelist linux/v4.6/kmi-whitelist \
1160 --vmlinux1 linux/v4.5/vmlinux \
1161 --vmlinux2 linux/v4.6/vmlinux \
1162 linux/v4.5/build/modules \
1163 linux/v4.6/build/modules
1164
1165 Invocation
1166 More generally, kmidiff is invoked under the form:
1167
1168 kmidiff [options] <first-modules-dir> <second-modules-dir>
1169
1170 Environment
1171 By default, kmidiff compares all the interfaces (exported functions and
1172 variables) between the Kernel and its modules. In practice, though,
1173 users want to compare a subset of the those interfaces.
1174
1175 Users can then define a “white list” of the interfaces to compare.
1176 Such a white list is a just a file in the “INI” format that looks like:
1177
1178 [kernel_version_x86_64_whitelist]
1179 function1_name
1180 function2_name
1181 global_variable1_name
1182 ....
1183
1184 Note that the name of the section (the name that is between the two
1185 brackets) of that INI file just has to end with the string “whitelist”.
1186 So you can define the name you want, for instance [ker‐
1187 nel_46_x86_64_whitelist].
1188
1189 Then each line of that whitelist file is the name of an exported func‐
1190 tion or variable. Only those interfaces along with the types reachable
1191 from their signatures are going to be compared by kmidiff recursively.
1192
1193 Note that kmidiff compares the interfaces exported by the vmlinux
1194 binary and by the all of the compiled modules.
1195
1196 Options
1197 · --help | -h
1198
1199 Display a short help about the command and exit.
1200
1201 · --version | -v
1202
1203 Display the version of the program and exit.
1204
1205 · --verbose
1206
1207 Display some verbose messages while executing.
1208
1209 · --debug-info-dir1 | --d1 <di-path1>
1210
1211 For cases where the debug information for the binaries of the
1212 first Linux kernel is split out into separate files, tells kmidiff
1213 where to find those separate debug information files.
1214
1215 Note that di-path must point to the root directory under which the
1216 debug information is arranged in a tree-like manner. Under Red
1217 Hat based systems, that directory is usually <root>/usr/lib/debug.
1218
1219 · --debug-info-dir2 | --d2 <di-path2>
1220
1221 Like --debug-info-dir1, this options tells kmidiff where to find
1222 the split debug information for the binaries of the second Linux
1223 kernel.
1224
1225 · --vmlinux1 | --l1 <path-to-first-vmlinux>
1226
1227 Sets the path to the first vmlinux binary to consider. This has
1228 to be the uncompressed vmlinux binary compiled with debug info.
1229
1230 · --vmlinux2 | --l2 <path-to-first-vmlinux>
1231
1232 Sets the path to the second vmlinux binary to consider. This has
1233 to be the uncompressed vmlinux binary compiled with debug info.
1234
1235 · --kmi-whitelist | -w <path-to-interface-whitelist>
1236
1237 Set the path to the white list of interfaces to compare while com‐
1238 paring the Kernel Module Interface of the first kernel against the
1239 one of the second kernel.
1240
1241 If this option is not provided, all the exported interfaces of the
1242 two kernels are compared. That takes a lot of times and is not
1243 necessarily meaningful because many interface are probably meant
1244 to see their reachable types change.
1245
1246 So please, make sure you always use this option unless you really
1247 know what you are doing.
1248
1249 · --suppressions | --suppr <path-to-suppressions>
1250
1251 Use a suppression specification file located at path-to-suppres‐
1252 sions. Note that this option can appear multiple times on the
1253 command line. In that case, all of the provided suppression spec‐
1254 ification files are taken into account.
1255
1256 Please note that, by default, if this option is not provided, then
1257 the default suppression specification files are loaded .
1258
1259 · --impacted-interfaces | -i
1260
1261 Tell what interfaces got impacted by each individual ABI change.
1262
1263 · --full-impact | -f
1264
1265 Emit a change report that shows the full impact of each change on
1266 exported interfaces. This is the default kind of report emitted
1267 by tools like abidiff or abipkgdiff.
1268
1269 · --show-bytes
1270
1271 Show sizes and offsets in bytes, not bits. This option is acti‐
1272 vated by default.
1273
1274 · --show-bits
1275
1276 Show sizes and offsets in bits, not bytes. By default, sizes and
1277 offsets are shown in bytes.
1278
1279 · --show-hex
1280
1281 Show sizes and offsets in hexadecimal base. This option is acti‐
1282 vated by default.
1283
1284 · --show-dec
1285
1286 Show sizes and offsets in decimal base.
1287
1288 abidw
1289 abidw reads a shared library in ELF format and emits an XML representa‐
1290 tion of its ABI to standard output. The emitted representation
1291 includes all the globally defined functions and variables, along with a
1292 complete representation of their types. It also includes a representa‐
1293 tion of the globally defined ELF symbols of the file. The input shared
1294 library must contain associated debug information in DWARF format.
1295
1296 When given the --linux-tree option, this program can also handle a
1297 Linux kernel tree. That is, a directory tree that contains both the
1298 vmlinux binary and Linux kernel modules. It analyses those Linux ker‐
1299 nel binaries and emits an XML representation of the interface between
1300 the kernel and its module, to standard output. In this case, we don’t
1301 call it an ABI, but a KMI (Kernel Module Interface). The emitted KMI
1302 includes all the globally defined functions and variables, along with a
1303 complete representation of their types. The input binaries must con‐
1304 tain associated debug information in DWARF format.
1305
1306 Invocation
1307 abidw [options] [<path-to-elf-file>]
1308
1309 Options
1310 · --help | -h
1311
1312 Display a short help about the command and exit.
1313
1314 · –version | -v
1315
1316 Display the version of the program and exit.
1317
1318 · --debug-info-dir | -d <dir-path>
1319
1320 In cases where the debug info for path-to-elf-file is in a sepa‐
1321 rate file that is located in a non-standard place, this tells
1322 abidw where to look for that debug info file.
1323
1324 Note that dir-path must point to the root directory under which
1325 the debug information is arranged in a tree-like manner. Under
1326 Red Hat based systems, that directory is usually
1327 <root>/usr/lib/debug.
1328
1329 This option can be provided several times with different root
1330 directories. In that case, abidw will potentially look into all
1331 those root directories to find the split debug info for the elf
1332 file.
1333
1334 Note that this option is not mandatory for split debug information
1335 installed by your system’s package manager because then abidw
1336 knows where to find it.
1337
1338 · --out-file <file-path>
1339
1340 This option instructs abidw to emit the XML representation of
1341 path-to-elf-file into the file file-path, rather than emitting it
1342 to its standard output.
1343
1344 · --noout
1345
1346 This option instructs abidw to not emit the XML representation of
1347 the ABI. So it only reads the ELF and debug information, builds
1348 the internal representation of the ABI and exits. This option is
1349 usually useful for debugging purposes.
1350
1351 · --no-corpus-path
1352
1353 Do not emit the path attribute for the ABI corpus.
1354
1355 · --suppressions | suppr <path-to-suppression-specifications-file>
1356
1357 Use a suppression specification file located at path-to-suppres‐
1358 sion-specifications-file. Note that this option can appear multi‐
1359 ple times on the command line. In that case, all of the provided
1360 suppression specification files are taken into account. ABI arti‐
1361 facts matched by the suppression specifications are suppressed
1362 from the output of this tool.
1363
1364 · --kmi-whitelist | -kaw <path-to-whitelist>
1365
1366 When analyzing a Linux kernel binary, this option points to the
1367 white list of names of ELF symbols of functions and variables
1368 which ABI must be written out. That white list is called a ” Ker‐
1369 nel Module Interface white list”. This is because for the Kernel,
1370 we don’t talk about the ABI; we rather talk about the interface
1371 between the Kernel and its module. Hence the term KMI rather than
1372 ABI
1373
1374 Any other function or variable which ELF symbol are not present in
1375 that white list will not be considered by the KMI writing process.
1376
1377 If this option is not provided – thus if no white list is provided
1378 – then the entire KMI, that is, all publicly defined and exported
1379 functions and global variables by the Linux Kernel binaries is
1380 emitted.
1381
1382 · --linux-tree | --lt
1383
1384 Make abidw to consider the input path as a path to a directory
1385 containing the vmlinux binary as several kernel modules binaries.
1386 In that case, this program emits the representation of the Kernel
1387 Module Interface (KMI) on the standard output.
1388
1389 Below is an example of usage of abidw on a Linux Kernel tree.
1390
1391 First, checkout a Linux kernel source tree and build it. Then
1392 install the kernel modules in a directory somewhere. Copy the
1393 vmlinux binary into that directory too. And then serialize the
1394 KMI of that kernel to disk, using abidw:
1395
1396 $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
1397 $ cd linux && git checkout v4.5
1398 $ make allyesconfig all
1399 $ mkdir build-output
1400 $ make INSTALL_MOD_PATH=./build-output modules_install
1401 $ cp vmlinux build-output/modules/4.5.0
1402 $ abidw --linux-tree build-output/modules/4.5.0 > build-output/linux-4.5.0.kmi
1403
1404 · --headers-dir | --hd <headers-directory-path-1>
1405
1406 Specifies where to find the public headers of the first shared
1407 library that the tool has to consider. The tool will thus filter
1408 out types that are not defined in public headers.
1409
1410 · --no-linux-kernel-mode
1411
1412 Without this option, if abipkgiff detects that the binaries it is
1413 looking at are Linux Kernel binaries (either vmlinux or modules)
1414 then it only considers functions and variables which ELF symbols
1415 are listed in the __ksymtab and __ksymtab_gpl sections.
1416
1417 With this option, abipkgdiff considers the binary as a non-special
1418 ELF binary. It thus considers functions and variables which are
1419 defined and exported in the ELF sense.
1420
1421 · --check-alternate-debug-info <elf-path>
1422
1423 If the debug info for the file elf-path contains a reference to an
1424 alternate debug info file, abidw checks that it can find that
1425 alternate debug info file. In that case, it emits a meaningful
1426 success message mentioning the full path to the alternate debug
1427 info file found. Otherwise, it emits an error code.
1428
1429 · --no-show-locs
1430 In the emitted ABI representation, do not show file, line or
1431 column where ABI artifacts are defined.
1432
1433 · --check-alternate-debug-info-base-name <elf-path>
1434
1435 Like --check-alternate-debug-info, but in the success message,
1436 only mention the base name of the debug info file; not its full
1437 path.
1438
1439 · --load-all-types
1440
1441 By default, libabigail (and thus abidw) only loads types that are
1442 reachable from functions and variables declarations that are pub‐
1443 licly defined and exported by the binary. So only those types are
1444 present in the output of abidw. This option however makes abidw
1445 load all the types defined in the binaries, even those that are
1446 not reachable from public declarations.
1447
1448 · --abidiff
1449 Load the ABI of the ELF binary given in argument, save it in
1450 libabigail’s XML format in a temporary file; read the ABI from
1451 the temporary XML file and compare the ABI that has been read
1452 back against the ABI of the ELF binary given in argument. The
1453 ABIs should compare equal. If they don’t, the program emits a
1454 diagnostic and exits with a non-zero code.
1455
1456 This is a debugging and sanity check option.
1457
1458 · --annotate
1459 Annotate the ABIXML output with comments above most elements.
1460 The comments are made of the pretty-printed form types, declara‐
1461 tion or even ELF symbols. The purpose is to make the ABIXML
1462 output more human-readable for debugging or documenting pur‐
1463 poses.
1464
1465 · --stats
1466
1467 Emit statistics about various internal things.
1468
1469 · --verbose
1470
1471 Emit verbose logs about the progress of miscellaneous internal
1472 things.
1473
1474 Notes
1475 Alternate debug info files
1476 As of the version 4 of the DWARF specification, Alternate debug infor‐
1477 mation is a GNU extension to the DWARF specification. It has however
1478 been proposed for inclusion into the upcoming version 5 of the DWARF
1479 standard. You can read more about the GNU extensions to the DWARF
1480 standard here.
1481
1482 abicompat
1483 abicompat checks that an application that links against a given shared
1484 library is still ABI compatible with a subsequent version of that
1485 library. If the new version of the library introduces an ABI incompat‐
1486 ibility, then abicompat hints the user at what exactly that incompati‐
1487 bility is.
1488
1489 Invocation
1490 abicompat [options] [<application> <shared-library-first-version> <shared-library-second-version>]
1491
1492 Options
1493 · --help
1494
1495 Display a short help about the command and exit.
1496
1497 · –version | -v
1498
1499 Display the version of the program and exit.
1500
1501 · --list-undefined-symbols | -u
1502
1503 Display the list of undefined symbols of the application and exit.
1504
1505 · --show-base-names | -b
1506
1507 In the resulting report emitted by the tool, this option makes the
1508 application and libraries be referred to by their base names only;
1509 not by a full absolute name. This can be useful for use in
1510 scripts that wants to compare names of the application and
1511 libraries independently of what their directory names are.
1512
1513 · --app-debug-info-dir | --appd <path-to-app-debug-info-directory>
1514
1515 Set the path to the directory under which the debug information of
1516 the application is supposed to be laid out. This is useful for
1517 application binaries for which the debug info is in a separate set
1518 of files.
1519
1520 · --lib-debug-info-dir1 | --libd1 <path-to-lib1-debug-info>
1521
1522 Set the path to the directory under which the debug information of
1523 the first version of the shared library is supposed to be laid
1524 out. This is useful for shared library binaries for which the
1525 debug info is in a separate set of files.
1526
1527 · --lib-debug-info-dir2 | --libd2 <path-to-lib1-debug-info>
1528
1529 Set the path to the directory under which the debug information of
1530 the second version of the shared library is supposed to be laid
1531 out. This is useful for shared library binaries for which the
1532 debug info is in a separate set of files.
1533
1534 · --suppressions | --suppr <path-to-suppressions>
1535
1536 Use a suppression specification file located at path-to-suppres‐
1537 sions. Note that this option can appear multiple times on the
1538 command line; all the suppression specification files are then
1539 taken into account.
1540
1541 · --no-show-locs
1542 Do not show information about where in the second shared library
1543 the respective type was changed.
1544
1545 · --weak-mode
1546
1547 This triggers the weak mode of abicompat. In this mode, only one
1548 version of the library is required. That is, abicompat is invoked
1549 like this:
1550
1551 abicompat --weak-mode <the-application> <the-library>
1552
1553 Note that the --weak-mode option can even be omitted if only one
1554 version of the library is given, along with the application; in
1555 that case, abicompat automatically switches to operate in weak
1556 mode:
1557
1558 abicompat <the-application> <the-library>
1559
1560 In this weak mode, the types of functions and variables exported
1561 by the library and consumed by the application (as in, the symbols
1562 of the these functions and variables are undefined in the applica‐
1563 tion and are defined and exported by the library) are compared to
1564 the version of these types as expected by the application. And if
1565 these two versions of types are different, abicompat tells the
1566 user what the differences are.
1567
1568 In other words, in this mode, abicompat checks that the types of
1569 the functions and variables exported by the library mean the same
1570 thing as what the application expects, as far as the ABI is con‐
1571 cerned.
1572
1573 Note that in this mode, abicompat doesn’t detect exported func‐
1574 tions or variables (symbols) that are expected by the application
1575 but that are removed from the library. That is why it is called
1576 weak mode.
1577
1578 Return values
1579 The exit code of the abicompat command is either 0 if the ABI of the
1580 binaries being compared are equal, or non-zero if they differ or if the
1581 tool encountered an error.
1582
1583 In the later case, the exit code is a 8-bits-wide bit field in which
1584 each bit has a specific meaning.
1585
1586 The first bit, of value 1, named ABIDIFF_ERROR means there was an
1587 error.
1588
1589 The second bit, of value 2, named ABIDIFF_USAGE_ERROR means there was
1590 an error in the way the user invoked the tool. It might be set, for
1591 instance, if the user invoked the tool with an unknown command line
1592 switch, with a wrong number or argument, etc. If this bit is set, then
1593 the ABIDIFF_ERROR bit must be set as well.
1594
1595 The third bit, of value 4, named ABIDIFF_ABI_CHANGE means the ABI of
1596 the binaries being compared are different.
1597
1598 The fourth bit, of value 8, named ABIDIFF_ABI_INCOMPATIBLE_CHANGE means
1599 the ABI of the binaries compared are different in an incompatible way.
1600 If this bit is set, then the ABIDIFF_ABI_CHANGE bit must be set as
1601 well. If the ABIDIFF_ABI_CHANGE is set and the ABIDIFF_INCOMPATI‐
1602 BLE_CHANGE is NOT set, then it means that the ABIs being compared might
1603 or might not be compatible. In that case, a human being needs to
1604 review the ABI changes to decide if they are compatible or not.
1605
1606 The remaining bits are not used for the moment.
1607
1608 Usage examples
1609 · Detecting a possible ABI incompatibility in a new shared library
1610 version:
1611
1612 $ cat -n test0.h
1613 1 struct foo
1614 2 {
1615 3 int m0;
1616 4
1617 5 foo()
1618 6 : m0()
1619 7 {}
1620 8 };
1621 9
1622 10 foo*
1623 11 first_func();
1624 12
1625 13 void
1626 14 second_func(foo&);
1627 15
1628 16 void
1629 17 third_func();
1630 $
1631
1632 $ cat -n test-app.cc
1633 1 // Compile with:
1634 2 // g++ -g -Wall -o test-app -L. -ltest-0 test-app.cc
1635 3
1636 4 #include "test0.h"
1637 5
1638 6 int
1639 7 main()
1640 8 {
1641 9 foo* f = first_func();
1642 10 second_func(*f);
1643 11 return 0;
1644 12 }
1645 $
1646
1647 $ cat -n test0.cc
1648 1 // Compile this with:
1649 2 // g++ -g -Wall -shared -o libtest-0.so test0.cc
1650 3
1651 4 #include "test0.h"
1652 5
1653 6 foo*
1654 7 first_func()
1655 8 {
1656 9 foo* f = new foo();
1657 10 return f;
1658 11 }
1659 12
1660 13 void
1661 14 second_func(foo&)
1662 15 {
1663 16 }
1664 17
1665 18 void
1666 19 third_func()
1667 20 {
1668 21 }
1669 $
1670
1671 $ cat -n test1.h
1672 1 struct foo
1673 2 {
1674 3 int m0;
1675 4 char m1; /* <-- a new member got added here! */
1676 5
1677 6 foo()
1678 7 : m0(),
1679 8 m1()
1680 9 {}
1681 10 };
1682 11
1683 12 foo*
1684 13 first_func();
1685 14
1686 15 void
1687 16 second_func(foo&);
1688 17
1689 18 void
1690 19 third_func();
1691 $
1692
1693 $ cat -n test1.cc
1694 1 // Compile this with:
1695 2 // g++ -g -Wall -shared -o libtest-1.so test1.cc
1696 3
1697 4 #include "test1.h"
1698 5
1699 6 foo*
1700 7 first_func()
1701 8 {
1702 9 foo* f = new foo();
1703 10 return f;
1704 11 }
1705 12
1706 13 void
1707 14 second_func(foo&)
1708 15 {
1709 16 }
1710 17
1711 18 /* Let's comment out the definition of third_func()
1712 19 void
1713 20 third_func()
1714 21 {
1715 22 }
1716 23 */
1717 $
1718
1719 · Compile the first and second versions of the libraries:
1720 libtest-0.so and libtest-1.so:
1721
1722 $ g++ -g -Wall -shared -o libtest-0.so test0.cc
1723 $ g++ -g -Wall -shared -o libtest-1.so test1.cc
1724
1725 · Compile the application and link it against the first version of
1726 the library, creating the test-app binary:
1727
1728 $ g++ -g -Wall -o test-app -L. -ltest-0.so test-app.cc
1729
1730 · Now, use abicompat to see if libtest-1.so is ABI compatible with
1731 app, with respect to the ABI of libtest-0.so:
1732
1733 $ abicompat test-app libtest-0.so libtest-1.so
1734 ELF file 'test-app' might not be ABI compatible with 'libtest-1.so' due to differences with 'libtest-0.so' below:
1735 Functions changes summary: 0 Removed, 2 Changed, 0 Added functions
1736 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1737
1738 2 functions with some indirect sub-type change:
1739
1740 [C]'function foo* first_func()' has some indirect sub-type changes:
1741 return type changed:
1742 in pointed to type 'struct foo':
1743 size changed from 32 to 64 bits
1744 1 data member insertion:
1745 'char foo::m1', at offset 32 (in bits)
1746 [C]'function void second_func(foo&)' has some indirect sub-type changes:
1747 parameter 0 of type 'foo&' has sub-type changes:
1748 referenced type 'struct foo' changed, as reported earlier
1749
1750 $
1751
1752 · Now use the weak mode of abicompat, that is, providing just the
1753 application and the new version of the library:
1754
1755 $ abicompat --weak-mode test-app libtest-1.so
1756 functions defined in library
1757 'libtest-1.so'
1758 have sub-types that are different from what application
1759 'test-app'
1760 expects:
1761
1762 function foo* first_func():
1763 return type changed:
1764 in pointed to type 'struct foo':
1765 size changed from 32 to 64 bits
1766 1 data member insertion:
1767 'char foo::m1', at offset 32 (in bits)
1768
1769 $
1770
1771 abilint
1772 abilint parses the native XML representation of an ABI as emitted by
1773 abidw. Once it has parsed the XML representation of the ABI, abilint
1774 builds and in-memory model from it. It then tries to save it back to
1775 an XML form, to standard output. If that read-write operation succeeds
1776 chances are the input XML ABI representation is meaningful.
1777
1778 Note that the main intent of this tool to help debugging issues in the
1779 underlying Libabigail library.
1780
1781 Note also that abilint can also read an ELF input file, build the
1782 in-memory model for its ABI, and serialize that model back into XML to
1783 standard output. In that case, the ELF input file must be accompanied
1784 with its debug information in the DWARF format.
1785
1786 Invocation
1787 abilint [options] [<abi-file1>]
1788
1789 Options
1790 · --help
1791
1792 Display a short help message and exits.
1793
1794 · –version | -v
1795
1796 Display the version of the program and exit.
1797
1798 · --debug-info-dir <path>
1799
1800 When reading an ELF input file which debug information is split
1801 out into a separate file, this options tells abilint where to find
1802 that separate debug information file.
1803
1804 Note that path must point to the root directory under which the
1805 debug information is arranged in a tree-like manner. Under Red
1806 Hat based systems, that directory is usually <root>/usr/lib/debug.
1807
1808 Note also that this option is not mandatory for split debug infor‐
1809 mation installed by your system’s package manager because then
1810 abidiff knows where to find it.
1811
1812 · --diff
1813
1814 For XML inputs, perform a text diff between the input and the mem‐
1815 ory model saved back to disk. This can help to spot issues in the
1816 handling of the XML format by the underlying Libabigail library.
1817
1818 · --noout
1819
1820 Do not display anything on standard output. The return code of
1821 the command is the only way to know if the command succeeded.
1822
1823 · --suppressions | suppr <path-to-suppression-specifications-file>
1824
1825 Use a suppression specification file located at path-to-suppres‐
1826 sion-specifications-file. Note that this option can appear multi‐
1827 ple times on the command line. In that case, all of the provided
1828 suppression specification files are taken into account. ABI arti‐
1829 facts matched by the suppression specifications are suppressed
1830 from the output of this tool.
1831
1832 · --headers-dir | --hd <headers-directory-path-1>
1833
1834 Specifies where to find the public headers of the first shared
1835 library that the tool has to consider. The tool will thus filter
1836 out types that are not defined in public headers.
1837
1838 · --stdin | --
1839
1840 Read the input content from standard input.
1841
1842 · --tu
1843
1844 Expect the input XML to represent a single translation unit.
1845
1846 fedabipkgdiff
1847 fedabipkgdiff compares the ABI of shared libraries in Fedora packages.
1848 It’s a convenient way to do so without having to manually download
1849 packages from the Fedora Build System.
1850
1851 fedabipkgdiff knows how to talk with the Fedora Build System to find
1852 the right packages versions, their associated debug information and
1853 development packages, download them, compare their ABI locally, and
1854 report about the possible ABI changes.
1855
1856 Note that by default, this tool reports ABI changes about types that
1857 are defined in public header files found in the development packages
1858 associated with the packages being compared. It also reports ABI
1859 changes about functions and global variables whose symbols are defined
1860 and exported in the ELF binaries found in the packages being compared.
1861
1862 Invocation
1863 fedabipkgdiff [option] <NVR> ...
1864
1865 Environment
1866 fedabipkgdiff loads two default suppression specifications files,
1867 merges their content and use it to filter out ABI change reports that
1868 might be considered as false positives to users.
1869
1870 · Default system-wide suppression specification file
1871
1872 It’s located by the optional environment variable LIBABI‐
1873 GAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE. If that environment variable
1874 is not set, then fedabipkgdiff tries to load the suppression file
1875 $libdir/libabigail/libabigail-default.abignore. If that file is not
1876 present, then no default system-wide suppression specification file
1877 is loaded.
1878
1879 · Default user suppression specification file.
1880
1881 It’s located by the optional environment LIBABIGAIL_DEFAULT_USER_SUP‐
1882 PRESSION_FILE. If that environment variable is not set, then fed‐
1883 abipkgdiff tries to load the suppression file $HOME/.abignore. If
1884 that file is not present, then no default user suppression specifica‐
1885 tion is loaded.
1886
1887 Options
1888 · --help | -h
1889
1890 Display a short help about the command and exit.
1891
1892 · --dry-run
1893
1894 Don’t actually perform the ABI comparison. Details about what is
1895 going to be done are emitted on standard output.
1896
1897 · --debug
1898
1899 Emit debugging messages about the execution of the program.
1900 Details about each method invocation, including input parameters
1901 and returned values, are emitted.
1902
1903 · --traceback
1904
1905 Show traceback when an exception raised. This is useful for devel‐
1906 opers of the tool itself to know more exceptional errors.
1907
1908 · --server <URL>
1909
1910 Specifies the URL of the Koji XMLRPC service the tool talks to.
1911 The default value of this option is
1912 http://koji.fedoraproject.org/kojihub.
1913
1914 · --topurl <URL>
1915
1916 Specifies the URL of the package store the tool downloads RPMs
1917 from. The default value of this option is
1918 https://kojipkgs.fedoraproject.org.
1919
1920 · --from <distro>
1921
1922 Specifies the name of the baseline Fedora distribution in which to
1923 find the first build that is used for comparison. The distro value
1924 can be any valid value of the RPM macro %{?dist} for Fedora, for
1925 example, fc4, fc23, fc25.
1926
1927 · --to <distro>
1928
1929 Specifies the name of the Fedora distribution in which to find the
1930 build that is compared against the baseline specified by option
1931 --from. The distro value could be any valid value of the RPM
1932 macro %{?dist} for Fedora, for example, fc4, fc23.
1933
1934 · --all-subpackages
1935
1936 Instructs the tool to also compare the ABI of the binaries in the
1937 sub-packages of the packages specified.
1938
1939 · --dso-only
1940
1941 Compares the ABI of shared libraries only. If this option is not
1942 provided, the tool compares the ABI of all ELF binaries found in
1943 the packages.
1944
1945 · --suppressions <path-to-suppresions>
1946
1947 Use a suppression specification file located at path-to-suppres‐
1948 sions.
1949
1950 · --no-default-suppression
1951
1952 Do not load the default suppression specification files.
1953
1954 · --no-devel-pkg
1955
1956 Do not take associated development packages into account when per‐
1957 forming the ABI comparison. This makes the tool report ABI
1958 changes about all types that are reachable from functions and
1959 global variables which symbols are defined and publicly exported
1960 in the binaries being compared, even if those types are not
1961 defined in public header files available from the packages being
1962 compared.
1963
1964 · --show-identical-binaries
1965 Show the names of the all binaries compared, including the bina‐
1966 ries whose ABI compare equal. By default, when this option is
1967 not provided, only binaries with ABI changes are mentionned in
1968 the output.
1969
1970 · --abipkgdiff <path/to/abipkgdiff>
1971
1972 Specify an alternative abipkgdiff instead of the one installed in
1973 system.
1974
1975 · --clean-cache-before
1976
1977 Clean cache before ABI comparison.
1978
1979 · --clean-cache-after
1980
1981 Clean cache after ABI comparison.
1982
1983 · --clean-cache
1984
1985 If you want to clean cache both before and after ABI comparison,
1986 --clean-cache is the convenient way for you to save typing of two
1987 options at same time.
1988
1989 Note that a build is a specific version and release of an RPM package.
1990 It’s specified by its the package name, version and release. These are
1991 specified by the Fedora Naming Guidelines
1992
1993 Return value
1994 The exit code of the abipkgdiff command is either 0 if the ABI of the
1995 binaries compared are equivalent, or non-zero if they differ or if the
1996 tool encountered an error.
1997
1998 In the later case, the value of the exit code is the same as for the
1999 abidiff tool.
2000
2001 Use cases
2002 Below are some usage examples currently supported by fedabipkgdiff.
2003
2004 1. Compare the ABI of binaries in a local package against the ABI of
2005 the latest stable package in Fedora 23.
2006
2007 Suppose you have built just built the httpd package and you want
2008 to compare the ABI of the binaries in this locally built package
2009 against the ABI of the binaries in the latest http build from
2010 Fedora 23. The command line invocation would be:
2011
2012 $ fedabipkgdiff --from fc23 ./httpd-2.4.18-2.fc24.x86_64.rpm
2013
2014 2. Compare the ABI of binaries in two local packages.
2015
2016 Suppose you have built two versions of package httpd, and you
2017 want to see what ABI differences between these two versions of
2018 RPM files. The command line invocation would be:
2019
2020 $ fedabipkgdiff path/to/httpd-2.4.23-3.fc23.x86_64.rpm another/path/to/httpd-2.4.23-4.fc24.x86_64.rpm
2021
2022 All what fedabipkgdiff does happens on local machine without the
2023 need of querying or downloading RPMs from Koji.
2024
2025 3. Compare the ABI of binaries in the latest build of the httpd
2026 package in Fedora 23 against the ABI of the binaries in the lat‐
2027 est build of the same package in 24.
2028
2029 In this case, note that neither of the two packages are available
2030 locally. The tool is going to talk with the Fedora Build System,
2031 determine what the versions and releases of the latest packages
2032 are, download them and perform the comparison locally. The com‐
2033 mand line invocation would be:
2034
2035 $ fedabipkgdiff --from fc23 --to fc24 httpd
2036
2037 4. Compare the ABI of binaries of two builds of the httpd package,
2038 designated their versions and releases.
2039
2040 If we want to do perform the ABI comparison for all the processor
2041 architectures supported by Fedora the command line invocation
2042 would be:
2043
2044 $ fedabipkgdiff httpd-2.8.14.fc23 httpd-2.8.14.fc24
2045
2046 But if we want to perform the ABI comparison for a specific
2047 architecture, say, x86_64, then the command line invocation would
2048 be:
2049
2050 $ fedabipkgdiff httpd-2.8.14.fc23.x86_64 httpd-2.8.14.fc24.x86_64
2051
2052 5. If the use wants to also compare the sub-packages of a given
2053 package, she can use the –all-subpackages option. The first com‐
2054 mand of the previous example would thus look like:
2055
2056 $ fedabipkgdiff --all-subpackages httpd-2.8.14.fc23 httpd-2.8.14.fc24
2057
2059 ABI artifacts
2060 An ABI artifact is a relevant part of the ABI of a shared library or
2061 program. Examples of ABI artifacts are exported types, variables,
2062 functions, or ELF symbols exported by a shared library.
2063
2064 The set of ABI artifact for a binary is called an ABI Corpus.
2065
2066 Harmful changes
2067 A change in the diff report is considered harmful if it might cause ABI
2068 compatibility issues. That is, it might prevent an application dynami‐
2069 cally linked against a given version of a library to keep working with
2070 the changed subsequent versions of the same library.
2071
2072 Harmless changes
2073 A change in the diff report is considered harmless if it will not cause
2074 any ABI compatibility issue. That is, it will not prevent an applica‐
2075 tion dynamically linked against given version of a library to keep
2076 working with the changed subsequent versions of the same library.
2077
2078 By default, abidiff filters harmless changes from the diff report.
2079
2080 Suppression specifications
2081 Definition
2082 A suppression specification file is a way for a user to instruct abid‐
2083 iff, abipkgdiff or any other relevant libabigail tool to avoid emitting
2084 reports for changes involving certain ABI artifacts.
2085
2086 It contains directives (or specifications) that describe the set of ABI
2087 artifacts to avoid emitting change reports about.
2088
2089 Introductory examples
2090 Its syntax is based on a simplified and customized form of Ini File
2091 Syntax. For instance, to specify that change reports on a type named
2092 FooPrivateType should be suppressed, one could write this suppression
2093 specification:
2094
2095 [suppress_type]
2096 name = FooPrivateType
2097
2098 If we want to ensure that only change reports about structures named
2099 FooPrivateType should be suppressed, we could write:
2100
2101 [suppress_type]
2102 type_kind = struct
2103 name = FooPrivateType
2104
2105 But we could also want to suppress change reports avoid typedefs named
2106 FooPrivateType. In that case we would write:
2107
2108 [suppress_type]
2109 type_kind = typedef
2110 name = FooPrivateType
2111
2112 Or, we could want to suppress change reports about all struct which
2113 names end with the string “PrivateType”:
2114
2115 [suppress_type]
2116 type_kind = struct
2117 name_regexp = ^.*PrivateType
2118
2119 Let’s now look at the generic syntax of suppression specification
2120 files.
2121
2122 Syntax
2123 Properties
2124 More generally, the format of suppression lists is organized around the
2125 concept of property. Every property has a name and a value, delimited
2126 by the = sign. E.g:
2127
2128 name = value
2129
2130 Leading and trailing white spaces are ignored around property names and
2131 values.
2132
2133 Regular expressions
2134 The value of some properties might be a regular expression. In that
2135 case, they must comply with the syntax of extended POSIX regular
2136 expressions. Note that Libabigail uses the regular expression engine
2137 of the GNU C Library.
2138
2139 Escaping a character in a regular expression
2140 When trying to match a string that contains a * character, like in the
2141 pointer type int*, one must be careful to notice that the character *
2142 is a special character in the extended POSIX regular expression syntax.
2143 And that character must be escaped for the regular expression engine.
2144 Thus the regular expression that would match the string int* in a sup‐
2145 pression file should be
2146
2147 int\\*
2148
2149 Wait; but then why the two \ characters? Well, because the \ character
2150 is a special character in the Ini File Syntax used for specifying sup‐
2151 pressions. So it must be escaped as well, so that the Ini File parser
2152 leaves a \ character intact in the data stream that is handed to the
2153 regular expression engine. Hence the \\ targeted at the Ini File
2154 parser.
2155
2156 So, in short, to escape a character in a regular expression, always
2157 prefix the character with the \\ sequence.
2158
2159 Modus operandi
2160 Suppression specifications can be applied at two different points of
2161 the processing pipeline of libabigail.
2162
2163 In the default operating mode called “late suppression mode”, suppres‐
2164 sion specifications are applied to the result of comparing the in-mem‐
2165 ory internal representations of two ABIs. In this mode, if an ABI
2166 artifact matches a suppression specification, its changes are not men‐
2167 tioned in the ABI change report. The internal representation of the
2168 “suppressed” changed ABI artifact is still present in memory; it is
2169 just not mentioned in the ABI change report. The change report can
2170 still mention statistics about the number of changed ABI artifacts that
2171 were suppressed.
2172
2173 There is another operating mode called the “early suppression mode”
2174 where suppression specifications are applied during the construction of
2175 the in-memory internal representation of a given ABI. In that mode, if
2176 an ABI artifact matches a suppression specification, no in-memory
2177 internal representation is built for it. As a result, no change about
2178 the matched ABI artifact is going to be mentioned in the ABI change
2179 report and no statistic about the number of suppressed ABI changes is
2180 available. Also, please note that because suppressed ABI artifacts are
2181 removed from the in-memory internal representation in this mode, the
2182 amount memory used by the internal representation is potentially
2183 smaller than the memory consumption in the late suppression mode.
2184
2185 Sections
2186 Properties are then grouped into arbitrarily named sections that shall
2187 not be nested. The name of the section is on a line by itself and is
2188 surrounded by square brackets, i.e:
2189
2190 [section_name]
2191 property1_name = property1_value
2192 property2_name = property2_value
2193
2194 A section might or might not have properties. Sections that expect to
2195 have properties and which are found nonetheless empty are just ignored.
2196 Properties that are not recognized by the reader are ignored as well.
2197
2198 Section names
2199 Each different section can be thought of as being a directive to sup‐
2200 press ABI change reports for a particular kind of ABI artifact.
2201
2202 [suppress_file]
2203 This directive prevents a given tool from loading a file (binary or
2204 abixml file) if its file name or other properties match certain proper‐
2205 ties. Thus, if the tool is meant to compare the ABIs of two files, and
2206 if the directive prevents it from loading either one of the files, then
2207 no comparison is performed.
2208
2209 Note that for the [suppress_file] directive to work, at least one of
2210 the following properties must be provided:
2211 file_name_regexp, file_name_not_regexp.
2212
2213 The potential properties of this sections are listed below:
2214
2215 · file_name_regexp
2216
2217 Usage:
2218 file_name_regexp = <regular-expression>
2219
2220 Prevents the system from loading the file which name matches the reg‐
2221 ular expression specified as value of this property.
2222
2223 · file_name_not_regexp
2224
2225 Usage:
2226 file_name_not_regexp = <regular-expression>
2227
2228 Prevents the system from loading the file which name does not match
2229 the regular expression specified as value of this property.
2230
2231 · soname_regexp
2232
2233 Usage:
2234 soname_regexp = <regular-expression>
2235
2236 Prevents the system from loading the file which contains a SONAME
2237 property that matches the regular expression of this property. Note
2238 that this property also works on an abixml file if it contains a SON‐
2239 AME property.
2240
2241 · soname_not_regexp
2242
2243 Usage:
2244 soname_not_regexp = <regular-expression>
2245
2246 Prevents the system from loading the file which contains a SONAME
2247 property that does NOT match the regular expression of this property.
2248 Note that this property also works on an abixml file if it contains a
2249 SONAME property.
2250
2251 · label
2252 Usage:
2253 label = <some-value>
2254
2255 Define a label for the section. A label is just an informative
2256 string that might be used by the tool to refer to a type suppression
2257 in error messages.
2258
2259 [suppress_type]
2260 This directive suppresses report messages about a type change.
2261
2262 Note that for the [suppress_type] directive to work, at least one of
2263 the following properties must be provided:
2264 file_name_regexp, file_name_not_regexp, soname_regexp, son‐
2265 ame_not_regexp, name, name_regexp, name_not_regexp, type_kind,
2266 source_location_not_in, source_location_not_regexp.
2267
2268 If none of the following properties are provided, then the [sup‐
2269 press_type] directive is simply ignored.
2270
2271 The potential properties of this sections are listed below:
2272
2273 · file_name_regexp
2274
2275 Usage:
2276 file_name_regexp = <regular-expression>
2277
2278 Suppresses change reports about ABI artifacts that are defined in a
2279 binary file which name matches the regular expression specified as
2280 value of this property.
2281
2282 · file_name_not_regexp
2283
2284 Usage:
2285 file_name_not_regexp = <regular-expression>
2286
2287 Suppresses change reports about ABI artifacts that are defined in a
2288 binary file which name does not match the regular expression speci‐
2289 fied as value of this property.
2290
2291 · soname_regexp
2292
2293 Usage:
2294 soname_regexp = <regular-expression>
2295
2296 Suppresses change reports about ABI artifacts that are defined in a
2297 shared library which SONAME property matches the regular expression
2298 specified as value of this property.
2299
2300 · soname_not_regexp
2301
2302 Usage:
2303 soname_not_regexp = <regular-expression>
2304
2305 Suppresses change reports about ABI artifacts that are defined in a
2306 shared library which SONAME property does not match the regular
2307 expression specified as value of this property.
2308
2309 · name_regexp
2310 Usage:
2311 name_regexp = <regular-expression>
2312
2313 Suppresses change reports involving types whose name matches the
2314 regular expression specified as value of this property.
2315
2316 · name_not_regexp
2317 Usage:
2318 name_not_regexp = <regular-expression>
2319
2320 Suppresses change reports involving types whose name does NOT match
2321 the regular expression specified as value of this property. Said
2322 otherwise, this property specifies which types to keep, rather than
2323 types to suppress from reports.
2324
2325 · name
2326 Usage:
2327 name = <a-value>
2328
2329 Suppresses change reports involving types whose name equals the
2330 value of this property.
2331
2332 · type_kind
2333 Usage:
2334
2335 type_kind = class | struct | union | enum |
2336 array | typedef | builtin
2337
2338 Suppresses change reports involving a certain kind of type. The
2339 kind of type to suppress change reports for is specified by the pos‐
2340 sible values listed above:
2341
2342 ·
2343
2344 class: suppress change reports for class types. Note that
2345 even if class types don’t exist for C, this value still
2346 triggers the suppression of change reports for struct
2347 types, in C. In C++ however, it should do what it sug‐
2348 gests.
2349
2350 ·
2351
2352 struct: suppress change reports for struct types in C or C++.
2353 Note that the value class above is a super-set of this
2354 one.
2355
2356 · union: suppress change reports for union types.
2357
2358 · enum: suppress change reports for enum types.
2359
2360 · array: suppress change reports for array types.
2361
2362 · typedef: suppress change reports for typedef types.
2363
2364 · builtin: suppress change reports for built-in (or native)
2365 types. Example of built-in types are char, int, unsigned int,
2366 etc.
2367
2368 · source_location_not_in
2369 Usage:
2370 source_location_not_in = <list-of-file-paths>
2371
2372 Suppresses change reports involving a type which is defined in a
2373 file which path is NOT listed in the value list-of-file-paths. Note
2374 that the value is a comma-separated list of file paths e.g, this
2375 property
2376
2377 source_location_not_in = libabigail/abg-ir.h, libabigail/abg-dwarf-reader.h
2378
2379 suppresses change reports about all the types that are NOT defined
2380 in header files whose path end up with the strings libabi‐
2381 gail/abg-ir.h or libabigail/abg-dwarf-reader.h.
2382
2383 · source_location_not_regexp
2384 Usage:
2385 source_location_not_regexp = <regular-expression>
2386
2387 Suppresses change reports involving a type which is defined in a
2388 file which path does NOT match the regular expression provided as
2389 value of the property. E.g, this property
2390
2391 source_location_not_regexp = libabigail/abg-.*\\.h
2392
2393 suppresses change reports involving all the types that are NOT
2394 defined in header files whose path match the regular expression pro‐
2395 vided a value of the property.
2396
2397 · has_data_member_inserted_at
2398 Usage:
2399 has_data_member_inserted_at = <offset-in-bit>
2400
2401 Suppresses change reports involving a type which has at least one
2402 data member inserted at an offset specified by the property value
2403 offset-in-bit. The value offset-in-bit is either:
2404
2405 · an integer value, expressed in bits, which denotes the off‐
2406 set of the insertion point of the data member, starting
2407 from the beginning of the relevant structure or class.
2408
2409 · the keyword end which is a named constant which value
2410 equals the offset of the end of the of the structure or
2411 class.
2412
2413 · the function call expression offset_of(data-member-name)
2414 where data-member-name is the name of a given data member
2415 of the relevant structure or class. The value of this
2416 function call expression is an integer that represents the
2417 offset of the data member denoted by data-member-name.
2418
2419 · the function call expression offset_after(data-member-name)
2420 where data-member-name is the name of a given data member
2421 of the relevant structure or class. The value of this
2422 function call expression is an integer that represents the
2423 offset of the point that comes right after the region occu‐
2424 pied by the data member denoted by data-member-name.
2425
2426 · has_data_member_inserted_between
2427 Usage:
2428 has_data_member_inserted_between = {<range-begin>, <range-end>}
2429
2430 Suppresses change reports involving a type which has at least one
2431 data mber inserted at an offset that is comprised in the range
2432 between range-begin`` and range-end. Please note that each of the
2433 lues range-begin and range-end can be of the same form as the
2434 has_data_member_inserted_at property above.
2435
2436 Usage examples of this properties are:
2437
2438 has_data_member_inserted_between = {8, 64}
2439
2440 or:
2441
2442 has_data_member_inserted_between = {16, end}
2443
2444 or:
2445
2446 has_data_member_inserted_between = {offset_after(member1), end}
2447
2448 · has_data_members_inserted_between
2449 Usage:
2450 has_data_members_inserted_between = {<sequence-of-ranges>}
2451
2452 Suppresses change reports involving a type which has multiple data
2453 member inserted in various offset ranges. A usage example of this
2454 property is, for instance:
2455
2456 has_data_members_inserted_between = {{8, 31}, {72, 95}}
2457
2458 This usage example suppresses change reports involving a type which
2459 has data members inserted in bit offset ranges [8 31] and [72 95].
2460 The length of the sequence of ranges or this has_data_mem‐
2461 bers_inserted_between is not bounded; it can be as long as the sys‐
2462 tem can cope with. The values of the boundaries of the ranges are
2463 of the same kind as for the has_data_member_inserted_at property
2464 above.
2465
2466 Another usage example of this property is thus:
2467
2468 has_data_members_inserted_between =
2469 {
2470 {offset_after(member0), offset_of(member1)},
2471 {72, end}
2472 }
2473
2474 · accessed_through
2475 Usage:
2476 accessed_through = <some-predefined-values>
2477
2478 Suppress change reports involving a type which is referred to either
2479 directly or through a pointer or a reference. The potential values
2480 of this property are the predefined keywords below:
2481
2482 · direct
2483
2484 So if the [suppress_type] contains the property description:
2485
2486 accessed_through = direct
2487
2488 then changes about a type that is referred-to directly (i.e,
2489 not through a pointer or a reference) are going to be sup‐
2490 pressed.
2491
2492 · pointer
2493
2494 If the accessed_through property is set to the value pointer
2495 then changes about a type that is referred-to through a
2496 pointer are going to be suppressed.
2497
2498 · reference
2499
2500 If the accessed_through property is set to the value reference
2501 then changes about a type that is referred-to through a refer‐
2502 ence are going to be suppressed.
2503
2504 · reference-or-pointer
2505
2506 If the accessed_through property is set to the value refer‐
2507 ence-or-pointer then changes about a type that is referred-to
2508 through either a reference or a pointer are going to be sup‐
2509 pressed.
2510
2511 For an extensive example of how to use this property, please check
2512 out the example below about suppressing change reports about types
2513 accessed either directly or through pointers.
2514
2515 · drop
2516 Usage:
2517 drop = yes | no
2518
2519 If a type is matched by a suppression specification which contains
2520 the “drop” property set to “yes” (or to “true”) then the type is not
2521 even going to be represented in the internal representation of the
2522 ABI being analyzed. This property makes its enclosing suppression
2523 specification to be applied in the early suppression specification
2524 mode. The net effect is that it potentially reduces the memory used
2525 to represent the ABI being analyzed.
2526
2527 Please note that for this property to be effective, the enclosing
2528 suppression specification must have at least one of the following
2529 properties specified: name_regexp, name, name_regexp, source_loca‐
2530 tion_not_in or source_location_not_regexp.
2531
2532 · label
2533 Usage:
2534 label = <some-value>
2535
2536 Define a label for the section. A label is just an informative
2537 string that might be used by a tool to refer to a type suppression
2538 in error messages.
2539
2540 · changed_enumerators
2541
2542 Usage:
2543 changed_enumerators = <list-of-enumerators>
2544
2545 Suppresses change reports involving changes in the value of enumera‐
2546 tors of a given enum type. This property is applied if the type_kind
2547 property is set to the value enum, at least. The value of the
2548 changed_enumerators is a comma-separated list of the enumerators that
2549 the user expects to change. For instance:
2550
2551 changed_enumerators = LAST_ENUMERATORS0, LAST_ENUMERATOR1
2552
2553 [suppress_function]
2554 This directive suppresses report messages about changes on a set of
2555 functions.
2556
2557 Note that for the [suppress_function] directive to work, at least one
2558 of the following properties must be provided:
2559 label, file_name_regexp, file_name_not_regexp, soname_regexp, son‐
2560 ame_not_regexp, name, name_regexp, name_not_regexp, parameter,
2561 return_type_name, symbol_name, symbol_name_regexp, sym‐
2562 bol_name_not_regexp,``symbol_version``, symbol_version_regexp.
2563
2564 If none of the following properties are provided, then the [sup‐
2565 press_function] directive is simply ignored.
2566
2567 The potential properties of this sections are:
2568
2569 · label
2570 Usage:
2571 label = <some-value>
2572
2573 This property is the same as the label property defined above.
2574
2575 · file_name_regexp
2576
2577 Usage:
2578
2579 file_name_regexp = <regular-expression>
2580
2581 Suppresses change reports about ABI artifacts that are defined in a
2582 binary file which name matches the regular expression specified as
2583 value of this property.
2584
2585 · file_name_not_regexp
2586
2587 Usage:
2588 file_name_not_regexp = <regular-expression>
2589
2590 Suppresses change reports about ABI artifacts that are defined in a
2591 binary file which name does not match the regular expression speci‐
2592 fied as value of this property.
2593
2594 · soname_regexp
2595
2596 Usage:
2597 soname_regexp = <regular-expression>
2598
2599 Suppresses change reports about ABI artifacts that are defined in a
2600 shared library which SONAME property matches the regular expression
2601 specified as value of this property.
2602
2603 · soname_not_regexp
2604
2605 Usage:
2606 soname_not_regexp = <regular-expression>
2607
2608 Suppresses change reports about ABI artifacts that are defined in a
2609 shared library which SONAME property does not match the regular
2610 expression specified as value of this property.
2611
2612 · name
2613 Usage:
2614 name = <some-value>
2615
2616 Suppresses change reports involving functions whose name equals the
2617 value of this property.
2618
2619 · name_regexp
2620 Usage:
2621 name_regexp = <regular-expression>
2622
2623 Suppresses change reports involving functions whose name matches the
2624 regular expression specified as value of this property.
2625
2626 Let’s consider the case of functions that have several symbol names.
2627 This happens when the underlying symbol for the function has
2628 aliases. Each symbol name is actually one alias name.
2629
2630 In this case, if the regular expression matches the name of at least
2631 one of the aliases names, then it must match the names of all of the
2632 aliases of the function for the directive to actually suppress the
2633 diff reports for said function.
2634
2635 · name_not_regexp
2636 Usage:
2637 name_not_regexp = <regular-expression>
2638
2639 Suppresses change reports involving functions whose names don’t
2640 match the regular expression specified as value of this property.
2641
2642 The rules for functions that have several symbol names are the same
2643 rules as for the name_regexp property above.
2644
2645 · change_kind
2646 Usage:
2647 change_kind = <predefined-possible-values>
2648
2649 Specifies the kind of changes this suppression specification should
2650 apply to. The possible values of this property as well as their
2651 meaning are listed below:
2652
2653 · function-subtype-change
2654
2655 This suppression specification applies to functions that which
2656 have at least one sub-type that has changed.
2657
2658 · added-function
2659
2660 This suppression specification applies to functions that have
2661 been added to the binary.
2662
2663 · deleted-function
2664
2665 This suppression specification applies to functions that have
2666 been removed from the binary.
2667
2668 · all
2669
2670 This suppression specification applies to functions that have
2671 all of the changes above. Note that not providing the
2672 change_kind property at all is equivalent to setting it to the
2673 value all.
2674
2675 · parameter
2676 Usage:
2677 parameter = <function-parameter-specification>
2678
2679 Suppresses change reports involving functions whose parameters match
2680 the parameter specification indicated as value of this property.
2681
2682 The format of the function parameter specification is:
2683
2684 ' <parameter-index> <space> <type-name-or-regular-expression>
2685
2686 That is, an apostrophe followed by a number that is the index of the
2687 parameter, followed by one of several spaces, followed by either the
2688 name of the type of the parameter, or a regular expression describ‐
2689 ing a family of parameter type names.
2690
2691 If the parameter type name is designated by a regular expression,
2692 then said regular expression must be enclosed between two slashes;
2693 like /some-regular-expression/.
2694
2695 The index of the first parameter of the function is zero. Note that
2696 for member functions (methods of classes), the this is the first
2697 parameter that comes after the implicit “this” pointer parameter.
2698
2699 Examples of function parameter specifications are:
2700
2701 '0 int
2702
2703 Which means, the parameter at index 0, whose type name is int.
2704
2705 '4 unsigned char*
2706
2707 Which means, the parameter at index 4, whose type name is unsigned
2708 char*.
2709
2710 '2 /^foo.*&/
2711
2712 Which means, the parameter at index 2, whose type name starts with
2713 the string “foo” and ends with an ‘&’. In other words, this is the
2714 third parameter and it’s a reference on a type that starts with the
2715 string “foo”.
2716
2717 · return_type_name
2718 Usage:
2719 return_type_name = <some-value>
2720
2721 Suppresses change reports involving functions whose return type name
2722 equals the value of this property.
2723
2724 · return_type_regexp
2725 Usage:
2726 return_type_regexp = <regular-expression>
2727
2728 Suppresses change reports involving functions whose return type name
2729 matches the regular expression specified as value of this property.
2730
2731 · symbol_name
2732 Usage:
2733 symbol_name = <some-value>
2734
2735 Suppresses change reports involving functions whose symbol name
2736 equals the value of this property.
2737
2738 · symbol_name_regexp
2739 Usage:
2740 symbol_name_regexp = <regular-expression>
2741
2742 Suppresses change reports involving functions whose symbol name
2743 matches the regular expression specified as value of this property.
2744
2745 Let’s consider the case of functions that have several symbol names.
2746 This happens when the underlying symbol for the function has
2747 aliases. Each symbol name is actually one alias name.
2748
2749 In this case, the regular expression must match the names of all of
2750 the aliases of the function for the directive to actually suppress
2751 the diff reports for said function.
2752
2753 · symbol_name_not_regexp
2754 Usage:
2755 symbol_name_not_regexp = <regular-expression>
2756
2757 Suppresses change reports involving functions whose symbol name does
2758 not match the regular expression specified as value of this prop‐
2759 erty.
2760
2761 · symbol_version
2762 Usage:
2763 symbol_version = <some-value>
2764
2765 Suppresses change reports involving functions whose symbol version
2766 equals the value of this property.
2767
2768 · symbol_version_regexp
2769 Usage:
2770 symbol_version_regexp = <regular-expression>
2771
2772 Suppresses change reports involving functions whose symbol version
2773 matches the regular expression specified as value of this property.
2774
2775 · drop
2776 Usage:
2777 drop = yes | no
2778
2779 If a function is matched by a suppression specification which con‐
2780 tains the “drop” property set to “yes” (or to “true”) then the func‐
2781 tion is not even going to be represented in the internal representa‐
2782 tion of the ABI being analyzed. This property makes its enclosing
2783 suppression specification to be applied in the early suppression
2784 specification mode. The net effect is that it potentially reduces
2785 the memory used to represent the ABI being analyzed.
2786
2787 Please note that for this property to be effective, the enclosing
2788 suppression specification must have at least one of the following
2789 properties specified: name_regexp, name, name_regexp, source_loca‐
2790 tion_not_in or source_location_not_regexp.
2791
2792 [suppress_variable]
2793 This directive suppresses report messages about changes on a set of
2794 variables.
2795
2796 Note that for the [suppress_variable] directive to work, at least one
2797 of the following properties must be provided:
2798 label, file_name_regexp, file_name_not_regexp, soname_regexp, son‐
2799 ame_not_regexp, name, name_regexp, symbol_name, symbol_name_regexp,
2800 symbol_name_not_regexp, symbol_version, symbol_version_regexp.
2801
2802 If none of the following properties are provided, then the [sup‐
2803 pres_variable] directive is simply ignored.
2804
2805 The potential properties of this sections are:
2806
2807 · label
2808 Usage:
2809 label = <some-value>
2810
2811 This property is the same as the label property defined above.
2812
2813 · file_name_regexp
2814
2815 Usage:
2816
2817 file_name_regexp = <regular-expression>
2818
2819 Suppresses change reports about ABI artifacts that are defined in a
2820 binary file which name matches the regular expression specified as
2821 value of this property.
2822
2823 · file_name_not_regexp
2824
2825 Usage:
2826 file_name_not_regexp = <regular-expression>
2827
2828 Suppresses change reports about ABI artifacts that are defined in a
2829 binary file which name does not match the regular expression speci‐
2830 fied as value of this property.
2831
2832 · soname_regexp
2833
2834 Usage:
2835 soname_regexp = <regular-expression>
2836
2837 Suppresses change reports about ABI artifacts that are defined in a
2838 shared library which SONAME property matches the regular expression
2839 specified as value of this property.
2840
2841 · soname_not_regexp
2842
2843 Usage:
2844 soname_not_regexp = <regular-expression>
2845
2846 Suppresses change reports about ABI artifacts that are defined in a
2847 shared library which SONAME property does not match the regular
2848 expression specified as value of this property.
2849
2850 · name
2851 Usage:
2852 name = <some-value>
2853
2854 Suppresses change reports involving variables whose name equals the
2855 value of this property.
2856
2857 · name_regexp
2858 Usage:
2859 name_regexp = <regular-expression>
2860
2861 Suppresses change reports involving variables whose name matches the
2862 regular expression specified as value of this property.
2863
2864 · change_kind
2865 Usage:
2866 change_kind = <predefined-possible-values>
2867
2868 Specifies the kind of changes this suppression specification should
2869 apply to. The possible values of this property as well as their
2870 meaning are the same as when it’s used in the [suppress_function]
2871 section.
2872
2873 · symbol_name
2874 Usage:
2875 symbol_name = <some-value>
2876
2877 Suppresses change reports involving variables whose symbol name
2878 equals the value of this property.
2879
2880 · symbol_name_regexp
2881 Usage:
2882 symbol_name_regexp = <regular-expression>
2883
2884 Suppresses change reports involving variables whose symbol name
2885 matches the regular expression specified as value of this property.
2886
2887 · symbol_name_not_regexp
2888 Usage:
2889 symbol_name_not_regexp = <regular-expression>
2890
2891 Suppresses change reports involving variables whose symbol name does
2892 not match the regular expression specified as value of this prop‐
2893 erty.
2894
2895 · symbol_version
2896 Usage:
2897 symbol_version = <some-value>
2898
2899 Suppresses change reports involving variables whose symbol version
2900 equals the value of this property.
2901
2902 · symbol_version_regexp
2903 Usage:
2904 symbol_version_regexp = <regular-expression>
2905
2906 Suppresses change reports involving variables whose symbol version
2907 matches the regular expression specified as value of this property.
2908
2909 · type_name
2910 Usage:
2911 type_name = <some-value>
2912
2913 Suppresses change reports involving variables whose type name equals
2914 the value of this property.
2915
2916 · type_name_regexp
2917 Usage:
2918 type_name_regexp = <regular-expression>
2919
2920 Suppresses change reports involving variables whose type name
2921 matches the regular expression specified as value of this property.
2922
2923 Comments
2924 ; or # ASCII character at the beginning of a line indicates a comment.
2925 Comment lines are ignored.
2926
2927 Code examples
2928 1. Suppressing change reports about types.
2929
2930 Suppose we have a library named libtest1-v0.so which contains this
2931 very useful code:
2932
2933 $ cat -n test1-v0.cc
2934 1 // A forward declaration for a type considered to be opaque to
2935 2 // function foo() below.
2936 3 struct opaque_type;
2937 4
2938 5 // This function cannot touch any member of opaque_type. Hence,
2939 6 // changes to members of opaque_type should not impact foo, as far as
2940 7 // ABI is concerned.
2941 8 void
2942 9 foo(opaque_type*)
2943 10 {
2944 11 }
2945 12
2946 13 struct opaque_type
2947 14 {
2948 15 int member0;
2949 16 char member1;
2950 17 };
2951 $
2952
2953 Let’s change the layout of struct opaque_type by inserting a data mem‐
2954 ber around line 15, leading to a new version of the library, that we
2955 shall name libtest1-v1.so:
2956
2957 $ cat -n test1-v1.cc
2958 1 // A forward declaration for a type considered to be opaque to
2959 2 // function foo() below.
2960 3 struct opaque_type;
2961 4
2962 5 // This function cannot touch any member of opaque_type; Hence,
2963 6 // changes to members of opaque_type should not impact foo, as far as
2964 7 // ABI is concerned.
2965 8 void
2966 9 foo(opaque_type*)
2967 10 {
2968 11 }
2969 12
2970 13 struct opaque_type
2971 14 {
2972 15 char added_member; // <-- a new member got added here now.
2973 16 int member0;
2974 17 char member1;
2975 18 };
2976 $
2977
2978 Let’s compile both examples. We shall not forget to compile them with
2979 debug information generation turned on:
2980
2981 $ g++ -shared -g -Wall -o libtest1-v0.so test1-v0.cc
2982 $ g++ -shared -g -Wall -o libtest1-v1.so test1-v1.cc
2983
2984 Let’s ask abidiff which ABI differences it sees between libtest1-v0.so
2985 and libtest1-v1.so:
2986
2987 $ abidiff libtest1-v0.so libtest1-v1.so
2988 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
2989 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
2990
2991 1 function with some indirect sub-type change:
2992
2993 [C]'function void foo(opaque_type*)' has some indirect sub-type changes:
2994 parameter 0 of type 'opaque_type*' has sub-type changes:
2995 in pointed to type 'struct opaque_type':
2996 size changed from 64 to 96 bits
2997 1 data member insertion:
2998 'char opaque_type::added_member', at offset 0 (in bits)
2999 2 data member changes:
3000 'int opaque_type::member0' offset changed from 0 to 32
3001 'char opaque_type::member1' offset changed from 32 to 64
3002
3003 So abidiff reports that the opaque_type’s layout has changed in a sig‐
3004 nificant way, as far as ABI implications are concerned, in theory.
3005 After all, a sub-type (struct opaque_type) of an exported function
3006 (foo()) has seen its layout change. This might have non negligible ABI
3007 implications. But in practice here, the programmer of the
3008 litest1-v1.so library knows that the “soft” contract between the func‐
3009 tion foo() and the type struct opaque_type is to stay away from the
3010 data members of the type. So layout changes of struct opaque_type
3011 should not impact foo().
3012
3013 Now to teach abidiff about this soft contract and have it avoid emit‐
3014 ting what amounts to false positives in this case, we write the sup‐
3015 pression specification file below:
3016
3017 $ cat test1.suppr
3018 [suppress_type]
3019 type_kind = struct
3020 name = opaque_type
3021
3022 Translated in plain English, this suppression specification would read:
3023 “Do not emit change reports about a struct which name is opaque_type”.
3024
3025 Let’s now invoke abidiff on the two versions of the library again, but
3026 this time with the suppression specification:
3027
3028 $ abidiff --suppressions test1.suppr libtest1-v0.so libtest1-v1.so
3029 Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
3030 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
3031
3032 As you can see, abidiff does not report the change anymore; it tells us
3033 that it was filtered out instead.
3034
3035 Suppressing change reports about types with data member insertions
3036
3037 Suppose the first version of a library named libtest3-v0.so has this
3038 source code:
3039
3040 /* Compile this with:
3041 gcc -g -Wall -shared -o libtest3-v0.so test3-v0.c
3042 */
3043
3044 struct S
3045 {
3046 char member0;
3047 int member1; /*
3048 between member1 and member2, there is some padding,
3049 at least on some popular platforms. On
3050 these platforms, adding a small enough data
3051 member into that padding shouldn't change
3052 the offset of member1. Right?
3053 */
3054 };
3055
3056 int
3057 foo(struct S* s)
3058 {
3059 return s->member0 + s->member1;
3060 }
3061
3062 Now, suppose the second version of the library named libtest3-v1.so has
3063 this source code in which a data member has been added in the padding
3064 space of struct S and another data member has been added at its end:
3065
3066 /* Compile this with:
3067 gcc -g -Wall -shared -o libtest3-v1.so test3-v1.c
3068 */
3069
3070 struct S
3071 {
3072 char member0;
3073 char inserted1; /* <---- A data member has been added here... */
3074 int member1;
3075 char inserted2; /* <---- ... and another one has been added here. */
3076 };
3077
3078 int
3079 foo(struct S* s)
3080 {
3081 return s->member0 + s->member1;
3082 }
3083
3084 In libtest3-v1.so, adding char data members S::inserted1 and
3085 S::inserted2 can be considered harmless (from an ABI compatibility per‐
3086 spective), at least on the x86 platform, because that doesn’t change
3087 the offsets of the data members S::member0 and S::member1. But then
3088 running abidiff on these two versions of library yields:
3089
3090 $ abidiff libtest3-v0.so libtest3-v1.so
3091 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
3092 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
3093
3094 1 function with some indirect sub-type change:
3095
3096 [C]'function int foo(S*)' has some indirect sub-type changes:
3097 parameter 0 of type 'S*' has sub-type changes:
3098 in pointed to type 'struct S':
3099 type size changed from 64 to 96 bits
3100 2 data member insertions:
3101 'char S::inserted1', at offset 8 (in bits)
3102 'char S::inserted2', at offset 64 (in bits)
3103 $
3104
3105 That is, abidiff shows us the two changes, even though we (the develop‐
3106 ers of that very involved library) know that these changes are harmless
3107 in this particular context.
3108
3109 Luckily, we can devise a suppression specification that essentially
3110 tells abidiff to filter out change reports about adding a data member
3111 between S::member0 and S::member1, and adding a data member at the end
3112 of struct S. We have written such a suppression specification in a
3113 file called test3-1.suppr and it unsurprisingly looks like:
3114
3115 [suppress_type]
3116 name = S
3117 has_data_member_inserted_between = {offset_after(member0), offset_of(member1)}
3118 has_data_member_inserted_at = end
3119
3120 Now running abidiff with this suppression specification yields:
3121
3122 $ ../build/tools/abidiff --suppressions test3-1.suppr libtest3-v0.so libtest3-v1.so
3123 Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
3124 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
3125
3126 $
3127
3128 Hooora! \o/ (I guess)
3129
3130 Suppressing change reports about types accessed either directly or
3131 through pointers
3132
3133 Suppose we have a first version of an object file which source code is
3134 the file widget-v0.cc below:
3135
3136 // Compile with: g++ -g -c widget-v0.cc
3137
3138 struct widget
3139 {
3140 int x;
3141 int y;
3142
3143 widget()
3144 :x(), y()
3145 {}
3146 };
3147
3148 void
3149 fun0(widget*)
3150 {
3151 // .. do stuff here.
3152 }
3153
3154 void
3155 fun1(widget&)
3156 {
3157 // .. do stuff here ..
3158 }
3159
3160 void
3161 fun2(widget w)
3162 {
3163 // ... do other stuff here ...
3164 }
3165
3166 Now suppose in the second version of that file, named widget-v1.cc, we
3167 have added some data members at the end of the type struct widget; here
3168 is what the content of that file would look like:
3169
3170 // Compile with: g++ -g -c widget-v1.cc
3171
3172 struct widget
3173 {
3174 int x;
3175 int y;
3176 int w; // We have added these two new data members here ..
3177 int h; // ... and here.
3178
3179 widget()
3180 : x(), y(), w(), h()
3181 {}
3182 };
3183
3184 void
3185 fun0(widget*)
3186 {
3187 // .. do stuff here.
3188 }
3189
3190 void
3191 fun1(widget&)
3192 {
3193 // .. do stuff here ..
3194 }
3195
3196 void
3197 fun2(widget w)
3198 {
3199 // ... do other stuff here ...
3200 }
3201
3202 When we invoke abidiff on the object files resulting from the compila‐
3203 tion of the two file above, here is what we get:
3204
3205 $ abidiff widget-v0.o widget-v1.o
3206 Functions changes summary: 0 Removed, 2 Changed (1 filtered out), 0 Added functions
3207 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
3208
3209 2 functions with some indirect sub-type change:
3210
3211 [C]'function void fun0(widget*)' has some indirect sub-type changes:
3212 parameter 1 of type 'widget*' has sub-type changes:
3213 in pointed to type 'struct widget':
3214 type size changed from 64 to 128 bits
3215 2 data member insertions:
3216 'int widget::w', at offset 64 (in bits)
3217 'int widget::h', at offset 96 (in bits)
3218
3219 [C]'function void fun2(widget)' has some indirect sub-type changes:
3220 parameter 1 of type 'struct widget' has sub-type changes:
3221 details were reported earlier
3222 $
3223
3224 I guess a little bit of explaining is due here. abidiff detects that
3225 two data member got added at the end of struct widget. it also tells
3226 us that the type change impacts the exported function fun0() which uses
3227 the type struct widget through a pointer, in its signature.
3228
3229 Careful readers will notice that the change to struct widget also
3230 impacts the exported function fun1(), that uses type struct widget
3231 through a reference. But then abidiff doesn’t tell us about the impact
3232 on that function fun1() because it has evaluated that change as being
3233 redundant with the change it reported on fun0(). It has thus filtered
3234 it out, to avoid cluttering the output with noise.
3235
3236 Redundancy detection and filtering is fine and helpful to avoid burying
3237 the important information in a sea of noise. However, it must be
3238 treated with care, by fear of mistakenly filtering out relevant and
3239 important information.
3240
3241 That is why abidiff tells us about the impact that the change to struct
3242 widget has on function fun2(). In this case, that function uses the
3243 type struct widget directly (in its signature). It does not use it via
3244 a pointer or a reference. In this case, the direct use of this type
3245 causes fun2() to be exposed to a potentially harmful ABI change.
3246 Hence, the report about fun2() is not filtered out, even though it’s
3247 about that same change on struct widget.
3248
3249 To go further in suppressing reports about changes that are harmless
3250 and keeping only those that we know are harmful, we would like to go
3251 tell abidiff to suppress reports about this particular struct widget
3252 change when it impacts uses of struct widget through a pointer or ref‐
3253 erence. In other words, suppress the change reports about fun0() and
3254 fun1(). We would then write this suppression specification, in file
3255 widget.suppr:
3256
3257 [suppress_type]
3258 name = widget
3259 type_kind = struct
3260 has_data_member_inserted_at = end
3261 accessed_through = reference-or-pointer
3262
3263 # So this suppression specification says to suppress reports about
3264 # the type 'struct widget', if this type was added some data member
3265 # at its end, and if the change impacts uses of the type through a
3266 # reference or a pointer.
3267
3268 Invoking abidiff on widget-v0.o and widget-v1.o with this suppression
3269 specification yields:
3270
3271 $ abidiff --suppressions widget.suppr widget-v0.o widget-v1.o
3272 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
3273 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
3274
3275 1 function with some indirect sub-type change:
3276
3277 [C]'function void fun2(widget)' has some indirect sub-type changes:
3278 parameter 1 of type 'struct widget' has sub-type changes:
3279 type size changed from 64 to 128 bits
3280 2 data member insertions:
3281 'int widget::w', at offset 64 (in bits)
3282 'int widget::h', at offset 96 (in bits)
3283 $
3284
3285 As expected, I guess.
3286
3287 Suppressing change reports about functions.
3288
3289 Suppose we have a first version a library named libtest2-v0.so whose
3290 source code is:
3291
3292 $ cat -n test2-v0.cc
3293
3294 1 struct S1
3295 2 {
3296 3 int m0;
3297 4
3298 5 S1()
3299 6 : m0()
3300 7 {}
3301 8 };
3302 9
3303 10 struct S2
3304 11 {
3305 12 int m0;
3306 13
3307 14 S2()
3308 15 : m0()
3309 16 {}
3310 17 };
3311 18
3312 19 struct S3
3313 20 {
3314 21 int m0;
3315 22
3316 23 S3()
3317 24 : m0()
3318 25 {}
3319 26 };
3320 27
3321 28 int
3322 29 func(S1&)
3323 30 {
3324 31 // suppose the code does something with the argument.
3325 32 return 0;
3326 33
3327 34 }
3328 35
3329 36 char
3330 37 func(S2*)
3331 38 {
3332 39 // suppose the code does something with the argument.
3333 40 return 0;
3334 41 }
3335 42
3336 43 unsigned
3337 44 func(S3)
3338 45 {
3339 46 // suppose the code does something with the argument.
3340 47 return 0;
3341 48 }
3342 $
3343
3344 And then we come up with a second version libtest2-v1.so of that
3345 library; the source code is modified by making the structures S1, S2,
3346 S3 inherit another struct:
3347
3348 $ cat -n test2-v1.cc
3349 1 struct base_type
3350 2 {
3351 3 int m_inserted;
3352 4 };
3353 5
3354 6 struct S1 : public base_type // <--- S1 now has base_type as its base
3355 7 // type.
3356 8 {
3357 9 int m0;
3358 10
3359 11 S1()
3360 12 : m0()
3361 13 {}
3362 14 };
3363 15
3364 16 struct S2 : public base_type // <--- S2 now has base_type as its base
3365 17 // type.
3366 18 {
3367 19 int m0;
3368 20
3369 21 S2()
3370 22 : m0()
3371 23 {}
3372 24 };
3373 25
3374 26 struct S3 : public base_type // <--- S3 now has base_type as its base
3375 27 // type.
3376 28 {
3377 29 int m0;
3378 30
3379 31 S3()
3380 32 : m0()
3381 33 {}
3382 34 };
3383 35
3384 36 int
3385 37 func(S1&)
3386 38 {
3387 39 // suppose the code does something with the argument.
3388 40 return 0;
3389 41
3390 42 }
3391 43
3392 44 char
3393 45 func(S2*)
3394 46 {
3395 47 // suppose the code does something with the argument.
3396 48 return 0;
3397 49 }
3398 50
3399 51 unsigned
3400 52 func(S3)
3401 53 {
3402 54 // suppose the code does something with the argument.
3403 55 return 0;
3404 56 }
3405 $
3406
3407 Now let’s build the two libraries:
3408
3409 g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc
3410 g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc
3411
3412 Let’s look at the output of abidiff:
3413
3414 $ abidiff libtest2-v0.so libtest2-v1.so
3415 Functions changes summary: 0 Removed, 3 Changed, 0 Added functions
3416 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
3417
3418 3 functions with some indirect sub-type change:
3419
3420 [C]'function unsigned int func(S3)' has some indirect sub-type changes:
3421 parameter 0 of type 'struct S3' has sub-type changes:
3422 size changed from 32 to 64 bits
3423 1 base class insertion:
3424 struct base_type
3425 1 data member change:
3426 'int S3::m0' offset changed from 0 to 32
3427
3428 [C]'function char func(S2*)' has some indirect sub-type changes:
3429 parameter 0 of type 'S2*' has sub-type changes:
3430 in pointed to type 'struct S2':
3431 size changed from 32 to 64 bits
3432 1 base class insertion:
3433 struct base_type
3434 1 data member change:
3435 'int S2::m0' offset changed from 0 to 32
3436
3437 [C]'function int func(S1&)' has some indirect sub-type changes:
3438 parameter 0 of type 'S1&' has sub-type changes:
3439 in referenced type 'struct S1':
3440 size changed from 32 to 64 bits
3441 1 base class insertion:
3442 struct base_type
3443 1 data member change:
3444 'int S1::m0' offset changed from 0 to 32
3445 $
3446
3447 Let’s tell abidiff to avoid showing us the differences on the overloads
3448 of func that takes either a pointer or a reference. For that, we
3449 author this simple suppression specification:
3450
3451 $ cat -n libtest2.suppr
3452 1 [suppress_function]
3453 2 name = func
3454 3 parameter = '0 S1&
3455 4
3456 5 [suppress_function]
3457 6 name = func
3458 7 parameter = '0 S2*
3459 $
3460
3461 And then let’s invoke abidiff with the suppression specification:
3462
3463 $ ../build/tools/abidiff --suppressions libtest2.suppr libtest2-v0.so libtest2-v1.so
3464 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
3465 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
3466
3467 1 function with some indirect sub-type change:
3468
3469 [C]'function unsigned int func(S3)' has some indirect sub-type changes:
3470 parameter 0 of type 'struct S3' has sub-type changes:
3471 size changed from 32 to 64 bits
3472 1 base class insertion:
3473 struct base_type
3474 1 data member change:
3475 'int S3::m0' offset changed from 0 to 32
3476
3477 The suppression specification could be reduced using regular expres‐
3478 sions:
3479
3480 $ cat -n libtest2-1.suppr
3481 1 [suppress_function]
3482 2 name = func
3483 3 parameter = '0 /^S.(&|\\*)/
3484 $
3485
3486 $ ../build/tools/abidiff --suppressions libtest2-1.suppr libtest2-v0.so libtest2-v1.so
3487 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
3488 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
3489
3490 1 function with some indirect sub-type change:
3491
3492 [C]'function unsigned int func(S3)' has some indirect sub-type changes:
3493 parameter 0 of type 'struct S3' has sub-type changes:
3494 size changed from 32 to 64 bits
3495 1 base class insertion:
3496 struct base_type
3497 1 data member change:
3498 'int S3::m0' offset changed from 0 to 32
3499
3500 $
3501
3503 Dodji Seketeli
3504
3506 2014-2020, Red Hat, Inc.
3507
3508
3509
3510
3511 Feb 25, 2020 LIBABIGAIL(7)