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