1ABIDIFF(1)                        Libabigail                        ABIDIFF(1)
2
3
4

NAME

6       abidiff - compare ABIs of ELF files
7
8       abidiff  compares the Application Binary Interfaces (ABI) of two shared
9       libraries in ELF format.  It emits a meaningful report  describing  the
10       differences between the two ABIs.
11
12       This  tool  can  also compare the textual representations of the ABI of
13       two ELF binaries (as emitted by abidw) or an ELF binary against a  tex‐
14       tual representation of another ELF binary.
15
16       For a comprehensive ABI change report that includes changes about func‐
17       tion and variable sub-types, the two input shared libraries must be ac‐
18       companied  with  their  debug  information in DWARF format.  Otherwise,
19       only ELF symbols that were added or removed are reported.
20

INVOCATION

22          abidiff [options] <first-shared-library> <second-shared-library>
23

ENVIRONMENT

25       abidiff loads two  default  suppression  specifications  files,  merges
26       their content and use it to filter out ABI change reports that might be
27       considered as false positives to users.
28
29       • Default system-wide suppression specification file
30
31         It’s located by  the  optional  environment  variable  LIBABIGAIL_DE‐
32         FAULT_SYSTEM_SUPPRESSION_FILE.   If  that environment variable is not
33         set, then abidiff tries to load the suppression file  $libdir/libabi‐
34         gail/libabigail-default.abignore.   If that file is not present, then
35         no default system-wide suppression specification file is loaded.
36
37       • Default user suppression specification file.
38
39         It’s located by the optional environment LIBABIGAIL_DEFAULT_USER_SUP‐
40         PRESSION_FILE.  If that environment variable is not set, then abidiff
41         tries to load the suppression file $HOME/.abignore.  If that file  is
42         not  present,  then  no  default  user  suppression  specification is
43         loaded.
44

OPTIONS

46--help | -h
47
48            Display a short help about the command and exit.
49
50--debug
51
52            In this mode, error messages are emitted for types which fail type
53            canonicalization.
54
55            This  is  an optional ebugging and sanity check option.  To enable
56            it the libabigail package needs to be  configured  with  the  –en‐
57            able-debug-self-comparison option.
58
59--version | -v
60
61            Display the version of the program and exit.
62
63--debug-info-dir1 | --d1 <di-path1>
64
65            For  cases where the debug information for first-shared-library is
66            split out into a separate file, tells abidiff where to  find  that
67            separate debug information file.
68
69            Note that di-path must point to the root directory under which the
70            debug information is arranged in a tree-like  manner.   Under  Red
71            Hat based systems, that directory is usually <root>/usr/lib/debug.
72
73            This  option can be provided several times with different root di‐
74            rectories.  In that case, abidiff will potentially look  into  all
75            those   root   directories  to  find  the  split  debug  info  for
76            first-shared-library.
77
78            Note also that this option is not mandatory for split debug infor‐
79            mation  installed  by  your  system’s package manager because then
80            abidiff knows where to find it.
81
82--debug-info-dir2 | --d2 <di-path2>
83
84            Like --debug-info-dir1, this options tells abidiff where  to  find
85            the split debug information for the second-shared-library file.
86
87            This  option can be provided several times with different root di‐
88            rectories.  In that case, abidiff will potentially look  into  all
89            those  root  directories  to  find  the  split debug info for sec‐
90            ond-shared-library.
91
92--headers-dir1 | --hd1 <headers-directory-path-1>
93
94            Specifies where to find the public headers of the first shared li‐
95            brary  (or  binary in general) that the tool has to consider.  The
96            tool will thus filter out ABI changes on types that  are  not  de‐
97            fined in public headers.
98
99            Note  that  several public header directories can be specified for
100            the first shared library.  In that case the --headers-dir1  option
101            should  be  present several times on the command line, like in the
102            following example:
103
104                $ abidiff --headers-dir1 /some/path       \
105                          --headers-dir1 /some/other/path \
106                          binary-version-1 binary-version-2
107
108--header-file1 | --hf1 <header-file-path-1>
109
110            Specifies where to find one public header of the first shared  li‐
111            brary  that  the  tool has to consider.  The tool will thus filter
112            out ABI changes on types that are not defined in public headers.
113
114--headers-dir2 | --hd2 <headers-directory-path-1>
115
116            Specifies where to find the public headers of  the  second  shared
117            library  that the tool has to consider.  The tool will thus filter
118            out ABI changes on types that are not defined in public headers.
119
120            Note that several public header directories can be  specified  for
121            the second shared library.  In that case the --headers-dir2 option
122            should be present several times like in the following example:
123
124                $ abidiff --headers-dir2 /some/path       \
125                          --headers-dir2 /some/other/path \
126                          binary-version-1 binary-version-2
127
128--header-file2 | --hf2 <header-file-path-2>
129
130            Specifies where to find one public header of the second shared li‐
131            brary  that  the  tool has to consider.  The tool will thus filter
132            out ABI changes on types that are not defined in public headers.
133
134--no-linux-kernel-mode
135
136            Without this option, if abidiff detects that the  binaries  it  is
137            looking  at  are Linux Kernel binaries (either vmlinux or modules)
138            then it only considers functions and variables which  ELF  symbols
139            are listed in the __ksymtab and __ksymtab_gpl sections.
140
141            With  this  option,  abidiff considers the binary as a non-special
142            ELF binary.  It thus considers functions and variables  which  are
143            defined and exported in the ELF sense.
144
145--kmi-whitelist | -kaw <path-to-whitelist>
146
147            When  analyzing  a  Linux kernel binary, this option points to the
148            white list of names of ELF  symbols  of  functions  and  variables
149            which ABI must be considered.  That white list is called a “Kernel
150            Module Interface white list”.  This is because for the Kernel,  we
151            don’t  talk  about ABI; we rather talk about the interface between
152            the Kernel and its module. Hence the term KMI rather than ABI.
153
154            Any other function or variable which ELF symbol are not present in
155            that white list will not be considered by this tool.
156
157            If this option is not provided – thus if no white list is provided
158            – then the entire KMI, that is, the set of  all  publicly  defined
159            and  exported  functions  and global variables by the Linux Kernel
160            binaries, is considered.
161
162--drop-private-types
163
164            This option is to be used with the  --headers-dir1,  header-file1,
165            header-file2  and --headers-dir2 options.  With this option, types
166            that are NOT defined in the headers are entirely dropped from  the
167            internal  representation build by Libabigail to represent the ABI.
168            They thus don’t have to be filtered out from the final ABI  change
169            report because they are not even present in Libabigail’s represen‐
170            tation.
171
172            Without this option however, those private types are kept  in  the
173            internal representation and later filtered out from the report.
174
175            This  options  thus potentially makes Libabigail consume less mem‐
176            ory.  It’s meant to be mainly used to optimize the memory consump‐
177            tion  of  the  tool on binaries with a lot of publicly defined and
178            exported types.
179
180--stat
181
182            Rather  than  displaying  the  detailed  ABI  differences  between
183            first-shared-library  and second-shared-library, just display some
184            summary statistics about these differences.
185
186--symtabs
187
188            Only display the symbol tables  of  the  first-shared-library  and
189            second-shared-library.
190
191--deleted-fns
192
193            In   the   resulting   report   about   the   differences  between
194            first-shared-library and second-shared-library, only  display  the
195            globally  defined functions that got deleted from first-shared-li‐
196            brary.
197
198--changed-fns
199
200            In  the   resulting   report   about   the   differences   between
201            first-shared-library  and  second-shared-library, only display the
202            changes  in  sub-types  of  the  global   functions   defined   in
203            first-shared-library.
204
205--added-fns
206
207            In   the   resulting   report   about   the   differences  between
208            first-shared-library and second-shared-library, only  display  the
209            globally  defined  functions  that were added to second-shared-li‐
210            brary.
211
212--deleted-vars
213
214            In  the   resulting   report   about   the   differences   between
215            first-shared-library  and  second-shared-library, only display the
216            globally defined variables that were deleted from first-shared-li‐
217            brary.
218
219--changed-vars
220
221            In   the   resulting   report   about   the   differences  between
222            first-shared-library and second-shared-library, only  display  the
223            changes  in  the  sub-types  of  the  global  variables defined in
224            first-shared-library
225
226--added-vars
227
228            In  the   resulting   report   about   the   differences   between
229            first-shared-library  and  second-shared-library, only display the
230            global variables that were added  (defined)  to  second-shared-li‐
231            brary.
232
233--non-reachable-types|-t
234
235            Analyze  and  emit change reports for all the types of the binary,
236            including those that are not reachable from global  functions  and
237            variables.
238
239            This  option  might  incur some serious performance degradation as
240            the number of types analyzed can be huge.  However, if paired with
241            the  --headers-dir{1,2} and/or header-file{1,2} options, the addi‐
242            tional non-reachable types analyzed are restricted  to  those  de‐
243            fined  in  public headers files, thus hopefully making the perfor‐
244            mance hit acceptable.
245
246            Also, using this option alongside suppression  specifications  (by
247            also  using  the --suppressions option) might help keep the number
248            of analyzed types (and the potential performance  degradation)  in
249            control.
250
251            Note  that without this option, only types that are reachable from
252            global functions and variables are analyzed, so the  tool  detects
253            and reports changes on these reachable types only.
254
255--no-added-syms
256
257            In   the   resulting   report   about   the   differences  between
258            first-shared-library and  second-shared-library,  do  not  display
259            added  functions  or variables.  Do not display added functions or
260            variables ELF symbols either.  All other kinds of changes are dis‐
261            played  unless  they are explicitely forbidden by other options on
262            the command line.
263
264--no-linkage-name
265
266            In the resulting report, do not display the linkage names  of  the
267            added, removed, or changed functions or variables.
268
269--no-show-locs
270              Do not show information about where in the second shared library
271              the respective type was changed.
272
273--show-bytes
274
275            Show sizes and offsets in bytes, not bits.  By default, sizes  and
276            offsets are shown in bits.
277
278--show-bits
279
280            Show  sizes  and offsets in bits, not bytes.  This option is acti‐
281            vated by default.
282
283--show-hex
284
285            Show sizes and offsets in hexadecimal base.
286
287--show-dec
288
289            Show sizes and offsets in decimal base.  This option is  activated
290            by default.
291
292--no-show-relative-offset-changes
293
294            Without this option, when the offset of a data member changes, the
295            change report not only mentions the older and newer offset, but it
296            also mentions by how many bits the data member changes.  With this
297            option, the latter is not shown.
298
299--no-unreferenced-symbols
300
301            In the resulting report, do not display change  information  about
302            function and variable symbols that are not referenced by any debug
303            information.  Note that for these symbols not  referenced  by  any
304            debug  information,  the  change  information  displayed is either
305            added or removed symbols.
306
307--no-default-suppression
308
309            Do not load the default suppression specification files.
310
311--suppressions | --suppr <path-to-suppressions>
312
313            Use a suppression specification file located  at  path-to-suppres‐
314            sions.   Note  that  this  option can appear multiple times on the
315            command line.  In that case, all of the provided suppression spec‐
316            ification files are taken into account.
317
318            Please note that, by default, if this option is not provided, then
319            the default suppression specification files are loaded .
320
321--drop <regex>
322
323            When reading the  first-shared-library  and  second-shared-library
324            ELF input files, drop the globally defined functions and variables
325            which name match the regular expression regex.  As  a  result,  no
326            change  involving  these functions or variables will be emitted in
327            the diff report.
328
329--drop-fn <regex>
330
331            When reading the  first-shared-library  and  second-shared-library
332            ELF  input  files,  drop the globally defined functions which name
333            match the regular expression regex.  As a result,  no  change  in‐
334            volving these functions will be emitted in the diff report.
335
336--drop-var <regex>
337
338            When  reading  the  first-shared-library and second-shared-library
339            ELF input files, drop the globally defined  variables  matching  a
340            the regular expression regex.
341
342--keep <regex>
343
344            When  reading  the  first-shared-library and second-shared-library
345            ELF input files, keep the globally defined functions and variables
346            which  names  match the regular expression regex.  All other func‐
347            tions and variables are dropped on the floor and will thus not ap‐
348            pear in the resulting diff report.
349
350--keep-fn <regex>
351
352            When  reading  the  first-shared-library and second-shared-library
353            ELF input files, keep the globally defined  functions  which  name
354            match  the  regular  expression  regex.   All  other functions are
355            dropped on the floor and will thus not  appear  in  the  resulting
356            diff report.
357
358--keep-var <regex>
359
360            When  reading  the  first-shared-library and second-shared-library
361            ELF input files, keep the globally defined which names  match  the
362            regular  expression regex.  All other variables are dropped on the
363            floor and will thus not appear in the resulting diff report.
364
365--harmless
366
367            In the diff report, display only the  harmless  changes.   By  de‐
368            fault,  the  harmless  changes are filtered out of the diff report
369            keep the clutter to a minimum and have a greater  chance  to  spot
370            real ABI issues.
371
372--no-harmful
373
374            In  the  diff  report, do not display the harmful changes.  By de‐
375            fault, only the harmful changes are displayed in diff report.
376
377--redundant
378
379            In the diff report, do display  redundant  changes.   A  redundant
380            change  is  a  change that has been displayed elsewhere in the re‐
381            port.
382
383--no-redundant
384
385            In the diff report, do NOT display redundant changes.  A redundant
386            change  is  a  change that has been displayed elsewhere in the re‐
387            port.  This option is switched on by default.
388
389--no-architecture
390
391            Do not take architecture in account when comparing ABIs.
392
393--no-corpus-path
394
395            Do not emit the path attribute for the ABI corpus.
396
397--fail-no-debug-info
398
399            If no debug info was found, then this option makes the program  to
400            fail.  Otherwise, without this option, the program will attempt to
401            compare properties of the binaries that are not related  to  debug
402            info, like pure ELF properties.
403
404--leaf-changes-only|-l  only  show leaf changes, so don’t show im‐
405            pact analysis report.  This option implies --redundant.
406
407            The typical output of abidiff when comparing  two  binaries  looks
408            like this
409
410                $ abidiff libtest-v0.so libtest-v1.so
411                Functions changes summary: 0 Removed, 1 Changed, 0 Added function
412                Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
413
414                1 function with some indirect sub-type change:
415
416                  [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
417                    parameter 1 of type 'C&' has sub-type changes:
418                      in referenced type 'struct C' at test-v1.cc:7:1:
419                        type size hasn't changed
420                        1 data member change:
421                         type of 'leaf* C::m0' changed:
422                           in pointed to type 'struct leaf' at test-v1.cc:1:1:
423                             type size changed from 32 to 64 bits
424                             1 data member insertion:
425                               'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
426
427                $
428
429            So in that example the report emits information about how the data
430            member insertion change of “struct leaf” is reachable  from  func‐
431            tion “void fn(C&)”.  In other words, the report not only shows the
432            data member change on “struct leaf”, but it also shows the  impact
433            of that change on the function “void fn(C&)”.
434
435            In  abidiff parlance, the change on “struct leaf” is called a leaf
436            change.  So the --leaf-changes-only --impacted-interfaces  options
437            show, well, only the leaf change.  And it goes like this:
438
439                $ abidiff -l libtest-v0.so libtest-v1.so
440                'struct leaf' changed:
441                  type size changed from 32 to 64 bits
442                  1 data member insertion:
443                    'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
444
445                  one impacted interface:
446                    function void fn(C&)
447                $
448
449            Note  how  the  report  ends by showing the list of interfaces im‐
450            pacted by the leaf change.
451
452            Now if you don’t want to see that  list  of  impacted  interfaces,
453            then  you  can  just  avoid using the --impacted-interface option.
454            You can learn about that option below, in any case.
455
456--impacted-interfaces
457
458            When showing leaf changes, this option instructs abidiff  to  show
459            the  list  of impacted interfaces.  This option is thus to be used
460            in addition the --leaf-changes-only option,  otherwise,  it’s  ig‐
461            nored.
462
463--dump-diff-tree
464              After the diff report, emit a textual representation of the diff
465              nodes tree used  by  the  comparison  engine  to  represent  the
466              changed functions and variables.  That representation is emitted
467              to the error output for debugging purposes.  Note that this diff
468              tree  is relevant only to functions and variables that have some
469              sub-type changes.  Added or removed functions and  variables  do
470              not have any diff nodes tree associated to them.
471
472--stats
473
474            Emit statistics about various internal things.
475
476--verbose
477
478            Emit  verbose  logs  about  the progress of miscellaneous internal
479            things.
480

RETURN VALUES

482       The exit code of the abidiff command is either 0 if the ABI of the  bi‐
483       naries  being  compared are equal, or non-zero if they differ or if the
484       tool encountered an error.
485
486       In the later case, the exit code is a 8-bits-wide bit  field  in  which
487       each bit has a specific meaning.
488
489       The  first  bit, of value 1, named ABIDIFF_ERROR means there was an er‐
490       ror.
491
492       The second bit, of value 2, named ABIDIFF_USAGE_ERROR means  there  was
493       an  error  in  the way the user invoked the tool.  It might be set, for
494       instance, if the user invoked the tool with  an  unknown  command  line
495       switch, with a wrong number or argument, etc.  If this bit is set, then
496       the ABIDIFF_ERROR bit must be set as well.
497
498       The third bit, of value 4, named ABIDIFF_ABI_CHANGE means  the  ABI  of
499       the binaries being compared are different.
500
501       The fourth bit, of value 8, named ABIDIFF_ABI_INCOMPATIBLE_CHANGE means
502       the ABI of the binaries compared are different in an incompatible  way.
503       If  this  bit  is  set,  then the ABIDIFF_ABI_CHANGE bit must be set as
504       well.  If the ABIDIFF_ABI_CHANGE  is  set  and  the  ABIDIFF_INCOMPATI‐
505       BLE_CHANGE is NOT set, then it means that the ABIs being compared might
506       or might not be compatible.  In that case, a human being needs  to  re‐
507       view the ABI changes to decide if they are compatible or not.
508
509       Note  that,  at  the  moment, there are only a few kinds of ABI changes
510       that would result in setting the flag  ABIDIFF_ABI_INCOMPATIBLE_CHANGE.
511       Those ABI changes are either:
512
513          • the  removal of the symbol of a function or variable that has been
514            defined and exported.
515
516          • the modification of the index of a member of  a  virtual  function
517            table (for C++ programs and libraries).
518
519       With time, when more ABI change patterns are found to always constitute
520       incompatible ABI changes, we will adapt the  code  to  recognize  those
521       cases  and set the ABIDIFF_ABI_INCOMPATIBLE_CHANGE accordingly.  So, if
522       you find such patterns, please let us know.
523
524       The remaining bits are not used for the moment.
525

USAGE EXAMPLES

527          1. Detecting a change in a sub-type of a function:
528
529                 $ cat -n test-v0.cc
530                          1      // Compile this with:
531                          2      //   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
532                          3
533                          4      struct S0
534                          5      {
535                          6        int m0;
536                          7      };
537                          8
538                          9      void
539                         10      foo(S0* /*parameter_name*/)
540                         11      {
541                         12        // do something with parameter_name.
542                         13      }
543                 $
544                 $ cat -n test-v1.cc
545                          1      // Compile this with:
546                          2      //   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
547                          3
548                          4      struct type_base
549                          5      {
550                          6        int inserted;
551                          7      };
552                          8
553                          9      struct S0 : public type_base
554                         10      {
555                         11        int m0;
556                         12      };
557                         13
558                         14      void
559                         15      foo(S0* /*parameter_name*/)
560                         16      {
561                         17        // do something with parameter_name.
562                         18      }
563                 $
564                 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
565                 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
566                 $
567                 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
568                 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
569                 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
570
571                 1 function with some indirect sub-type change:
572
573                   [C]'function void foo(S0*)' has some indirect sub-type changes:
574                         parameter 0 of type 'S0*' has sub-type changes:
575                           in pointed to type 'struct S0':
576                             size changed from 32 to 64 bits
577                             1 base class insertion:
578                               struct type_base
579                             1 data member change:
580                              'int S0::m0' offset changed from 0 to 32
581                 $
582
583          2. Detecting another change in a sub-type of a function:
584
585                 $ cat -n test-v0.cc
586                          1      // Compile this with:
587                          2      //   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
588                          3
589                          4      struct S0
590                          5      {
591                          6        int m0;
592                          7      };
593                          8
594                          9      void
595                         10      foo(S0& /*parameter_name*/)
596                         11      {
597                         12        // do something with parameter_name.
598                         13      }
599                 $
600                 $ cat -n test-v1.cc
601                          1      // Compile this with:
602                          2      //   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
603                          3
604                          4      struct S0
605                          5      {
606                          6        char inserted_member;
607                          7        int m0;
608                          8      };
609                          9
610                         10      void
611                         11      foo(S0& /*parameter_name*/)
612                         12      {
613                         13        // do something with parameter_name.
614                         14      }
615                 $
616                 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
617                 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
618                 $
619                 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
620                 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
621                 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
622
623                 1 function with some indirect sub-type change:
624
625                   [C]'function void foo(S0&)' has some indirect sub-type changes:
626                         parameter 0 of type 'S0&' has sub-type changes:
627                           in referenced type 'struct S0':
628                             size changed from 32 to 64 bits
629                             1 data member insertion:
630                               'char S0::inserted_member', at offset 0 (in bits)
631                             1 data member change:
632                              'int S0::m0' offset changed from 0 to 32
633
634
635                 $
636
637          3. Detecting that functions got removed or added to a library:
638
639                 $ cat -n test-v0.cc
640                          1      // Compile this with:
641                          2      //   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
642                          3
643                          4      struct S0
644                          5      {
645                          6        int m0;
646                          7      };
647                          8
648                          9      void
649                         10      foo(S0& /*parameter_name*/)
650                         11      {
651                         12        // do something with parameter_name.
652                         13      }
653                 $
654                 $ cat -n test-v1.cc
655                          1      // Compile this with:
656                          2      //   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
657                          3
658                          4      struct S0
659                          5      {
660                          6        char inserted_member;
661                          7        int m0;
662                          8      };
663                          9
664                         10      void
665                         11      bar(S0& /*parameter_name*/)
666                         12      {
667                         13        // do something with parameter_name.
668                         14      }
669                 $
670                 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
671                 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
672                 $
673                 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
674                 Functions changes summary: 1 Removed, 0 Changed, 1 Added functions
675                 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
676
677                 1 Removed function:
678                   'function void foo(S0&)'    {_Z3fooR2S0}
679
680                 1 Added function:
681                   'function void bar(S0&)'    {_Z3barR2S0}
682
683                 $
684

AUTHOR

686       Dodji Seketeli
687
689       2014-2022, Red Hat, Inc.
690
691
692
693
694                                 Jan 20, 2022                       ABIDIFF(1)
Impressum