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