1######### 2Concepts 3######### 4 5.. _abi_artifacts_label: 6 7ABI artifacts 8============= 9 10An ABI artifact is a relevant part of the ABI of a shared library or 11program. Examples of ABI artifacts are exported types, variables, 12functions, or `ELF`_ symbols exported by a shared library. 13 14The set of ABI artifact for a binary is called an ABI Corpus. 15 16.. _harmfulchangeconcept_label: 17 18Harmful changes 19=============== 20 21A change in the diff report is considered harmful if it might cause 22ABI compatibility issues. That is, it might prevent an application 23dynamically linked against a given version of a library to keep 24working with the changed subsequent versions of the same library. 25 26.. _harmlesschangeconcept_label: 27 28Harmless changes 29================ 30 31A change in the diff report is considered harmless if it will not 32cause any ABI compatibility issue. That is, it will not prevent an 33application dynamically linked against given version of a library to 34keep working with the changed subsequent versions of the same library. 35 36By default, ``abidiff`` filters harmless changes from the diff report. 37 38.. _suppr_spec_label: 39 40Suppression specifications 41========================== 42 43 44Definition 45---------- 46 47A suppression specification file is a way for a user to instruct 48:ref:`abidiff <abidiff_label>`, :ref:`abipkgdiff <abipkgdiff_label>` 49or any other relevant libabigail tool to avoid emitting reports for 50changes involving certain :ref:`ABI artifacts<abi_artifacts_label>`. 51 52It contains directives (or specifications) that describe the set of 53ABI artifacts to avoid emitting change reports about. 54 55Introductory examples 56--------------------- 57 58Its syntax is based on a simplified and customized form of `Ini File 59Syntax`_. For instance, to specify that change reports on a type 60named FooPrivateType should be suppressed, one could write this 61suppression specification: :: 62 63 [suppress_type] 64 name = FooPrivateType 65 66If we want to ensure that only change reports about structures named 67FooPrivateType should be suppressed, we could write: :: 68 69 [suppress_type] 70 type_kind = struct 71 name = FooPrivateType 72 73But we could also want to suppress change reports avoid typedefs named 74FooPrivateType. In that case we would write: :: 75 76 [suppress_type] 77 type_kind = typedef 78 name = FooPrivateType 79 80Or, we could want to suppress change reports about all struct which 81names end with the string "PrivateType": :: 82 83 [suppress_type] 84 type_kind = struct 85 name_regexp = ^.*PrivateType 86 87Let's now look at the generic syntax of suppression specification 88files. 89 90Syntax 91------ 92 93Properties 94^^^^^^^^^^ 95 96More generally, the format of suppression lists is organized around 97the concept of `property`. Every property has a name and a value, 98delimited by the ``=`` sign. E.g: :: 99 100 name = value 101 102Leading and trailing white spaces are ignored around property names 103and values. 104 105.. _suppr_regexp_label: 106 107Regular expressions 108^^^^^^^^^^^^^^^^^^^ 109 110The value of some properties might be a regular expression. In that 111case, they must comply with the syntax of `extended POSIX regular 112expressions 113<http://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002dextended-regular-expression-syntax.html#posix_002dextended-regular-expression-syntax>`_. 114Note that Libabigail uses the regular expression engine of the `GNU C 115Library`_. 116 117Escaping a character in a regular expression 118^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 119 120When trying to match a string that contains a ``*`` character, like in 121the pointer type ``int*``, one must be careful to notice that the 122character ``*`` is a special character in the extended POSIX regular 123expression syntax. And that character must be escaped for the regular 124expression engine. Thus the regular expression that would match the 125string ``int*`` in a suppression file should be :: 126 127 int\\* 128 129Wait; but then why the two ``\`` characters? Well, because the ``\`` 130character is a special character in the `Ini File Syntax`_ used for 131specifying suppressions. So it must be escaped as well, so that the 132Ini File parser leaves a ``\`` character intact in the data stream 133that is handed to the regular expression engine. Hence the ``\\`` 134targeted at the Ini File parser. 135 136So, in short, to escape a character in a regular expression, always 137prefix the character with the ``\\`` sequence. 138 139Modus operandi 140^^^^^^^^^^^^^^ 141 142 143Suppression specifications can be applied at two different points of 144the processing pipeline of libabigail. 145 146.. _late_suppression_mode_label: 147 148In the default operating mode called "late suppression mode", 149suppression specifications are applied to the result of comparing the 150in-memory internal representations of two ABIs. In this mode, if an 151ABI artifact matches a suppression specification, its changes are not 152mentioned in the ABI change report. The internal representation of 153the "suppressed" changed ABI artifact is still present in memory; it 154is just not mentioned in the ABI change report. The change report can 155still mention statistics about the number of changed ABI artifacts 156that were suppressed. 157 158.. _early_suppression_mode_label: 159 160There is another operating mode called the "early suppression mode" 161where suppression specifications are applied during the construction 162of the in-memory internal representation of a given ABI. In that 163mode, if an ABI artifact matches a suppression specification, no 164in-memory internal representation is built for it. As a result, no 165change about the matched ABI artifact is going to be mentioned in the 166ABI change report and no statistic about the number of suppressed ABI 167changes is available. Also, please note that because suppressed ABI 168artifacts are removed from the in-memory internal representation in 169this mode, the amount memory used by the internal representation is 170potentially smaller than the memory consumption in the late 171suppression mode. 172 173Sections 174^^^^^^^^ 175 176Properties are then grouped into arbitrarily named sections that shall 177not be nested. The name of the section is on a line by itself and is 178surrounded by square brackets, i.e: :: 179 180 [section_name] 181 property1_name = property1_value 182 property2_name = property2_value 183 184 185A section might or might not have properties. Sections that expect to 186have properties and which are found nonetheless empty are just 187ignored. Properties that are not recognized by the reader are ignored 188as well. 189 190Section names 191^^^^^^^^^^^^^ 192 193Each different section can be thought of as being a directive to 194suppress ABI change reports for a particular kind of ABI artifact. 195 196``[suppress_file]`` 197$$$$$$$$$$$$$$$$$$$ 198 199This directive prevents a given tool from loading a file (binary or 200abixml file) if its file name or other properties match certain 201properties. Thus, if the tool is meant to compare the ABIs of two 202files, and if the directive prevents it from loading either one of the 203files, then no comparison is performed. 204 205Note that for the ``[suppress_file]`` directive to work, at least one 206of the following properties must be provided: 207 208 ``file_name_regexp``, ``file_name_not_regexp``, ``soname_regexp``, 209 ``soname_not_regexp``. 210 211If none of the above properties are provided, then the 212``[suppress_file]`` directive is simply ignored. 213 214The potential properties of this sections are listed below: 215 216* ``file_name_regexp`` 217 218 Usage: 219 220 ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 221 222 Prevents the system from loading the file which name matches the 223 regular expression specified as value of this property. 224 225* ``file_name_not_regexp`` 226 227 Usage: 228 229 ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 230 231 Prevents the system from loading the file which name does not match 232 the regular expression specified as value of this property. 233 234 235* ``soname_regexp`` 236 237 Usage: 238 239 ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 240 241 Prevents the system from loading the file which contains a SONAME 242 property that matches the regular expression of this property. Note 243 that this property also works on an abixml file if it contains a 244 SONAME property. 245 246* ``soname_not_regexp`` 247 248 Usage: 249 250 ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 251 252 Prevents the system from loading the file which contains a SONAME 253 property that does *NOT* match the regular expression of this 254 property. Note that this property also works on an abixml file if 255 it contains a SONAME property. 256 257* ``label`` 258 259 Usage: 260 261 ``label`` ``=`` <some-value> 262 263 Define a label for the section. A label is just an informative 264 string that might be used by the tool to refer to a type suppression 265 in error messages. 266 267``[suppress_type]`` 268$$$$$$$$$$$$$$$$$$$ 269 270This directive suppresses report messages about a type change. 271 272Note that for the ``[suppress_type]`` directive to work, at least one 273of the following properties must be provided: 274 275 ``file_name_regexp``, ``file_name_not_regexp``, ``soname_regexp``, 276 ``soname_not_regexp``, ``name``, ``name_regexp``, 277 ``name_not_regexp``, ``type_kind``, ``source_location_not_in``, 278 ``source_location_not_regexp``. 279 280If none of the above properties are provided, then the 281``[suppress_type]`` directive is simply ignored. 282 283The potential properties of this sections are listed below: 284 285* ``file_name_regexp`` 286 287 Usage: 288 289 ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 290 291 Suppresses change reports about ABI artifacts that are defined in a 292 binary file which name matches the regular expression specified as 293 value of this property. 294 295* ``file_name_not_regexp`` 296 297 Usage: 298 299 ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 300 301 Suppresses change reports about ABI artifacts that are defined in a 302 binary file which name does not match the regular expression 303 specified as value of this property. 304 305 306* ``soname_regexp`` 307 308 Usage: 309 310 ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 311 312 Suppresses change reports about ABI artifacts that are defined in a 313 shared library which SONAME property matches the regular expression 314 specified as value of this property. 315 316* ``soname_not_regexp`` 317 318 Usage: 319 320 ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 321 322 Suppresses change reports about ABI artifacts that are defined in a 323 shared library which SONAME property does not match the regular 324 expression specified as value of this property. 325 326* ``name_regexp`` 327 328 Usage: 329 330 ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 331 332 Suppresses change reports involving types whose name matches the 333 regular expression specified as value of this property. 334 335 336* ``name_not_regexp`` 337 338 Usage: 339 340 ``name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 341 342 Suppresses change reports involving types whose name does *NOT* match 343 the regular expression specified as value of this property. Said 344 otherwise, this property specifies which types to keep, rather than 345 types to suppress from reports. 346 347* ``name`` 348 349 Usage: 350 351 ``name`` ``=`` <a-value> 352 353 Suppresses change reports involving types whose name equals the value 354 of this property. 355 356* ``type_kind`` 357 358 Usage: 359 360 ``type_kind`` ``=`` ``class`` | ``struct`` | ``union`` | ``enum`` | 361 ``array`` | ``typedef`` | ``builtin`` 362 363 Suppresses change reports involving a certain kind of type. The kind 364 of type to suppress change reports for is specified by the possible 365 values listed above: 366 367 - ``class``: suppress change reports for class types. Note that 368 even if class types don't exist for C, this value still 369 triggers the suppression of change reports for struct types, 370 in C. In C++ however, it should do what it suggests. 371 372 - ``struct``: suppress change reports for struct types in C or C++. 373 Note that the value ``class`` above is a super-set of this 374 one. 375 376 - ``union``: suppress change reports for union types. 377 378 - ``enum``: suppress change reports for enum types. 379 380 - ``array``: suppress change reports for array types. 381 382 - ``typedef``: suppress change reports for typedef types. 383 384 - ``builtin``: suppress change reports for built-in (or native) 385 types. Example of built-in types are char, int, unsigned int, 386 etc. 387 388 .. _suppr_source_location_not_in_label: 389 390* ``source_location_not_in`` 391 392 Usage: 393 394 ``source_location_not_in`` ``=`` <``list-of-file-paths``> 395 396 Suppresses change reports involving a type which is defined in a file 397 which path is *NOT* listed in the value ``list-of-file-paths``. Note 398 that the value is a comma-separated list of file paths e.g, this 399 property :: 400 401 source_location_not_in = libabigail/abg-ir.h, libabigail/abg-dwarf-reader.h 402 403 suppresses change reports about all the types that are *NOT* defined 404 in header files whose path end up with the strings 405 libabigail/abg-ir.h or libabigail/abg-dwarf-reader.h. 406 407 .. _suppr_source_location_not_regexp_label: 408 409* ``source_location_not_regexp`` 410 411 Usage: 412 413 ``source_location_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 414 415 Suppresses change reports involving a type which is defined in a file 416 which path does *NOT* match the :ref:`regular expression 417 <suppr_regexp_label>` provided as value of the property. E.g, this 418 property :: 419 420 source_location_not_regexp = libabigail/abg-.*\\.h 421 422 suppresses change reports involving all the types that are *NOT* 423 defined in header files whose path match the regular expression 424 provided a value of the property. 425 426 .. _suppr_has_data_member_inserted_at_label: 427 428* ``has_data_member_inserted_at`` 429 430 Usage: 431 432 ``has_data_member_inserted_at`` ``=`` <``offset-in-bit``> 433 434 Suppresses change reports involving a type which has at least one 435 data member inserted at an offset specified by the property value 436 ``offset-in-bit``. The value ``offset-in-bit`` is either: 437 438 - an integer value, expressed in bits, which denotes the 439 offset of the insertion point of the data member, starting 440 from the beginning of the relevant structure or class. 441 442 - the keyword ``end`` which is a named constant which value 443 equals the offset of the end of the of the structure or 444 class. 445 446 - the function call expression 447 ``offset_of(data-member-name)`` where `data-member-name` is 448 the name of a given data member of the relevant structure 449 or class. The value of this function call expression is an 450 integer that represents the offset of the data member 451 denoted by ``data-member-name``. 452 453 - the function call expression 454 ``offset_after(data-member-name)`` where `data-member-name` 455 is the name of a given data member of the relevant 456 structure or class. The value of this function call 457 expression is an integer that represents the offset of the 458 point that comes right after the region occupied by the 459 data member denoted by ``data-member-name``. 460 461 .. _suppr_has_data_member_inserted_between_label: 462 463 464* ``has_data_member_inserted_between`` 465 466 Usage: 467 468 ``has_data_member_inserted_between`` ``=`` {<``range-begin``>, <``range-end``>} 469 470 Suppresses change reports involving a type which has at least one 471 data mber inserted at an offset that is comprised in the range 472 between range-begin`` and ``range-end``. Please note that each of 473 the lues ``range-begin`` and ``range-end`` can be of the same form as 474 the :ref:`has_data_member_inserted_at 475 <suppr_has_data_member_inserted_at_label>` property above. 476 477 Usage examples of this properties are: :: 478 479 has_data_member_inserted_between = {8, 64} 480 481 or: :: 482 483 has_data_member_inserted_between = {16, end} 484 485 or: :: 486 487 has_data_member_inserted_between = {offset_after(member1), end} 488 489.. _suppr_has_data_members_inserted_between_label: 490 491 492* ``has_data_members_inserted_between`` 493 494 Usage: 495 496 ``has_data_members_inserted_between`` ``=`` {<sequence-of-ranges>} 497 498 Suppresses change reports involving a type which has multiple data 499 member inserted in various offset ranges. A usage example of this 500 property is, for instance: :: 501 502 has_data_members_inserted_between = {{8, 31}, {72, 95}} 503 504 This usage example suppresses change reports involving a type which 505 has data members inserted in bit offset ranges [8 31] and [72 95]. 506 The length of the sequence of ranges or this 507 ``has_data_members_inserted_between`` is not bounded; it can be as 508 long as the system can cope with. The values of the boundaries of 509 the ranges are of the same kind as for the 510 :ref:`has_data_member_inserted_at 511 <suppr_has_data_member_inserted_at_label>` property above. 512 513 Another usage example of this property is thus: :: 514 515 has_data_members_inserted_between = 516 { 517 {offset_after(member0), offset_of(member1)}, 518 {72, end} 519 } 520 521 .. _suppr_accessed_through_property_label: 522 523* ``accessed_through`` 524 525 Usage: 526 527 ``accessed_through`` ``=`` <some-predefined-values> 528 529 Suppress change reports involving a type which is referred to either 530 directly or through a pointer or a reference. The potential values 531 of this property are the predefined keywords below: 532 533 * ``direct`` 534 535 So if the ``[suppress_type]`` contains the property 536 description: :: 537 538 accessed_through = direct 539 540 then changes about a type that is referred-to 541 directly (i.e, not through a pointer or a reference) 542 are going to be suppressed. 543 544 * ``pointer`` 545 546 If the ``accessed_through`` property is set to the 547 value ``pointer`` then changes about a type that is 548 referred-to through a pointer are going to be 549 suppressed. 550 551 * ``reference`` 552 553 If the ``accessed_through`` property is set to the 554 value ``reference`` then changes about a type that is 555 referred-to through a reference are going to be 556 suppressed. 557 558 * ``reference-or-pointer`` 559 560 If the ``accessed_through`` property is set to the 561 value ``reference-or-pointer`` then changes about a 562 type that is referred-to through either a reference 563 or a pointer are going to be suppressed. 564 565 For an extensive example of how to use this property, please check 566 out the example below about :ref:`suppressing change reports about 567 types accessed either directly or through pointers 568 <example_accessed_through_label>`. 569 570* ``drop`` 571 572 Usage: 573 574 ``drop`` ``=`` yes | no 575 576 If a type is matched by a suppression specification which contains 577 the "drop" property set to "yes" (or to "true") then the type is not 578 even going to be represented in the internal representation of the 579 ABI being analyzed. This property makes its enclosing suppression 580 specification to be applied in the :ref:`early suppression 581 specification mode <early_suppression_mode_label>`. The net effect 582 is that it potentially reduces the memory used to represent the ABI 583 being analyzed. 584 585 Please note that for this property to be effective, the enclosing 586 suppression specification must have at least one of the following 587 properties specified: ``name_regexp``, ``name``, ``name_regexp``, 588 ``source_location_not_in`` or ``source_location_not_regexp``. 589 590 .. _suppr_label_property_label: 591 592* ``label`` 593 594 Usage: 595 596 ``label`` ``=`` <some-value> 597 598 Define a label for the section. A label is just an informative 599 string that might be used by a tool to refer to a type suppression in 600 error messages. 601 602.. _suppr_changed_enumerators_label: 603 604* ``changed_enumerators`` 605 606 Usage: 607 608 ``changed_enumerators`` ``=`` <list-of-enumerators> 609 610 Suppresses change reports involving changes in the value of 611 enumerators of a given enum type. This property is applied if the 612 ``type_kind`` property is set to the value ``enum``, at least. The 613 value of the ``changed_enumerators`` is a comma-separated list of 614 the enumerators that the user expects to change. For instance: :: 615 616 changed_enumerators = LAST_ENUMERATORS0, LAST_ENUMERATOR1 617 618``[suppress_function]`` 619$$$$$$$$$$$$$$$$$$$$$$$$ 620 621This directive suppresses report messages about changes on a set of 622functions. 623 624Note that for the ``[suppress_function]`` directive to work, at least 625one of the following properties must be provided: 626 627 ``label``, ``file_name_regexp``, ``file_name_not_regexp``, 628 ``soname_regexp``, ``soname_not_regexp``, ``name``, ``name_regexp``, 629 ``name_not_regexp``, ``parameter``, ``return_type_name``, 630 ``return_type_regexp``, ``symbol_name``, ``symbol_name_regexp``, 631 ``symbol_name_not_regexp``, ``symbol_version``, 632 ``symbol_version_regexp``. 633 634If none of the above properties are provided, then the 635``[suppress_function]`` directive is simply ignored. 636 637The potential properties of this sections are: 638 639* ``label`` 640 641 Usage: 642 643 ``label`` ``=`` <some-value> 644 645 This property is the same as the :ref:`label property 646 <suppr_label_property_label>` defined above. 647 648 649* ``file_name_regexp`` 650 651 Usage: 652 653 ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 654 655 Suppresses change reports about ABI artifacts that are defined in a 656 binary file which name matches the regular expression specified as 657 value of this property. 658 659 660* ``file_name_not_regexp`` 661 662 Usage: 663 664 ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 665 666 Suppresses change reports about ABI artifacts that are defined in a 667 binary file which name does not match the regular expression 668 specified as value of this property. 669 670* ``soname_regexp`` 671 672 Usage: 673 674 ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 675 676 Suppresses change reports about ABI artifacts that are defined in a 677 shared library which SONAME property matches the regular expression 678 specified as value of this property. 679 680* ``soname_not_regexp`` 681 682 Usage: 683 684 ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 685 686 Suppresses change reports about ABI artifacts that are defined in a 687 shared library which SONAME property does not match the regular 688 expression specified as value of this property. 689 690 691* ``name`` 692 693 Usage: 694 695 ``name`` ``=`` <some-value> 696 697 Suppresses change reports involving functions whose name equals the 698 value of this property. 699 700* ``name_regexp`` 701 702 Usage: 703 704 ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 705 706 Suppresses change reports involving functions whose name matches the 707 regular expression specified as value of this property. 708 709 Let's consider the case of functions that have several symbol names. 710 This happens when the underlying symbol for the function has 711 aliases. Each symbol name is actually one alias name. 712 713 In this case, if the regular expression matches the name of 714 at least one of the aliases names, then it must match the names of 715 all of the aliases of the function for the directive to actually 716 suppress the diff reports for said function. 717 718 719* ``name_not_regexp`` 720 721 Usage: 722 723 ``name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 724 725 Suppresses change reports involving functions whose names don't match 726 the regular expression specified as value of this property. 727 728 The rules for functions that have several symbol names are the same 729 rules as for the ``name_regexp`` property above. 730 731 .. _suppr_change_kind_property_label: 732 733 734* ``change_kind`` 735 736 Usage: 737 738 ``change_kind`` ``=`` <predefined-possible-values> 739 740 Specifies the kind of changes this suppression specification should 741 apply to. The possible values of this property as well as their 742 meaning are listed below: 743 744 - ``function-subtype-change`` 745 746 This suppression specification applies to functions 747 that which have at least one sub-type that has 748 changed. 749 750 - ``added-function`` 751 752 This suppression specification applies to functions 753 that have been added to the binary. 754 755 - ``deleted-function`` 756 757 This suppression specification applies to functions 758 that have been removed from the binary. 759 760 - ``all`` 761 762 This suppression specification applies to functions 763 that have all of the changes above. Note that not 764 providing the ``change_kind`` property at all is 765 equivalent to setting it to the value ``all``. 766 767 768* ``parameter`` 769 770 Usage: 771 772 ``parameter`` ``=`` <function-parameter-specification> 773 774 Suppresses change reports involving functions whose 775 parameters match the parameter specification indicated as 776 value of this property. 777 778 The format of the function parameter specification is: 779 780 ``'`` ``<parameter-index>`` ``<space>`` ``<type-name-or-regular-expression>`` 781 782 That is, an apostrophe followed by a number that is the 783 index of the parameter, followed by one of several spaces, 784 followed by either the name of the type of the parameter, 785 or a regular expression describing a family of parameter 786 type names. 787 788 If the parameter type name is designated by a regular 789 expression, then said regular expression must be enclosed 790 between two slashes; like ``/some-regular-expression/``. 791 792 The index of the first parameter of the function is zero. 793 Note that for member functions (methods of classes), the 794 this is the first parameter that comes after the implicit 795 "this" pointer parameter. 796 797 Examples of function parameter specifications are: :: 798 799 '0 int 800 801 Which means, the parameter at index 0, whose type name is 802 ``int``. :: 803 804 '4 unsigned char* 805 806 Which means, the parameter at index 4, whose type name is 807 ``unsigned char*``. :: 808 809 '2 /^foo.*&/ 810 811 Which means, the parameter at index 2, whose type name 812 starts with the string "foo" and ends with an '&'. In 813 other words, this is the third parameter and it's a 814 reference on a type that starts with the string "foo". 815 816* ``return_type_name`` 817 818 Usage: 819 820 ``return_type_name`` ``=`` <some-value> 821 822 Suppresses change reports involving functions whose return type name 823 equals the value of this property. 824 825* ``return_type_regexp`` 826 827 Usage: 828 829 ``return_type_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 830 831 Suppresses change reports involving functions whose return type name 832 matches the regular expression specified as value of this property. 833 834* ``symbol_name`` 835 836 Usage: 837 838 ``symbol_name`` ``=`` <some-value> 839 840 Suppresses change reports involving functions whose symbol name equals 841 the value of this property. 842 843* ``symbol_name_regexp`` 844 845 Usage: 846 847 ``symbol_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 848 849 Suppresses change reports involving functions whose symbol name 850 matches the regular expression specified as value of this property. 851 852 Let's consider the case of functions that have several symbol names. 853 This happens when the underlying symbol for the function has 854 aliases. Each symbol name is actually one alias name. 855 856 In this case, the regular expression must match the names of all of 857 the aliases of the function for the directive to actually suppress 858 the diff reports for said function. 859 860* ``symbol_name_not_regexp`` 861 862 Usage: 863 864 ``symbol_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 865 866 Suppresses change reports involving functions whose symbol name does 867 not match the regular expression specified as value of this property. 868 869* ``symbol_version`` 870 871 Usage: 872 873 ``symbol_version`` ``=`` <some-value> 874 875 Suppresses change reports involving functions whose symbol version 876 equals the value of this property. 877 878* ``symbol_version_regexp`` 879 880 Usage: 881 882 ``symbol_version_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 883 884 Suppresses change reports involving functions whose symbol version 885 matches the regular expression specified as value of this property. 886 887* ``drop`` 888 889 Usage: 890 891 ``drop`` ``=`` yes | no 892 893 If a function is matched by a suppression specification which 894 contains the "drop" property set to "yes" (or to "true") then the 895 function is not even going to be represented in the internal 896 representation of the ABI being analyzed. This property makes its 897 enclosing suppression specification to be applied in the :ref:`early 898 suppression specification mode <early_suppression_mode_label>`. The 899 net effect is that it potentially reduces the memory used to 900 represent the ABI being analyzed. 901 902 Please note that for this property to be effective, the enclosing 903 suppression specification must have at least one of the following 904 properties specified: ``name_regexp``, ``name``, ``name_regexp``, 905 ``source_location_not_in`` or ``source_location_not_regexp``. 906 907``[suppress_variable]`` 908$$$$$$$$$$$$$$$$$$$$$$$$ 909 910This directive suppresses report messages about changes on a set of 911variables. 912 913Note that for the ``[suppress_variable]`` directive to work, at least 914one of the following properties must be provided: 915 916 ``label``, ``file_name_regexp``, ``file_name_not_regexp``, 917 ``soname_regexp``, ``soname_not_regexp``, ``name``, ``name_regexp``, 918 ``name_not_regexp``, ``symbol_name``, ``symbol_name_regexp``, 919 ``symbol_name_not_regexp``, ``symbol_version``, 920 ``symbol_version_regexp``, ``type_name``, ``type_name_regexp``. 921 922If none of the above properties are provided, then the 923``[suppress_variable]`` directive is simply ignored. 924 925The potential properties of this sections are: 926 927* ``label`` 928 929 Usage: 930 931 ``label`` ``=`` <some-value> 932 933 This property is the same as the :ref:`label property 934 <suppr_label_property_label>` defined above. 935 936 937* ``file_name_regexp`` 938 939 Usage: 940 941 ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 942 943 Suppresses change reports about ABI artifacts that are defined in a 944 binary file which name matches the regular expression specified as 945 value of this property. 946 947* ``file_name_not_regexp`` 948 949 Usage: 950 951 ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 952 953 Suppresses change reports about ABI artifacts that are defined in a 954 binary file which name does not match the regular expression 955 specified as value of this property. 956 957 958* ``soname_regexp`` 959 960 Usage: 961 962 ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 963 964 Suppresses change reports about ABI artifacts that are defined in a 965 shared library which SONAME property matches the regular expression 966 specified as value of this property. 967 968 969* ``soname_not_regexp`` 970 971 Usage: 972 973 ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 974 975 Suppresses change reports about ABI artifacts that are defined in a 976 shared library which SONAME property does not match the regular 977 expression specified as value of this property. 978 979 980* ``name`` 981 982 Usage: 983 984 ``name`` ``=`` <some-value> 985 986 Suppresses change reports involving variables whose name equals the 987 value of this property. 988 989* ``name_regexp`` 990 991 Usage: 992 993 ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 994 995 Suppresses change reports involving variables whose name matches the 996 regular expression specified as value of this property. 997 998* ``change_kind`` 999 1000 Usage: 1001 1002 ``change_kind`` ``=`` <predefined-possible-values> 1003 1004 Specifies the kind of changes this suppression specification should 1005 apply to. The possible values of this property as well as their 1006 meaning are the same as when it's :ref:`used in the 1007 [suppress_function] section <suppr_change_kind_property_label>`. 1008 1009* ``symbol_name`` 1010 1011 Usage: 1012 1013 ``symbol_name`` ``=`` <some-value> 1014 1015 Suppresses change reports involving variables whose symbol name equals 1016 the value of this property. 1017 1018* symbol_name_regexp 1019 1020 Usage: 1021 1022 ``symbol_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 1023 1024 Suppresses change reports involving variables whose symbol name 1025 matches the regular expression specified as value of this property. 1026 1027 1028* ``symbol_name_not_regexp`` 1029 1030 Usage: 1031 1032 ``symbol_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 1033 1034 Suppresses change reports involving variables whose symbol name does 1035 not match the regular expression specified as value of this property. 1036 1037* ``symbol_version`` 1038 1039 Usage: 1040 1041 ``symbol_version`` ``=`` <some-value> 1042 1043 Suppresses change reports involving variables whose symbol version 1044 equals the value of this property. 1045 1046* ``symbol_version_regexp`` 1047 1048 Usage: 1049 1050 ``symbol_version_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 1051 1052 Suppresses change reports involving variables whose symbol version 1053 matches the regular expression specified as value of this property. 1054 1055* ``type_name`` 1056 1057 Usage: 1058 1059 ``type_name`` ``=`` <some-value> 1060 1061 Suppresses change reports involving variables whose type name equals 1062 the value of this property. 1063 1064* ``type_name_regexp`` 1065 1066 Usage: 1067 1068 ``type_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 1069 1070 Suppresses change reports involving variables whose type name matches 1071 the regular expression specified as value of this property. 1072 1073Comments 1074^^^^^^^^ 1075 1076``;`` or ``#`` ASCII character at the beginning of a line 1077indicates a comment. Comment lines are ignored. 1078 1079Code examples 1080^^^^^^^^^^^^^ 1081 10821. Suppressing change reports about types. 1083 1084 Suppose we have a library named ``libtest1-v0.so`` which 1085 contains this very useful code: :: 1086 1087 $ cat -n test1-v0.cc 1088 1 // A forward declaration for a type considered to be opaque to 1089 2 // function foo() below. 1090 3 struct opaque_type; 1091 4 1092 5 // This function cannot touch any member of opaque_type. Hence, 1093 6 // changes to members of opaque_type should not impact foo, as far as 1094 7 // ABI is concerned. 1095 8 void 1096 9 foo(opaque_type*) 1097 10 { 1098 11 } 1099 12 1100 13 struct opaque_type 1101 14 { 1102 15 int member0; 1103 16 char member1; 1104 17 }; 1105 $ 1106 1107Let's change the layout of struct opaque_type by inserting a data 1108member around line 15, leading to a new version of the library, 1109that we shall name ``libtest1-v1.so``: :: 1110 1111 $ cat -n test1-v1.cc 1112 1 // A forward declaration for a type considered to be opaque to 1113 2 // function foo() below. 1114 3 struct opaque_type; 1115 4 1116 5 // This function cannot touch any member of opaque_type; Hence, 1117 6 // changes to members of opaque_type should not impact foo, as far as 1118 7 // ABI is concerned. 1119 8 void 1120 9 foo(opaque_type*) 1121 10 { 1122 11 } 1123 12 1124 13 struct opaque_type 1125 14 { 1126 15 char added_member; // <-- a new member got added here now. 1127 16 int member0; 1128 17 char member1; 1129 18 }; 1130 $ 1131 1132Let's compile both examples. We shall not forget to compile them 1133with debug information generation turned on: :: 1134 1135 $ g++ -shared -g -Wall -o libtest1-v0.so test1-v0.cc 1136 $ g++ -shared -g -Wall -o libtest1-v1.so test1-v1.cc 1137 1138Let's ask :ref:`abidiff <abidiff_label>` which ABI differences it sees 1139between ``libtest1-v0.so`` and ``libtest1-v1.so``: :: 1140 1141 $ abidiff libtest1-v0.so libtest1-v1.so 1142 Functions changes summary: 0 Removed, 1 Changed, 0 Added function 1143 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1144 1145 1 function with some indirect sub-type change: 1146 1147 [C]'function void foo(opaque_type*)' has some indirect sub-type changes: 1148 parameter 0 of type 'opaque_type*' has sub-type changes: 1149 in pointed to type 'struct opaque_type': 1150 size changed from 64 to 96 bits 1151 1 data member insertion: 1152 'char opaque_type::added_member', at offset 0 (in bits) 1153 2 data member changes: 1154 'int opaque_type::member0' offset changed from 0 to 32 1155 'char opaque_type::member1' offset changed from 32 to 64 1156 1157 1158So ``abidiff`` reports that the opaque_type's layout has changed 1159in a significant way, as far as ABI implications are concerned, in 1160theory. After all, a sub-type (``struct opaque_type``) of an 1161exported function (``foo()``) has seen its layout change. This 1162might have non negligible ABI implications. But in practice here, 1163the programmer of the litest1-v1.so library knows that the "soft" 1164contract between the function ``foo()`` and the type ``struct 1165opaque_type`` is to stay away from the data members of the type. 1166So layout changes of ``struct opaque_type`` should not impact 1167``foo()``. 1168 1169Now to teach ``abidiff`` about this soft contract and have it 1170avoid emitting what amounts to false positives in this case, we 1171write the suppression specification file below: :: 1172 1173 $ cat test1.suppr 1174 [suppress_type] 1175 type_kind = struct 1176 name = opaque_type 1177 1178Translated in plain English, this suppression specification would 1179read: "Do not emit change reports about a struct which name is 1180opaque_type". 1181 1182Let's now invoke ``abidiff`` on the two versions of the library 1183again, but this time with the suppression specification: :: 1184 1185 $ abidiff --suppressions test1.suppr libtest1-v0.so libtest1-v1.so 1186 Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function 1187 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1188 1189As you can see, ``abidiff`` does not report the change anymore; it 1190tells us that it was filtered out instead. 1191 1192Suppressing change reports about types with data member 1193insertions 1194 1195Suppose the first version of a library named ``libtest3-v0.so`` 1196has this source code: :: 1197 1198 /* Compile this with: 1199 gcc -g -Wall -shared -o libtest3-v0.so test3-v0.c 1200 */ 1201 1202 struct S 1203 { 1204 char member0; 1205 int member1; /* 1206 between member1 and member2, there is some padding, 1207 at least on some popular platforms. On 1208 these platforms, adding a small enough data 1209 member into that padding shouldn't change 1210 the offset of member1. Right? 1211 */ 1212 }; 1213 1214 int 1215 foo(struct S* s) 1216 { 1217 return s->member0 + s->member1; 1218 } 1219 1220Now, suppose the second version of the library named 1221``libtest3-v1.so`` has this source code in which a data member 1222has been added in the padding space of struct S and another data 1223member has been added at its end: :: 1224 1225 /* Compile this with: 1226 gcc -g -Wall -shared -o libtest3-v1.so test3-v1.c 1227 */ 1228 1229 struct S 1230 { 1231 char member0; 1232 char inserted1; /* <---- A data member has been added here... */ 1233 int member1; 1234 char inserted2; /* <---- ... and another one has been added here. */ 1235 }; 1236 1237 int 1238 foo(struct S* s) 1239 { 1240 return s->member0 + s->member1; 1241 } 1242 1243 1244In libtest3-v1.so, adding char data members ``S::inserted1`` and 1245``S::inserted2`` can be considered harmless (from an ABI compatibility 1246perspective), at least on the x86 platform, because that doesn't 1247change the offsets of the data members S::member0 and S::member1. But 1248then running ``abidiff`` on these two versions of library yields: :: 1249 1250 $ abidiff libtest3-v0.so libtest3-v1.so 1251 Functions changes summary: 0 Removed, 1 Changed, 0 Added function 1252 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1253 1254 1 function with some indirect sub-type change: 1255 1256 [C]'function int foo(S*)' has some indirect sub-type changes: 1257 parameter 0 of type 'S*' has sub-type changes: 1258 in pointed to type 'struct S': 1259 type size changed from 64 to 96 bits 1260 2 data member insertions: 1261 'char S::inserted1', at offset 8 (in bits) 1262 'char S::inserted2', at offset 64 (in bits) 1263 $ 1264 1265 1266 1267That is, ``abidiff`` shows us the two changes, even though we (the 1268developers of that very involved library) know that these changes 1269are harmless in this particular context. 1270 1271Luckily, we can devise a suppression specification that essentially 1272tells abidiff to filter out change reports about adding a data 1273member between ``S::member0`` and ``S::member1``, and adding a data 1274member at the end of struct S. We have written such a suppression 1275specification in a file called test3-1.suppr and it unsurprisingly 1276looks like: :: 1277 1278 [suppress_type] 1279 name = S 1280 has_data_member_inserted_between = {offset_after(member0), offset_of(member1)} 1281 has_data_member_inserted_at = end 1282 1283 1284Now running ``abidiff`` with this suppression specification yields: :: 1285 1286 $ ../build/tools/abidiff --suppressions test3-1.suppr libtest3-v0.so libtest3-v1.so 1287 Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function 1288 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1289 1290 $ 1291 1292 1293Hooora! \\o/ (I guess) 1294 1295.. _example_accessed_through_label: 1296 1297Suppressing change reports about types accessed either directly 1298or through pointers 1299 1300Suppose we have a first version of an object file which source 1301code is the file widget-v0.cc below: :: 1302 1303 // Compile with: g++ -g -c widget-v0.cc 1304 1305 struct widget 1306 { 1307 int x; 1308 int y; 1309 1310 widget() 1311 :x(), y() 1312 {} 1313 }; 1314 1315 void 1316 fun0(widget*) 1317 { 1318 // .. do stuff here. 1319 } 1320 1321 void 1322 fun1(widget&) 1323 { 1324 // .. do stuff here .. 1325 } 1326 1327 void 1328 fun2(widget w) 1329 { 1330 // ... do other stuff here ... 1331 } 1332 1333Now suppose in the second version of that file, named 1334widget-v1.cc, we have added some data members at the end of 1335the type ``struct widget``; here is what the content of that file 1336would look like: :: 1337 1338 // Compile with: g++ -g -c widget-v1.cc 1339 1340 struct widget 1341 { 1342 int x; 1343 int y; 1344 int w; // We have added these two new data members here .. 1345 int h; // ... and here. 1346 1347 widget() 1348 : x(), y(), w(), h() 1349 {} 1350 }; 1351 1352 void 1353 fun0(widget*) 1354 { 1355 // .. do stuff here. 1356 } 1357 1358 void 1359 fun1(widget&) 1360 { 1361 // .. do stuff here .. 1362 } 1363 1364 void 1365 fun2(widget w) 1366 { 1367 // ... do other stuff here ... 1368 } 1369 1370When we invoke ``abidiff`` on the object files resulting from the 1371compilation of the two file above, here is what we get: :: 1372 1373 $ abidiff widget-v0.o widget-v1.o 1374 Functions changes summary: 0 Removed, 2 Changed (1 filtered out), 0 Added functions 1375 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1376 1377 2 functions with some indirect sub-type change: 1378 1379 [C]'function void fun0(widget*)' has some indirect sub-type changes: 1380 parameter 1 of type 'widget*' has sub-type changes: 1381 in pointed to type 'struct widget': 1382 type size changed from 64 to 128 bits 1383 2 data member insertions: 1384 'int widget::w', at offset 64 (in bits) 1385 'int widget::h', at offset 96 (in bits) 1386 1387 [C]'function void fun2(widget)' has some indirect sub-type changes: 1388 parameter 1 of type 'struct widget' has sub-type changes: 1389 details were reported earlier 1390 $ 1391 1392I guess a little bit of explaining is due here. ``abidiff`` 1393detects that two data member got added at the end of ``struct 1394widget``. it also tells us that the type change impacts the 1395exported function ``fun0()`` which uses the type ``struct 1396widget`` through a pointer, in its signature. 1397 1398Careful readers will notice that the change to ``struct widget`` 1399also impacts the exported function ``fun1()``, that uses type 1400``struct widget`` through a reference. But then ``abidiff`` 1401doesn't tell us about the impact on that function ``fun1()`` 1402because it has evaluated that change as being **redundant** with 1403the change it reported on ``fun0()``. It has thus filtered it 1404out, to avoid cluttering the output with noise. 1405 1406Redundancy detection and filtering is fine and helpful to avoid 1407burying the important information in a sea of noise. However, it 1408must be treated with care, by fear of mistakenly filtering out 1409relevant and important information. 1410 1411That is why ``abidiff`` tells us about the impact that the change 1412to ``struct widget`` has on function ``fun2()``. In this case, 1413that function uses the type ``struct widget`` **directly** (in 1414its signature). It does not use it via a pointer or a reference. 1415In this case, the direct use of this type causes ``fun2()`` to be 1416exposed to a potentially harmful ABI change. Hence, the report 1417about ``fun2()`` is not filtered out, even though it's about that 1418same change on ``struct widget``. 1419 1420To go further in suppressing reports about changes that are 1421harmless and keeping only those that we know are harmful, we 1422would like to go tell abidiff to suppress reports about this 1423particular ``struct widget`` change when it impacts uses of 1424``struct widget`` through a pointer or reference. In other 1425words, suppress the change reports about ``fun0()`` **and** 1426``fun1()``. We would then write this suppression specification, 1427in file ``widget.suppr``: :: 1428 1429 [suppress_type] 1430 name = widget 1431 type_kind = struct 1432 has_data_member_inserted_at = end 1433 accessed_through = reference-or-pointer 1434 1435 # So this suppression specification says to suppress reports about 1436 # the type 'struct widget', if this type was added some data member 1437 # at its end, and if the change impacts uses of the type through a 1438 # reference or a pointer. 1439 1440Invoking ``abidiff`` on ``widget-v0.o`` and ``widget-v1.o`` with 1441this suppression specification yields: :: 1442 1443 $ abidiff --suppressions widget.suppr widget-v0.o widget-v1.o 1444 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function 1445 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1446 1447 1 function with some indirect sub-type change: 1448 1449 [C]'function void fun2(widget)' has some indirect sub-type changes: 1450 parameter 1 of type 'struct widget' has sub-type changes: 1451 type size changed from 64 to 128 bits 1452 2 data member insertions: 1453 'int widget::w', at offset 64 (in bits) 1454 'int widget::h', at offset 96 (in bits) 1455 $ 1456 1457As expected, I guess. 1458 1459Suppressing change reports about functions. 1460 1461Suppose we have a first version a library named 1462``libtest2-v0.so`` whose source code is: :: 1463 1464 $ cat -n test2-v0.cc 1465 1466 1 struct S1 1467 2 { 1468 3 int m0; 1469 4 1470 5 S1() 1471 6 : m0() 1472 7 {} 1473 8 }; 1474 9 1475 10 struct S2 1476 11 { 1477 12 int m0; 1478 13 1479 14 S2() 1480 15 : m0() 1481 16 {} 1482 17 }; 1483 18 1484 19 struct S3 1485 20 { 1486 21 int m0; 1487 22 1488 23 S3() 1489 24 : m0() 1490 25 {} 1491 26 }; 1492 27 1493 28 int 1494 29 func(S1&) 1495 30 { 1496 31 // suppose the code does something with the argument. 1497 32 return 0; 1498 33 1499 34 } 1500 35 1501 36 char 1502 37 func(S2*) 1503 38 { 1504 39 // suppose the code does something with the argument. 1505 40 return 0; 1506 41 } 1507 42 1508 43 unsigned 1509 44 func(S3) 1510 45 { 1511 46 // suppose the code does something with the argument. 1512 47 return 0; 1513 48 } 1514 $ 1515 1516And then we come up with a second version ``libtest2-v1.so`` of 1517that library; the source code is modified by making the 1518structures ``S1``, ``S2``, ``S3`` inherit another struct: :: 1519 1520 $ cat -n test2-v1.cc 1521 1 struct base_type 1522 2 { 1523 3 int m_inserted; 1524 4 }; 1525 5 1526 6 struct S1 : public base_type // <--- S1 now has base_type as its base 1527 7 // type. 1528 8 { 1529 9 int m0; 1530 10 1531 11 S1() 1532 12 : m0() 1533 13 {} 1534 14 }; 1535 15 1536 16 struct S2 : public base_type // <--- S2 now has base_type as its base 1537 17 // type. 1538 18 { 1539 19 int m0; 1540 20 1541 21 S2() 1542 22 : m0() 1543 23 {} 1544 24 }; 1545 25 1546 26 struct S3 : public base_type // <--- S3 now has base_type as its base 1547 27 // type. 1548 28 { 1549 29 int m0; 1550 30 1551 31 S3() 1552 32 : m0() 1553 33 {} 1554 34 }; 1555 35 1556 36 int 1557 37 func(S1&) 1558 38 { 1559 39 // suppose the code does something with the argument. 1560 40 return 0; 1561 41 1562 42 } 1563 43 1564 44 char 1565 45 func(S2*) 1566 46 { 1567 47 // suppose the code does something with the argument. 1568 48 return 0; 1569 49 } 1570 50 1571 51 unsigned 1572 52 func(S3) 1573 53 { 1574 54 // suppose the code does something with the argument. 1575 55 return 0; 1576 56 } 1577 $ 1578 1579Now let's build the two libraries: :: 1580 1581 g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc 1582 g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc 1583 1584Let's look at the output of ``abidiff``: :: 1585 1586 $ abidiff libtest2-v0.so libtest2-v1.so 1587 Functions changes summary: 0 Removed, 3 Changed, 0 Added functions 1588 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1589 1590 3 functions with some indirect sub-type change: 1591 1592 [C]'function unsigned int func(S3)' has some indirect sub-type changes: 1593 parameter 0 of type 'struct S3' has sub-type changes: 1594 size changed from 32 to 64 bits 1595 1 base class insertion: 1596 struct base_type 1597 1 data member change: 1598 'int S3::m0' offset changed from 0 to 32 1599 1600 [C]'function char func(S2*)' has some indirect sub-type changes: 1601 parameter 0 of type 'S2*' has sub-type changes: 1602 in pointed to type 'struct S2': 1603 size changed from 32 to 64 bits 1604 1 base class insertion: 1605 struct base_type 1606 1 data member change: 1607 'int S2::m0' offset changed from 0 to 32 1608 1609 [C]'function int func(S1&)' has some indirect sub-type changes: 1610 parameter 0 of type 'S1&' has sub-type changes: 1611 in referenced type 'struct S1': 1612 size changed from 32 to 64 bits 1613 1 base class insertion: 1614 struct base_type 1615 1 data member change: 1616 'int S1::m0' offset changed from 0 to 32 1617 $ 1618 1619Let's tell ``abidiff`` to avoid showing us the differences on the 1620overloads of ``func`` that takes either a pointer or a reference. 1621For that, we author this simple suppression specification: :: 1622 1623 $ cat -n libtest2.suppr 1624 1 [suppress_function] 1625 2 name = func 1626 3 parameter = '0 S1& 1627 4 1628 5 [suppress_function] 1629 6 name = func 1630 7 parameter = '0 S2* 1631 $ 1632 1633And then let's invoke ``abidiff`` with the suppression 1634specification: :: 1635 1636 $ ../build/tools/abidiff --suppressions libtest2.suppr libtest2-v0.so libtest2-v1.so 1637 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function 1638 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1639 1640 1 function with some indirect sub-type change: 1641 1642 [C]'function unsigned int func(S3)' has some indirect sub-type changes: 1643 parameter 0 of type 'struct S3' has sub-type changes: 1644 size changed from 32 to 64 bits 1645 1 base class insertion: 1646 struct base_type 1647 1 data member change: 1648 'int S3::m0' offset changed from 0 to 32 1649 1650 1651The suppression specification could be reduced using 1652:ref:`regular expressions <suppr_regexp_label>`: :: 1653 1654 $ cat -n libtest2-1.suppr 1655 1 [suppress_function] 1656 2 name = func 1657 3 parameter = '0 /^S.(&|\\*)/ 1658 $ 1659 1660 $ ../build/tools/abidiff --suppressions libtest2-1.suppr libtest2-v0.so libtest2-v1.so 1661 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function 1662 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1663 1664 1 function with some indirect sub-type change: 1665 1666 [C]'function unsigned int func(S3)' has some indirect sub-type changes: 1667 parameter 0 of type 'struct S3' has sub-type changes: 1668 size changed from 32 to 64 bits 1669 1 base class insertion: 1670 struct base_type 1671 1 data member change: 1672 'int S3::m0' offset changed from 0 to 32 1673 1674 $ 1675 1676.. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format 1677 1678.. _Ini File Syntax: http://en.wikipedia.org/wiki/INI_file 1679 1680.. _GNU C Library: http://www.gnu.org/software/libc 1681