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

RETURN VALUES

442       The exit code of the abidiff command is either 0  if  the  ABI  of  the
443       binaries being compared are equal, or non-zero if they differ or if the
444       tool encountered an error.
445
446       In the later case, the exit code is a 8-bits-wide bit  field  in  which
447       each bit has a specific meaning.
448
449       The  first  bit,  of  value  1,  named ABIDIFF_ERROR means there was an
450       error.
451
452       The second bit, of value 2, named ABIDIFF_USAGE_ERROR means  there  was
453       an  error  in  the way the user invoked the tool.  It might be set, for
454       instance, if the user invoked the tool with  an  unknown  command  line
455       switch, with a wrong number or argument, etc.  If this bit is set, then
456       the ABIDIFF_ERROR bit must be set as well.
457
458       The third bit, of value 4, named ABIDIFF_ABI_CHANGE means  the  ABI  of
459       the binaries being compared are different.
460
461       The fourth bit, of value 8, named ABIDIFF_ABI_INCOMPATIBLE_CHANGE means
462       the ABI of the binaries compared are different in an incompatible  way.
463       If  this  bit  is  set,  then the ABIDIFF_ABI_CHANGE bit must be set as
464       well.  If the ABIDIFF_ABI_CHANGE  is  set  and  the  ABIDIFF_INCOMPATI‐
465       BLE_CHANGE is NOT set, then it means that the ABIs being compared might
466       or might not be compatible.  In that  case,  a  human  being  needs  to
467       review the ABI changes to decide if they are compatible or not.
468
469       Note  that,  at  the  moment, there are only a few kinds of ABI changes
470       that would result in setting the flag  ABIDIFF_ABI_INCOMPATIBLE_CHANGE.
471       Those ABI changes are either:
472
473          · the  removal of the symbol of a function or variable that has been
474            defined and exported.
475
476          · the modification of the index of a member of  a  virtual  function
477            table (for C++ programs and libraries).
478
479       With time, when more ABI change patterns are found to always constitute
480       incompatible ABI changes, we will adapt the  code  to  recognize  those
481       cases  and set the ABIDIFF_ABI_INCOMPATIBLE_CHANGE accordingly.  So, if
482       you find such patterns, please let us know.
483
484       The remaining bits are not used for the moment.
485

USAGE EXAMPLES

487          1. Detecting a change in a sub-type of a function:
488
489                 $ cat -n test-v0.cc
490                          1      // Compile this with:
491                          2      //   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
492                          3
493                          4      struct S0
494                          5      {
495                          6        int m0;
496                          7      };
497                          8
498                          9      void
499                         10      foo(S0* /*parameter_name*/)
500                         11      {
501                         12        // do something with parameter_name.
502                         13      }
503                 $
504                 $ cat -n test-v1.cc
505                          1      // Compile this with:
506                          2      //   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
507                          3
508                          4      struct type_base
509                          5      {
510                          6        int inserted;
511                          7      };
512                          8
513                          9      struct S0 : public type_base
514                         10      {
515                         11        int m0;
516                         12      };
517                         13
518                         14      void
519                         15      foo(S0* /*parameter_name*/)
520                         16      {
521                         17        // do something with parameter_name.
522                         18      }
523                 $
524                 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
525                 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
526                 $
527                 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
528                 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
529                 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
530
531                 1 function with some indirect sub-type change:
532
533                   [C]'function void foo(S0*)' has some indirect sub-type changes:
534                         parameter 0 of type 'S0*' has sub-type changes:
535                           in pointed to type 'struct S0':
536                             size changed from 32 to 64 bits
537                             1 base class insertion:
538                               struct type_base
539                             1 data member change:
540                              'int S0::m0' offset changed from 0 to 32
541                 $
542
543          2. Detecting another change in a sub-type of a function:
544
545                 $ cat -n test-v0.cc
546                          1      // Compile this with:
547                          2      //   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
548                          3
549                          4      struct S0
550                          5      {
551                          6        int m0;
552                          7      };
553                          8
554                          9      void
555                         10      foo(S0& /*parameter_name*/)
556                         11      {
557                         12        // do something with parameter_name.
558                         13      }
559                 $
560                 $ cat -n test-v1.cc
561                          1      // Compile this with:
562                          2      //   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
563                          3
564                          4      struct S0
565                          5      {
566                          6        char inserted_member;
567                          7        int m0;
568                          8      };
569                          9
570                         10      void
571                         11      foo(S0& /*parameter_name*/)
572                         12      {
573                         13        // do something with parameter_name.
574                         14      }
575                 $
576                 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
577                 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
578                 $
579                 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
580                 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
581                 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
582
583                 1 function with some indirect sub-type change:
584
585                   [C]'function void foo(S0&)' has some indirect sub-type changes:
586                         parameter 0 of type 'S0&' has sub-type changes:
587                           in referenced type 'struct S0':
588                             size changed from 32 to 64 bits
589                             1 data member insertion:
590                               'char S0::inserted_member', at offset 0 (in bits)
591                             1 data member change:
592                              'int S0::m0' offset changed from 0 to 32
593
594
595                 $
596
597          3. Detecting that functions got removed or added to a library:
598
599                 $ cat -n test-v0.cc
600                          1      // Compile this with:
601                          2      //   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
602                          3
603                          4      struct S0
604                          5      {
605                          6        int m0;
606                          7      };
607                          8
608                          9      void
609                         10      foo(S0& /*parameter_name*/)
610                         11      {
611                         12        // do something with parameter_name.
612                         13      }
613                 $
614                 $ cat -n test-v1.cc
615                          1      // Compile this with:
616                          2      //   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
617                          3
618                          4      struct S0
619                          5      {
620                          6        char inserted_member;
621                          7        int m0;
622                          8      };
623                          9
624                         10      void
625                         11      bar(S0& /*parameter_name*/)
626                         12      {
627                         13        // do something with parameter_name.
628                         14      }
629                 $
630                 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
631                 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
632                 $
633                 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
634                 Functions changes summary: 1 Removed, 0 Changed, 1 Added functions
635                 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
636
637                 1 Removed function:
638                   'function void foo(S0&)'    {_Z3fooR2S0}
639
640                 1 Added function:
641                   'function void bar(S0&)'    {_Z3barR2S0}
642
643                 $
644

AUTHOR

646       Dodji Seketeli
647
649       2014-2020, Red Hat, Inc.
650
651
652
653
654                                 Feb 25, 2020                       ABIDIFF(1)
Impressum