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