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
18       accompanied  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   LIBABI‐
32         GAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE.   If  that environment variable
33         is not set, then abidiff tries to load  the  suppression  file  $lib‐
34         dir/libabigail/libabigail-default.abignore.   If  that  file  is  not
35         present, then no default system-wide suppression  specification  file
36         is loaded.
37
38       · Default user suppression specification file.
39
40         It’s located by the optional environment LIBABIGAIL_DEFAULT_USER_SUP‐
41         PRESSION_FILE.  If that environment variable is not set, then abidiff
42         tries  to load the suppression file $HOME/.abignore.  If that file is
43         not present,  then  no  default  user  suppression  specification  is
44         loaded.
45

OPTIONS

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

RETURN VALUES

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

USAGE EXAMPLES

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

AUTHOR

678       Dodji Seketeli
679
681       2014-2021, Red Hat, Inc.
682
683
684
685
686                                 Feb 25, 2021                       ABIDIFF(1)
Impressum