• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1.. _abidiff_label:
2
3=======
4abidiff
5=======
6
7abidiff compares the Application Binary Interfaces (ABI) of two shared
8libraries in `ELF`_ format.  It emits a meaningful report describing the
9differences between the two ABIs.
10
11This tool can also compare the textual representations of the ABI of
12two ELF binaries (as emitted by ``abidw``) or an ELF binary against a
13textual representation of another ELF binary.
14
15For a comprehensive ABI change report that includes changes about
16function and variable sub-types, the two input shared libraries must
17be accompanied with their debug information in `DWARF`_ format.
18Otherwise, only `ELF`_ symbols that were added or removed are
19reported.
20
21.. _abidiff_invocation_label:
22
23Invocation
24==========
25
26::
27
28  abidiff [options] <first-shared-library> <second-shared-library>
29
30
31Environment
32===========
33
34.. _abidiff_default_supprs_label:
35
36abidiff loads two default :ref:`suppression specifications files
37<suppr_spec_label>`, merges their content and use it to filter out ABI
38change reports that might be considered as false positives to users.
39
40* Default system-wide suppression specification file
41
42  It's located by the optional environment variable
43  LIBABIGAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE.  If that environment
44  variable is not set, then abidiff tries to load the suppression file
45  $libdir/libabigail/libabigail-default.abignore.  If that file is not
46  present, then no default system-wide suppression specification file
47  is loaded.
48
49* Default user suppression specification file.
50
51  It's located by the optional environment
52  LIBABIGAIL_DEFAULT_USER_SUPPRESSION_FILE.  If that environment
53  variable is not set, then abidiff tries to load the suppression file
54  $HOME/.abignore.  If that file is not present, then no default user
55  suppression specification is loaded.
56
57.. _abidiff_options_label:
58
59Options
60=======
61
62  * ``--help | -h``
63
64    Display a short help about the command and exit.
65
66  * ``--version | -v``
67
68    Display the version of the program and exit.
69
70  * ``--debug-info-dir1 | --d1`` <*di-path1*>
71
72    For cases where the debug information for *first-shared-library*
73    is split out into a separate file, tells ``abidiff`` where to find
74    that separate debug information file.
75
76    Note that *di-path* must point to the root directory under which
77    the debug information is arranged in a tree-like manner.  Under
78    Red Hat based systems, that directory is usually
79    ``<root>/usr/lib/debug``.
80
81    This option can be provided several times with different root
82    directories.  In that case, ``abidiff`` will potentially look into
83    all those root directories to find the split debug info for
84    *first-shared-library*.
85
86    Note also that this option is not mandatory for split debug
87    information installed by your system's package manager because
88    then ``abidiff`` knows where to find it.
89
90  * ``--debug-info-dir2 | --d2`` <*di-path2*>
91
92    Like ``--debug-info-dir1``, this options tells ``abidiff`` where
93    to find the split debug information for the
94    *second-shared-library* file.
95
96    This option can be provided several times with different root
97    directories.  In that case, ``abidiff`` will potentially look into
98    all those root directories to find the split debug info for
99    *second-shared-library*.
100
101  * ``--headers-dir1 | --hd1`` <headers-directory-path-1>
102
103    Specifies where to find the public headers of the first shared
104    library (or binary in general) that the tool has to consider.  The
105    tool will thus filter out ABI changes on types that are not
106    defined in public headers.
107
108    Note that several public header directories can be specified for
109    the first shared library.  In that case the ``--headers-dir1``
110    option should be present several times on the command line, like
111    in the following example: ::
112
113      $ abidiff --headers-dir1 /some/path       \
114                --headers-dir1 /some/other/path \
115		binary-version-1 binary-version-2
116
117  * ``--header-file1 | --hf1`` <header-file-path-1>
118
119    Specifies where to find one public header of the first shared
120    library that the tool has to consider.  The tool will thus filter
121    out ABI changes on types that are not defined in public headers.
122
123  * ``--headers-dir2 | --hd2`` <headers-directory-path-1>
124
125    Specifies where to find the public headers of the second shared
126    library that the tool has to consider.  The tool will thus filter
127    out ABI changes on types that are not defined in public headers.
128
129    Note that several public header directories can be specified for
130    the second shared library.  In that case the ``--headers-dir2``
131    option should be present several times like in the following
132    example: ::
133
134      $ abidiff --headers-dir2 /some/path       \
135                --headers-dir2 /some/other/path \
136		binary-version-1 binary-version-2
137
138  * ``--header-file2 | --hf2`` <header-file-path-2>
139
140    Specifies where to find one public header of the second shared
141    library that the tool has to consider.  The tool will thus filter
142    out ABI changes on types that are not defined in public headers.
143
144  * ``--no-linux-kernel-mode``
145
146    Without this option, if abidiff detects that the binaries it is
147    looking at are Linux Kernel binaries (either vmlinux or modules)
148    then it only considers functions and variables which ELF symbols
149    are listed in the __ksymtab and __ksymtab_gpl sections.
150
151    With this option, abidiff considers the binary as a non-special
152    ELF binary.  It thus considers functions and variables which are
153    defined and exported in the ELF sense.
154
155  * ``--kmi-whitelist | -kaw`` <*path-to-whitelist*>
156
157    When analyzing a Linux kernel binary, this option points to the
158    white list of names of ELF symbols of functions and variables
159    which ABI must be considered.  That white list is called a "Kernel
160    Module Interface white list".  This is because for the Kernel, we
161    don't talk about ``ABI``; we rather talk about the interface
162    between the Kernel and its module. Hence the term ``KMI`` rather
163    than ``ABI``.
164
165    Any other function or variable which ELF symbol are not present in
166    that white list will not be considered by this tool.
167
168    If this option is not provided -- thus if no white list is
169    provided -- then the entire KMI, that is, the set of all publicly
170    defined and exported functions and global variables by the Linux
171    Kernel binaries, is considered.
172
173  * ``--drop-private-types``
174
175    This option is to be used with the ``--headers-dir1``,
176    ``header-file1``, ``header-file2`` and ``--headers-dir2`` options.
177    With this option, types that are *NOT* defined in the headers are
178    entirely dropped from the internal representation build by
179    Libabigail to represent the ABI.  They thus don't have to be
180    filtered out from the final ABI change report because they are not
181    even present in Libabigail's representation.
182
183    Without this option however, those private types are kept in the
184    internal representation and later filtered out from the report.
185
186    This options thus potentially makes Libabigail consume less
187    memory.  It's meant to be mainly used to optimize the memory
188    consumption of the tool on binaries with a lot of publicly defined
189    and exported types.
190
191  * ``--stat``
192
193    Rather than displaying the detailed ABI differences between
194    *first-shared-library* and *second-shared-library*, just display
195    some summary statistics about these differences.
196
197  * ``--symtabs``
198
199    Only display the symbol tables of the *first-shared-library* and
200    *second-shared-library*.
201
202  * ``--deleted-fns``
203
204    In the resulting report about the differences between
205    *first-shared-library* and *second-shared-library*, only display
206    the globally defined functions that got deleted from
207    *first-shared-library*.
208
209  * ``--changed-fns``
210
211    In the resulting report about the differences between
212    *first-shared-library* and *second-shared-library*, only display
213    the changes in sub-types of the global functions defined in
214    *first-shared-library*.
215
216  * ``--added-fns``
217
218    In the resulting report about the differences between
219    *first-shared-library* and *second-shared-library*, only display
220    the globally defined functions that were added to
221    *second-shared-library*.
222
223  * ``--deleted-vars``
224
225    In the resulting report about the differences between
226    *first-shared-library* and *second-shared-library*, only display
227    the globally defined variables that were deleted from
228    *first-shared-library*.
229
230  * ``--changed-vars``
231
232    In the resulting report about the differences between
233    *first-shared-library* and *second-shared-library*, only display
234    the changes in the sub-types of the global variables defined in
235    *first-shared-library*
236
237  * ``--added-vars``
238
239    In the resulting report about the differences between
240    *first-shared-library* and *second-shared-library*, only display
241    the global variables that were added (defined) to
242    *second-shared-library*.
243
244  * ``--non-reachable-types|-t``
245
246    Analyze and emit change reports for all the types of the binary,
247    including those that are not reachable from global functions and
248    variables.
249
250    This option might incur some serious performance degradation as
251    the number of types analyzed can be huge.  However, if paired with
252    the ``--headers-dir{1,2}`` and/or ``header-file{1,2}`` options,
253    the additional non-reachable types analyzed are restricted to
254    those defined in public headers files, thus hopefully making the
255    performance hit acceptable.
256
257    Also, using this option alongside suppression specifications (by
258    also using the ``--suppressions`` option) might help keep the number of
259    analyzed types (and the potential performance degradation) in
260    control.
261
262    Note that without this option, only types that are reachable from
263    global functions and variables are analyzed, so the tool detects
264    and reports changes on these reachable types only.
265
266  * ``--no-added-syms``
267
268    In the resulting report about the differences between
269    *first-shared-library* and *second-shared-library*, do not display
270    added functions or variables.  Do not display added functions or
271    variables ELF symbols either.  All other kinds of changes are
272    displayed unless they are explicitely forbidden by other options
273    on the command line.
274
275  * ``--no-linkage-name``
276
277    In the resulting report, do not display the linkage names of
278    the added, removed, or changed functions or variables.
279
280  * ``--no-show-locs``
281
282   Do not show information about where in the *second shared library*
283   the respective type was changed.
284
285  * ``--show-bytes``
286
287    Show sizes and offsets in bytes, not bits.  By default, sizes and
288    offsets are shown in bits.
289
290  * ``--show-bits``
291
292    Show sizes and offsets in bits, not bytes.  This option is
293    activated by default.
294
295  * ``--show-hex``
296
297    Show sizes and offsets in hexadecimal base.
298
299  * ``--show-dec``
300
301    Show sizes and offsets in decimal base.  This option is activated
302    by default.
303
304  *  ``--no-show-relative-offset-changes``
305
306     Without this option, when the offset of a data member changes,
307     the change report not only mentions the older and newer offset,
308     but it also mentions by how many bits the data member changes.
309     With this option, the latter is not shown.
310
311  * ``--no-unreferenced-symbols``
312
313    In the resulting report, do not display change information about
314    function and variable symbols that are not referenced by any debug
315    information.  Note that for these symbols not referenced by any
316    debug information, the change information displayed is either
317    added or removed symbols.
318
319  * ``--no-default-suppression``
320
321    Do not load the :ref:`default suppression specification files
322    <abidiff_default_supprs_label>`.
323
324  * ``--suppressions | --suppr`` <*path-to-suppressions*>
325
326    Use a :ref:`suppression specification <suppr_spec_label>` file
327    located at *path-to-suppressions*.  Note that this option can
328    appear multiple times on the command line.  In that case, all of
329    the provided suppression specification files are taken into
330    account.
331
332    Please note that, by default, if this option is not provided, then
333    the :ref:`default suppression specification files
334    <abidiff_default_supprs_label>` are loaded .
335
336  * ``--drop`` <*regex*>
337
338    When reading the *first-shared-library* and
339    *second-shared-library* ELF input files, drop the globally defined
340    functions and variables which name match the regular expression
341    *regex*.  As a result, no change involving these functions or
342    variables will be emitted in the diff report.
343
344  * ``--drop-fn`` <*regex*>
345
346    When reading the *first-shared-library* and
347    *second-shared-library* ELF input files, drop the globally defined
348    functions which name match the regular expression *regex*.  As a
349    result, no change involving these functions will be emitted in the
350    diff report.
351
352  * ``--drop-var`` <*regex*>
353
354    When reading the *first-shared-library* and
355    *second-shared-library* ELF input files, drop the globally defined
356    variables matching a the regular expression *regex*.
357
358  * ``--keep`` <*regex*>
359
360    When reading the *first-shared-library* and
361    *second-shared-library* ELF input files, keep the globally defined
362    functions and variables which names match the regular expression
363    *regex*.  All other functions and variables are dropped on the
364    floor and will thus not appear in the resulting diff report.
365
366  * ``--keep-fn`` <*regex*>
367
368    When reading the *first-shared-library* and
369    *second-shared-library* ELF input files, keep the globally defined
370    functions which name match the regular expression *regex*.  All
371    other functions are dropped on the floor and will thus not appear
372    in the resulting diff report.
373
374  * ``--keep-var`` <*regex*>
375
376    When reading the *first-shared-library* and
377    *second-shared-library* ELF input files, keep the globally defined
378    which names match the regular expression *regex*.  All other
379    variables are dropped on the floor and will thus not appear in the
380    resulting diff report.
381
382  * ``--harmless``
383
384    In the diff report, display only the :ref:`harmless
385    <harmlesschangeconcept_label>` changes.  By default, the harmless
386    changes are filtered out of the diff report keep the clutter to a
387    minimum and have a greater chance to spot real ABI issues.
388
389  * ``--no-harmful``
390
391    In the diff report, do not display the :ref:`harmful
392    <harmfulchangeconcept_label>` changes.  By default, only the
393    harmful changes are displayed in diff report.
394
395  * ``--redundant``
396
397    In the diff report, do display redundant changes.  A redundant
398    change is a change that has been displayed elsewhere in the
399    report.
400
401  * ``--no-redundant``
402
403    In the diff report, do *NOT* display redundant changes.  A
404    redundant change is a change that has been displayed elsewhere in
405    the report.  This option is switched on by default.
406
407  * ``--no-architecture``
408
409    Do not take architecture in account when comparing ABIs.
410
411  * ``--no-corpus-path``
412
413    Do not emit the path attribute for the ABI corpus.
414
415  * ``--fail-no-debug-info``
416
417    If no debug info was found, then this option makes the program to
418    fail.  Otherwise, without this option, the program will attempt to
419    compare properties of the binaries that are not related to debug
420    info, like pure ELF properties.
421
422  * ``--leaf-changes-only|-l`` only show leaf changes, so don't show
423    impact analysis report.  This option implies ``--redundant``.
424
425    The typical output of abidiff when comparing two binaries looks
426    like this ::
427
428	$ abidiff libtest-v0.so libtest-v1.so
429	Functions changes summary: 0 Removed, 1 Changed, 0 Added function
430	Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
431
432	1 function with some indirect sub-type change:
433
434	  [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
435	    parameter 1 of type 'C&' has sub-type changes:
436	      in referenced type 'struct C' at test-v1.cc:7:1:
437		type size hasn't changed
438		1 data member change:
439		 type of 'leaf* C::m0' changed:
440		   in pointed to type 'struct leaf' at test-v1.cc:1:1:
441		     type size changed from 32 to 64 bits
442		     1 data member insertion:
443		       'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
444
445	$
446
447    So in that example the report emits information about how the data
448    member insertion change of "struct leaf" is reachable from
449    function "void fn(C&)".  In other words, the report not only shows
450    the data member change on "struct leaf", but it also shows the
451    impact of that change on the function "void fn(C&)".
452
453    In abidiff parlance, the change on "struct leaf" is called a leaf
454    change.  So the ``--leaf-changes-only --impacted-interfaces``
455    options show, well, only the leaf change.  And it goes like this:
456    ::
457
458	$ abidiff -l libtest-v0.so libtest-v1.so
459	'struct leaf' changed:
460	  type size changed from 32 to 64 bits
461	  1 data member insertion:
462	    'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1
463
464	  one impacted interface:
465	    function void fn(C&)
466	$
467
468    Note how the report ends by showing the list of interfaces
469    impacted by the leaf change.
470
471    Now if you don't want to see that list of impacted interfaces,
472    then you can just avoid using the ``--impacted-interface`` option.
473    You can learn about that option below, in any case.
474
475
476  * ``--impacted-interfaces``
477
478    When showing leaf changes, this option instructs abidiff to show
479    the list of impacted interfaces.  This option is thus to be used
480    in addition the ``--leaf-changes-only`` option, otherwise, it's
481    ignored.
482
483
484  *  ``--dump-diff-tree``
485
486    After the diff report, emit a textual representation of the diff
487    nodes tree used by the comparison engine to represent the changed
488    functions and variables.  That representation is emitted to the
489    error output for debugging purposes.  Note that this diff tree is
490    relevant only to functions and variables that have some sub-type
491    changes.  Added or removed functions and variables do not have any
492    diff nodes tree associated to them.
493
494  * ``--stats``
495
496    Emit statistics about various internal things.
497
498  * ``--verbose``
499
500    Emit verbose logs about the progress of miscellaneous internal
501    things.
502
503.. _abidiff_return_value_label:
504
505Return values
506=============
507
508The exit code of the ``abidiff`` command is either 0 if the ABI of the
509binaries being compared are equal, or non-zero if they differ or if
510the tool encountered an error.
511
512In the later case, the exit code is a 8-bits-wide bit field in which
513each bit has a specific meaning.
514
515The first bit, of value 1, named ``ABIDIFF_ERROR`` means there was an
516error.
517
518The second bit, of value 2, named ``ABIDIFF_USAGE_ERROR`` means there
519was an error in the way the user invoked the tool.  It might be set,
520for instance, if the user invoked the tool with an unknown command
521line switch, with a wrong number or argument, etc.  If this bit is
522set, then the ``ABIDIFF_ERROR`` bit must be set as well.
523
524The third bit, of value 4, named ``ABIDIFF_ABI_CHANGE`` means the ABI
525of the binaries being compared are different.
526
527The fourth bit, of value 8, named ``ABIDIFF_ABI_INCOMPATIBLE_CHANGE``
528means the ABI of the binaries compared are different in an
529incompatible way.  If this bit is set, then the ``ABIDIFF_ABI_CHANGE``
530bit must be set as well.  If the ``ABIDIFF_ABI_CHANGE`` is set and the
531``ABIDIFF_INCOMPATIBLE_CHANGE`` is *NOT* set, then it means that the
532ABIs being compared might or might not be compatible.  In that case, a
533human being needs to review the ABI changes to decide if they are
534compatible or not.
535
536Note that, at the moment, there are only a few kinds of ABI changes
537that would result in setting the flag ``ABIDIFF_ABI_INCOMPATIBLE_CHANGE``.
538Those ABI changes are either:
539
540  - the removal of the symbol of a function or variable that has been
541    defined and exported.
542  - the modification of the index of a member of a virtual function
543    table (for C++ programs and libraries).
544
545With time, when more ABI change patterns are found to *always*
546constitute incompatible ABI changes, we will adapt the code to
547recognize those cases and set the ``ABIDIFF_ABI_INCOMPATIBLE_CHANGE``
548accordingly.  So, if you find such patterns, please let us know.
549
550The remaining bits are not used for the moment.
551
552.. _abidiff_usage_example_label:
553
554Usage examples
555==============
556
557  1. Detecting a change in a sub-type of a function: ::
558
559	$ cat -n test-v0.cc
560		 1	// Compile this with:
561		 2	//   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
562		 3
563		 4	struct S0
564		 5	{
565		 6	  int m0;
566		 7	};
567		 8
568		 9	void
569		10	foo(S0* /*parameter_name*/)
570		11	{
571		12	  // do something with parameter_name.
572		13	}
573	$
574	$ cat -n test-v1.cc
575		 1	// Compile this with:
576		 2	//   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
577		 3
578		 4	struct type_base
579		 5	{
580		 6	  int inserted;
581		 7	};
582		 8
583		 9	struct S0 : public type_base
584		10	{
585		11	  int m0;
586		12	};
587		13
588		14	void
589		15	foo(S0* /*parameter_name*/)
590		16	{
591		17	  // do something with parameter_name.
592		18	}
593	$
594	$ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
595	$ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
596	$
597	$ ../build/tools/abidiff libtest-v0.so libtest-v1.so
598	Functions changes summary: 0 Removed, 1 Changed, 0 Added function
599	Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
600
601	1 function with some indirect sub-type change:
602
603	  [C]'function void foo(S0*)' has some indirect sub-type changes:
604		parameter 0 of type 'S0*' has sub-type changes:
605		  in pointed to type 'struct S0':
606		    size changed from 32 to 64 bits
607		    1 base class insertion:
608		      struct type_base
609		    1 data member change:
610		     'int S0::m0' offset changed from 0 to 32
611	$
612
613
614  2. Detecting another change in a sub-type of a function: ::
615
616	$ cat -n test-v0.cc
617		 1	// Compile this with:
618		 2	//   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
619		 3
620		 4	struct S0
621		 5	{
622		 6	  int m0;
623		 7	};
624		 8
625		 9	void
626		10	foo(S0& /*parameter_name*/)
627		11	{
628		12	  // do something with parameter_name.
629		13	}
630	$
631	$ cat -n test-v1.cc
632		 1	// Compile this with:
633		 2	//   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
634		 3
635		 4	struct S0
636		 5	{
637		 6	  char inserted_member;
638		 7	  int m0;
639		 8	};
640		 9
641		10	void
642		11	foo(S0& /*parameter_name*/)
643		12	{
644		13	  // do something with parameter_name.
645		14	}
646	$
647	$ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
648	$ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
649	$
650	$ ../build/tools/abidiff libtest-v0.so libtest-v1.so
651	Functions changes summary: 0 Removed, 1 Changed, 0 Added function
652	Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
653
654	1 function with some indirect sub-type change:
655
656	  [C]'function void foo(S0&)' has some indirect sub-type changes:
657		parameter 0 of type 'S0&' has sub-type changes:
658		  in referenced type 'struct S0':
659		    size changed from 32 to 64 bits
660		    1 data member insertion:
661		      'char S0::inserted_member', at offset 0 (in bits)
662		    1 data member change:
663		     'int S0::m0' offset changed from 0 to 32
664
665
666	$
667
668  3. Detecting that functions got removed or added to a library: ::
669
670	$ cat -n test-v0.cc
671		 1	// Compile this with:
672		 2	//   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
673		 3
674		 4	struct S0
675		 5	{
676		 6	  int m0;
677		 7	};
678		 8
679		 9	void
680		10	foo(S0& /*parameter_name*/)
681		11	{
682		12	  // do something with parameter_name.
683		13	}
684	$
685	$ cat -n test-v1.cc
686		 1	// Compile this with:
687		 2	//   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
688		 3
689		 4	struct S0
690		 5	{
691		 6	  char inserted_member;
692		 7	  int m0;
693		 8	};
694		 9
695		10	void
696		11	bar(S0& /*parameter_name*/)
697		12	{
698		13	  // do something with parameter_name.
699		14	}
700	$
701	$ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
702	$ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
703	$
704	$ ../build/tools/abidiff libtest-v0.so libtest-v1.so
705	Functions changes summary: 1 Removed, 0 Changed, 1 Added functions
706	Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
707
708	1 Removed function:
709	  'function void foo(S0&)'    {_Z3fooR2S0}
710
711	1 Added function:
712	  'function void bar(S0&)'    {_Z3barR2S0}
713
714	$
715
716.. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
717.. _DWARF: http://www.dwarfstd.org
718
719