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          · --no-added-syms
195
196            In  the   resulting   report   about   the   differences   between
197            first-shared-library  and  second-shared-library,  do  not display
198            added functions or variables.  Do not display added  functions  or
199            variables ELF symbols either.  All other kinds of changes are dis‐
200            played unless they are explicitely forbidden by other  options  on
201            the command line.
202
203          · --no-linkage-name
204
205            In  the  resulting report, do not display the linkage names of the
206            added, removed, or changed functions or variables.
207
208          · --no-show-locs
209              Do not show information about where in the second shared library
210              the respective type was changed.
211
212          · --show-bytes
213
214            Show  sizes and offsets in bytes, not bits.  By default, sizes and
215            offsets are shown in bits.
216
217          · --show-bits
218
219            Show sizes and offsets in bits, not bytes.  This option  is  acti‐
220            vated by default.
221
222          · --show-hex
223
224            Show sizes and offsets in hexadecimal base.
225
226          · --show-dec
227
228            Show  sizes and offsets in decimal base.  This option is activated
229            by default.
230
231          · --no-show-relative-offset-changes
232
233            Without this option, when the offset of a data member changes, the
234            change report not only mentions the older and newer offset, but it
235            also mentions by how many bits the data member changes.  With this
236            option, the latter is not shown.
237
238          · --no-unreferenced-symbols
239
240            In  the  resulting report, do not display change information about
241            function and variable symbols that are not referenced by any debug
242            information.   Note  that  for these symbols not referenced by any
243            debug information, the  change  information  displayed  is  either
244            added or removed symbols.
245
246          · --no-default-suppression
247
248            Do not load the default suppression specification files.
249
250          · --suppressions | --suppr <path-to-suppressions>
251
252            Use  a  suppression specification file located at path-to-suppres‐
253            sions.  Note that this option can appear  multiple  times  on  the
254            command line.  In that case, all of the provided suppression spec‐
255            ification files are taken into account.
256
257            Please note that, by default, if this option is not provided, then
258            the default suppression specification files are loaded .
259
260          · --drop <regex>
261
262            When  reading  the  first-shared-library and second-shared-library
263            ELF input files, drop the globally defined functions and variables
264            which  name  match  the regular expression regex.  As a result, no
265            change involving these functions or variables will be  emitted  in
266            the diff report.
267
268          · --drop-fn <regex>
269
270            When  reading  the  first-shared-library and second-shared-library
271            ELF input files, drop the globally defined  functions  which  name
272            match  the  regular  expression  regex.   As  a  result, no change
273            involving these functions will be emitted in the diff report.
274
275          · --drop-var <regex>
276
277            When reading the  first-shared-library  and  second-shared-library
278            ELF  input  files,  drop the globally defined variables matching a
279            the regular expression regex.
280
281          · --keep <regex>
282
283            When reading the  first-shared-library  and  second-shared-library
284            ELF input files, keep the globally defined functions and variables
285            which names match the regular expression regex.  All  other  func‐
286            tions  and  variables  are  dropped on the floor and will thus not
287            appear in the resulting diff report.
288
289          · --keep-fn <regex>
290
291            When reading the  first-shared-library  and  second-shared-library
292            ELF  input  files,  keep the globally defined functions which name
293            match the regular  expression  regex.   All  other  functions  are
294            dropped  on  the  floor  and will thus not appear in the resulting
295            diff report.
296
297          · --keep-var <regex>
298
299            When reading the  first-shared-library  and  second-shared-library
300            ELF  input  files, keep the globally defined which names match the
301            regular expression regex.  All other variables are dropped on  the
302            floor and will thus not appear in the resulting diff report.
303
304          · --harmless
305
306            In  the  diff  report,  display  only  the  harmless  changes.  By
307            default, the harmless changes are filtered out of the diff  report
308            keep  the  clutter  to a minimum and have a greater chance to spot
309            real ABI issues.
310
311          · --no-harmful
312
313            In the diff report,  do  not  display  the  harmful  changes.   By
314            default, only the harmful changes are displayed in diff report.
315
316          · --redundant
317
318            In  the  diff  report,  do display redundant changes.  A redundant
319            change is a change  that  has  been  displayed  elsewhere  in  the
320            report.
321
322          · --no-redundant
323
324            In the diff report, do NOT display redundant changes.  A redundant
325            change is a change  that  has  been  displayed  elsewhere  in  the
326            report.  This option is switched on by default.
327
328          · --no-architecture
329
330            Do not take architecture in account when comparing ABIs.
331
332          · --no-corpus-path
333
334            Do not emit the path attribute for the ABI corpus.
335
336          · --fail-no-debug-info
337
338            If  no debug info was found, then this option makes the program to
339            fail.  Otherwise, without this option, the program will attempt to
340            compare  properties  of the binaries that are not related to debug
341            info, like pure ELF properties.
342
343          · --leaf-changes-only|-l only  show  leaf  changes,  so  don’t  show
344            impact analysis report.
345
346            The  typical  output  of abidiff when comparing two binaries looks
347            like this
348
349                $ abidiff libtest-v0.so libtest-v1.so
350                Functions changes summary: 0 Removed, 1 Changed, 0 Added function
351                Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
352
353                1 function with some indirect sub-type change:
354
355                  [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
356                    parameter 1 of type 'C&' has sub-type changes:
357                      in referenced type 'struct C' at test-v1.cc:7:1:
358                        type size hasn't changed
359                        1 data member change:
360                         type of 'leaf* C::m0' changed:
361                           in pointed to type 'struct leaf' at test-v1.cc:1:1:
362                             type size changed from 32 to 64 bits
363                             1 data member insertion:
364                               'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
365
366                $
367
368            So in that example the report emits information about how the data
369            member  insertion  change of “struct leaf” is reachable from func‐
370            tion “void fn(C&)”.  In other words, the report not only shows the
371            data  member change on “struct leaf”, but it also shows the impact
372            of that change on the function “void fn(C&)”.
373
374            In abidiff parlance, the change on “struct leaf” is called a  leaf
375            change.   So the --leaf-changes-only --impacted-interfaces options
376            show, well, only the leaf change.  And it goes like this:
377
378                $ abidiff -l libtest-v0.so libtest-v1.so
379                'struct leaf' changed:
380                  type size changed from 32 to 64 bits
381                  1 data member insertion:
382                    'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
383
384                  one impacted interface:
385                    function void fn(C&)
386                $
387
388            Note how the  report  ends  by  showing  the  list  of  interfaces
389            impacted by the leaf change.
390
391            Now  if  you  don’t  want to see that list of impacted interfaces,
392            then you can just avoid  using  the  --impacted-interface  option.
393            You can learn about that option below, in any case.
394
395          · --impacted-interfaces
396
397            When  showing  leaf changes, this option instructs abidiff to show
398            the list of impacted interfaces.  This option is thus to  be  used
399            in   addition  the  --leaf-changes-only  option,  otherwise,  it’s
400            ignored.
401
402          · --dump-diff-tree
403              After the diff report, emit a textual representation of the diff
404              nodes  tree  used  by  the  comparison  engine  to represent the
405              changed functions and variables.  That representation is emitted
406              to the error output for debugging purposes.  Note that this diff
407              tree is relevant only to functions and variables that have  some
408              sub-type  changes.   Added or removed functions and variables do
409              not have any diff nodes tree associated to them.
410
411          · --stats
412
413            Emit statistics about various internal things.
414
415          · --verbose
416
417            Emit verbose logs about the  progress  of  miscellaneous  internal
418            things.
419

RETURN VALUES

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

USAGE EXAMPLES

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

AUTHOR

625       Dodji Seketeli
626
628       2014-2016, Red Hat, Inc.
629
630
631
632
633                                 Mar 29, 2019                       ABIDIFF(1)
Impressum