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``. Please note that if a type has a change in which 437 at least one of its data members is removed or its size is reduced, 438 the type will *NOT* be suppressed by the evaluation of this property. 439 440 The value ``offset-in-bit`` is either: 441 442 - an integer value, expressed in bits, which denotes the 443 offset of the insertion point of the data member, starting 444 from the beginning of the relevant structure or class. 445 446 - the keyword ``end`` which is a named constant which value 447 equals the offset of the end of the of the structure or 448 class. 449 450 - the function call expression 451 ``offset_of(data-member-name)`` where `data-member-name` is 452 the name of a given data member of the relevant structure 453 or class. The value of this function call expression is an 454 integer that represents the offset of the data member 455 denoted by ``data-member-name``. 456 457 - the function call expression 458 ``offset_after(data-member-name)`` where `data-member-name` 459 is the name of a given data member of the relevant 460 structure or class. The value of this function call 461 expression is an integer that represents the offset of the 462 point that comes right after the region occupied by the 463 data member denoted by ``data-member-name``. 464 465 .. _suppr_has_data_member_inserted_between_label: 466 467 468* ``has_data_member_inserted_between`` 469 470 Usage: 471 472 ``has_data_member_inserted_between`` ``=`` {<``range-begin``>, <``range-end``>} 473 474 Suppresses change reports involving a type which has at least one 475 data member inserted at an offset that is comprised in the range 476 between ``range-begin`` and ``range-end``. Please note that each of 477 the values ``range-begin`` and ``range-end`` can be of the same form 478 as the :ref:`has_data_member_inserted_at 479 <suppr_has_data_member_inserted_at_label>` property above. Please 480 also note that if a type has a change in which at least one of its 481 data members is removed or its size is reduced, the type will *NOT* be 482 suppressed by the evaluation of this property. 483 484 Usage examples of this properties are: :: 485 486 has_data_member_inserted_between = {8, 64} 487 488 or: :: 489 490 has_data_member_inserted_between = {16, end} 491 492 or: :: 493 494 has_data_member_inserted_between = {offset_after(member1), end} 495 496.. _suppr_has_data_members_inserted_between_label: 497 498 499* ``has_data_members_inserted_between`` 500 501 Usage: 502 503 ``has_data_members_inserted_between`` ``=`` {<sequence-of-ranges>} 504 505 Suppresses change reports involving a type which has multiple data 506 member inserted in various offset ranges. A usage example of this 507 property is, for instance: :: 508 509 has_data_members_inserted_between = {{8, 31}, {72, 95}} 510 511 This usage example suppresses change reports involving a type which 512 has data members inserted in bit offset ranges [8 31] and [72 95]. 513 The length of the sequence of ranges or this 514 ``has_data_members_inserted_between`` is not bounded; it can be as 515 long as the system can cope with. The values of the boundaries of 516 the ranges are of the same kind as for the 517 :ref:`has_data_member_inserted_at 518 <suppr_has_data_member_inserted_at_label>` property above. Please 519 note that if a type has a change in which at least one of its data 520 members is removed or its size is reduced, the type will *NOT* be 521 suppressed by the evaluation of this property. 522 523 Another usage example of this property is thus: :: 524 525 has_data_members_inserted_between = 526 { 527 {offset_after(member0), offset_of(member1)}, 528 {72, end} 529 } 530 531 .. _suppr_accessed_through_property_label: 532 533* ``accessed_through`` 534 535 Usage: 536 537 ``accessed_through`` ``=`` <some-predefined-values> 538 539 Suppress change reports involving a type which is referred to either 540 directly or through a pointer or a reference. The potential values 541 of this property are the predefined keywords below: 542 543 * ``direct`` 544 545 So if the ``[suppress_type]`` contains the property 546 description: :: 547 548 accessed_through = direct 549 550 then changes about a type that is referred-to 551 directly (i.e, not through a pointer or a reference) 552 are going to be suppressed. 553 554 * ``pointer`` 555 556 If the ``accessed_through`` property is set to the 557 value ``pointer`` then changes about a type that is 558 referred-to through a pointer are going to be 559 suppressed. 560 561 * ``reference`` 562 563 If the ``accessed_through`` property is set to the 564 value ``reference`` then changes about a type that is 565 referred-to through a reference are going to be 566 suppressed. 567 568 * ``reference-or-pointer`` 569 570 If the ``accessed_through`` property is set to the 571 value ``reference-or-pointer`` then changes about a 572 type that is referred-to through either a reference 573 or a pointer are going to be suppressed. 574 575 For an extensive example of how to use this property, please check 576 out the example below about :ref:`suppressing change reports about 577 types accessed either directly or through pointers 578 <example_accessed_through_label>`. 579 580* ``drop`` 581 582 Usage: 583 584 ``drop`` ``=`` yes | no 585 586 If a type is matched by a suppression specification which contains 587 the "drop" property set to "yes" (or to "true") then the type is not 588 even going to be represented in the internal representation of the 589 ABI being analyzed. This property makes its enclosing suppression 590 specification to be applied in the :ref:`early suppression 591 specification mode <early_suppression_mode_label>`. The net effect 592 is that it potentially reduces the memory used to represent the ABI 593 being analyzed. 594 595 Please note that for this property to be effective, the enclosing 596 suppression specification must have at least one of the following 597 properties specified: ``name_regexp``, ``name``, ``name_regexp``, 598 ``source_location_not_in`` or ``source_location_not_regexp``. 599 600 .. _suppr_label_property_label: 601 602* ``label`` 603 604 Usage: 605 606 ``label`` ``=`` <some-value> 607 608 Define a label for the section. A label is just an informative 609 string that might be used by a tool to refer to a type suppression in 610 error messages. 611 612.. _suppr_changed_enumerators_label: 613 614* ``changed_enumerators`` 615 616 Usage: 617 618 ``changed_enumerators`` ``=`` <list-of-enumerators> 619 620 Suppresses change reports involving changes in the value of 621 enumerators of a given enum type. This property is applied if the 622 ``type_kind`` property is set to the value ``enum``, at least. The 623 value of the ``changed_enumerators`` is a comma-separated list of 624 the enumerators that the user expects to change. For instance: :: 625 626 changed_enumerators = LAST_ENUMERATORS0, LAST_ENUMERATOR1 627 628``[suppress_function]`` 629$$$$$$$$$$$$$$$$$$$$$$$$ 630 631This directive suppresses report messages about changes on a set of 632functions. 633 634Note that for the ``[suppress_function]`` directive to work, at least 635one of the following properties must be provided: 636 637 ``label``, ``file_name_regexp``, ``file_name_not_regexp``, 638 ``soname_regexp``, ``soname_not_regexp``, ``name``, ``name_regexp``, 639 ``name_not_regexp``, ``parameter``, ``return_type_name``, 640 ``return_type_regexp``, ``symbol_name``, ``symbol_name_regexp``, 641 ``symbol_name_not_regexp``, ``symbol_version``, 642 ``symbol_version_regexp``. 643 644If none of the above properties are provided, then the 645``[suppress_function]`` directive is simply ignored. 646 647The potential properties of this sections are: 648 649* ``label`` 650 651 Usage: 652 653 ``label`` ``=`` <some-value> 654 655 This property is the same as the :ref:`label property 656 <suppr_label_property_label>` defined above. 657 658 659* ``file_name_regexp`` 660 661 Usage: 662 663 ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 664 665 Suppresses change reports about ABI artifacts that are defined in a 666 binary file which name matches the regular expression specified as 667 value of this property. 668 669 670* ``file_name_not_regexp`` 671 672 Usage: 673 674 ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 675 676 Suppresses change reports about ABI artifacts that are defined in a 677 binary file which name does not match the regular expression 678 specified as value of this property. 679 680* ``soname_regexp`` 681 682 Usage: 683 684 ``soname_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 matches the regular expression 688 specified as value of this property. 689 690* ``soname_not_regexp`` 691 692 Usage: 693 694 ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 695 696 Suppresses change reports about ABI artifacts that are defined in a 697 shared library which SONAME property does not match the regular 698 expression specified as value of this property. 699 700 701* ``name`` 702 703 Usage: 704 705 ``name`` ``=`` <some-value> 706 707 Suppresses change reports involving functions whose name equals the 708 value of this property. 709 710* ``name_regexp`` 711 712 Usage: 713 714 ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 715 716 Suppresses change reports involving functions whose name matches the 717 regular expression specified as value of this property. 718 719 Let's consider the case of functions that have several symbol names. 720 This happens when the underlying symbol for the function has 721 aliases. Each symbol name is actually one alias name. 722 723 In this case, if the regular expression matches the name of 724 at least one of the aliases names, then it must match the names of 725 all of the aliases of the function for the directive to actually 726 suppress the diff reports for said function. 727 728 729* ``name_not_regexp`` 730 731 Usage: 732 733 ``name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 734 735 Suppresses change reports involving functions whose names don't match 736 the regular expression specified as value of this property. 737 738 The rules for functions that have several symbol names are the same 739 rules as for the ``name_regexp`` property above. 740 741 .. _suppr_change_kind_property_label: 742 743 744* ``change_kind`` 745 746 Usage: 747 748 ``change_kind`` ``=`` <predefined-possible-values> 749 750 Specifies the kind of changes this suppression specification should 751 apply to. The possible values of this property as well as their 752 meaning are listed below: 753 754 - ``function-subtype-change`` 755 756 This suppression specification applies to functions 757 that which have at least one sub-type that has 758 changed. 759 760 - ``added-function`` 761 762 This suppression specification applies to functions 763 that have been added to the binary. 764 765 - ``deleted-function`` 766 767 This suppression specification applies to functions 768 that have been removed from the binary. 769 770 - ``all`` 771 772 This suppression specification applies to functions 773 that have all of the changes above. Note that not 774 providing the ``change_kind`` property at all is 775 equivalent to setting it to the value ``all``. 776 777 778* ``parameter`` 779 780 Usage: 781 782 ``parameter`` ``=`` <function-parameter-specification> 783 784 Suppresses change reports involving functions whose 785 parameters match the parameter specification indicated as 786 value of this property. 787 788 The format of the function parameter specification is: 789 790 ``'`` ``<parameter-index>`` ``<space>`` ``<type-name-or-regular-expression>`` 791 792 That is, an apostrophe followed by a number that is the 793 index of the parameter, followed by one of several spaces, 794 followed by either the name of the type of the parameter, 795 or a regular expression describing a family of parameter 796 type names. 797 798 If the parameter type name is designated by a regular 799 expression, then said regular expression must be enclosed 800 between two slashes; like ``/some-regular-expression/``. 801 802 The index of the first parameter of the function is zero. 803 Note that for member functions (methods of classes), the 804 this is the first parameter that comes after the implicit 805 "this" pointer parameter. 806 807 Examples of function parameter specifications are: :: 808 809 '0 int 810 811 Which means, the parameter at index 0, whose type name is 812 ``int``. :: 813 814 '4 unsigned char* 815 816 Which means, the parameter at index 4, whose type name is 817 ``unsigned char*``. :: 818 819 '2 /^foo.*&/ 820 821 Which means, the parameter at index 2, whose type name 822 starts with the string "foo" and ends with an '&'. In 823 other words, this is the third parameter and it's a 824 reference on a type that starts with the string "foo". 825 826* ``return_type_name`` 827 828 Usage: 829 830 ``return_type_name`` ``=`` <some-value> 831 832 Suppresses change reports involving functions whose return type name 833 equals the value of this property. 834 835* ``return_type_regexp`` 836 837 Usage: 838 839 ``return_type_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 840 841 Suppresses change reports involving functions whose return type name 842 matches the regular expression specified as value of this property. 843 844* ``symbol_name`` 845 846 Usage: 847 848 ``symbol_name`` ``=`` <some-value> 849 850 Suppresses change reports involving functions whose symbol name equals 851 the value of this property. 852 853* ``symbol_name_regexp`` 854 855 Usage: 856 857 ``symbol_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 858 859 Suppresses change reports involving functions whose symbol name 860 matches the regular expression specified as value of this property. 861 862 Let's consider the case of functions that have several symbol names. 863 This happens when the underlying symbol for the function has 864 aliases. Each symbol name is actually one alias name. 865 866 In this case, the regular expression must match the names of all of 867 the aliases of the function for the directive to actually suppress 868 the diff reports for said function. 869 870* ``symbol_name_not_regexp`` 871 872 Usage: 873 874 ``symbol_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 875 876 Suppresses change reports involving functions whose symbol name does 877 not match the regular expression specified as value of this property. 878 879* ``symbol_version`` 880 881 Usage: 882 883 ``symbol_version`` ``=`` <some-value> 884 885 Suppresses change reports involving functions whose symbol version 886 equals the value of this property. 887 888* ``symbol_version_regexp`` 889 890 Usage: 891 892 ``symbol_version_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 893 894 Suppresses change reports involving functions whose symbol version 895 matches the regular expression specified as value of this property. 896 897* ``drop`` 898 899 Usage: 900 901 ``drop`` ``=`` yes | no 902 903 If a function is matched by a suppression specification which 904 contains the "drop" property set to "yes" (or to "true") then the 905 function is not even going to be represented in the internal 906 representation of the ABI being analyzed. This property makes its 907 enclosing suppression specification to be applied in the :ref:`early 908 suppression specification mode <early_suppression_mode_label>`. The 909 net effect is that it potentially reduces the memory used to 910 represent the ABI being analyzed. 911 912 Please note that for this property to be effective, the enclosing 913 suppression specification must have at least one of the following 914 properties specified: ``name_regexp``, ``name``, ``name_regexp``, 915 ``source_location_not_in`` or ``source_location_not_regexp``. 916 917``[suppress_variable]`` 918$$$$$$$$$$$$$$$$$$$$$$$$ 919 920This directive suppresses report messages about changes on a set of 921variables. 922 923Note that for the ``[suppress_variable]`` directive to work, at least 924one of the following properties must be provided: 925 926 ``label``, ``file_name_regexp``, ``file_name_not_regexp``, 927 ``soname_regexp``, ``soname_not_regexp``, ``name``, ``name_regexp``, 928 ``name_not_regexp``, ``symbol_name``, ``symbol_name_regexp``, 929 ``symbol_name_not_regexp``, ``symbol_version``, 930 ``symbol_version_regexp``, ``type_name``, ``type_name_regexp``. 931 932If none of the above properties are provided, then the 933``[suppress_variable]`` directive is simply ignored. 934 935The potential properties of this sections are: 936 937* ``label`` 938 939 Usage: 940 941 ``label`` ``=`` <some-value> 942 943 This property is the same as the :ref:`label property 944 <suppr_label_property_label>` defined above. 945 946 947* ``file_name_regexp`` 948 949 Usage: 950 951 ``file_name_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 matches the regular expression specified as 955 value of this property. 956 957* ``file_name_not_regexp`` 958 959 Usage: 960 961 ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 962 963 Suppresses change reports about ABI artifacts that are defined in a 964 binary file which name does not match the regular expression 965 specified as value of this property. 966 967 968* ``soname_regexp`` 969 970 Usage: 971 972 ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 973 974 Suppresses change reports about ABI artifacts that are defined in a 975 shared library which SONAME property matches the regular expression 976 specified as value of this property. 977 978 979* ``soname_not_regexp`` 980 981 Usage: 982 983 ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 984 985 Suppresses change reports about ABI artifacts that are defined in a 986 shared library which SONAME property does not match the regular 987 expression specified as value of this property. 988 989 990* ``name`` 991 992 Usage: 993 994 ``name`` ``=`` <some-value> 995 996 Suppresses change reports involving variables whose name equals the 997 value of this property. 998 999* ``name_regexp`` 1000 1001 Usage: 1002 1003 ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 1004 1005 Suppresses change reports involving variables whose name matches the 1006 regular expression specified as value of this property. 1007 1008* ``change_kind`` 1009 1010 Usage: 1011 1012 ``change_kind`` ``=`` <predefined-possible-values> 1013 1014 Specifies the kind of changes this suppression specification should 1015 apply to. The possible values of this property as well as their 1016 meaning are the same as when it's :ref:`used in the 1017 [suppress_function] section <suppr_change_kind_property_label>`. 1018 1019* ``symbol_name`` 1020 1021 Usage: 1022 1023 ``symbol_name`` ``=`` <some-value> 1024 1025 Suppresses change reports involving variables whose symbol name equals 1026 the value of this property. 1027 1028* symbol_name_regexp 1029 1030 Usage: 1031 1032 ``symbol_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 1033 1034 Suppresses change reports involving variables whose symbol name 1035 matches the regular expression specified as value of this property. 1036 1037 1038* ``symbol_name_not_regexp`` 1039 1040 Usage: 1041 1042 ``symbol_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 1043 1044 Suppresses change reports involving variables whose symbol name does 1045 not match the regular expression specified as value of this property. 1046 1047* ``symbol_version`` 1048 1049 Usage: 1050 1051 ``symbol_version`` ``=`` <some-value> 1052 1053 Suppresses change reports involving variables whose symbol version 1054 equals the value of this property. 1055 1056* ``symbol_version_regexp`` 1057 1058 Usage: 1059 1060 ``symbol_version_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 1061 1062 Suppresses change reports involving variables whose symbol version 1063 matches the regular expression specified as value of this property. 1064 1065* ``type_name`` 1066 1067 Usage: 1068 1069 ``type_name`` ``=`` <some-value> 1070 1071 Suppresses change reports involving variables whose type name equals 1072 the value of this property. 1073 1074* ``type_name_regexp`` 1075 1076 Usage: 1077 1078 ``type_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`> 1079 1080 Suppresses change reports involving variables whose type name matches 1081 the regular expression specified as value of this property. 1082 1083Comments 1084^^^^^^^^ 1085 1086``;`` or ``#`` ASCII character at the beginning of a line 1087indicates a comment. Comment lines are ignored. 1088 1089Code examples 1090^^^^^^^^^^^^^ 1091 10921. Suppressing change reports about types. 1093 1094 Suppose we have a library named ``libtest1-v0.so`` which 1095 contains this very useful code: :: 1096 1097 $ cat -n test1-v0.cc 1098 1 // A forward declaration for a type considered to be opaque to 1099 2 // function foo() below. 1100 3 struct opaque_type; 1101 4 1102 5 // This function cannot touch any member of opaque_type. Hence, 1103 6 // changes to members of opaque_type should not impact foo, as far as 1104 7 // ABI is concerned. 1105 8 void 1106 9 foo(opaque_type*) 1107 10 { 1108 11 } 1109 12 1110 13 struct opaque_type 1111 14 { 1112 15 int member0; 1113 16 char member1; 1114 17 }; 1115 $ 1116 1117Let's change the layout of struct opaque_type by inserting a data 1118member around line 15, leading to a new version of the library, 1119that we shall name ``libtest1-v1.so``: :: 1120 1121 $ cat -n test1-v1.cc 1122 1 // A forward declaration for a type considered to be opaque to 1123 2 // function foo() below. 1124 3 struct opaque_type; 1125 4 1126 5 // This function cannot touch any member of opaque_type; Hence, 1127 6 // changes to members of opaque_type should not impact foo, as far as 1128 7 // ABI is concerned. 1129 8 void 1130 9 foo(opaque_type*) 1131 10 { 1132 11 } 1133 12 1134 13 struct opaque_type 1135 14 { 1136 15 char added_member; // <-- a new member got added here now. 1137 16 int member0; 1138 17 char member1; 1139 18 }; 1140 $ 1141 1142Let's compile both examples. We shall not forget to compile them 1143with debug information generation turned on: :: 1144 1145 $ g++ -shared -g -Wall -o libtest1-v0.so test1-v0.cc 1146 $ g++ -shared -g -Wall -o libtest1-v1.so test1-v1.cc 1147 1148Let's ask :ref:`abidiff <abidiff_label>` which ABI differences it sees 1149between ``libtest1-v0.so`` and ``libtest1-v1.so``: :: 1150 1151 $ abidiff libtest1-v0.so libtest1-v1.so 1152 Functions changes summary: 0 Removed, 1 Changed, 0 Added function 1153 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1154 1155 1 function with some indirect sub-type change: 1156 1157 [C]'function void foo(opaque_type*)' has some indirect sub-type changes: 1158 parameter 0 of type 'opaque_type*' has sub-type changes: 1159 in pointed to type 'struct opaque_type': 1160 size changed from 64 to 96 bits 1161 1 data member insertion: 1162 'char opaque_type::added_member', at offset 0 (in bits) 1163 2 data member changes: 1164 'int opaque_type::member0' offset changed from 0 to 32 1165 'char opaque_type::member1' offset changed from 32 to 64 1166 1167 1168So ``abidiff`` reports that the opaque_type's layout has changed 1169in a significant way, as far as ABI implications are concerned, in 1170theory. After all, a sub-type (``struct opaque_type``) of an 1171exported function (``foo()``) has seen its layout change. This 1172might have non negligible ABI implications. But in practice here, 1173the programmer of the litest1-v1.so library knows that the "soft" 1174contract between the function ``foo()`` and the type ``struct 1175opaque_type`` is to stay away from the data members of the type. 1176So layout changes of ``struct opaque_type`` should not impact 1177``foo()``. 1178 1179Now to teach ``abidiff`` about this soft contract and have it 1180avoid emitting what amounts to false positives in this case, we 1181write the suppression specification file below: :: 1182 1183 $ cat test1.suppr 1184 [suppress_type] 1185 type_kind = struct 1186 name = opaque_type 1187 1188Translated in plain English, this suppression specification would 1189read: "Do not emit change reports about a struct which name is 1190opaque_type". 1191 1192Let's now invoke ``abidiff`` on the two versions of the library 1193again, but this time with the suppression specification: :: 1194 1195 $ abidiff --suppressions test1.suppr libtest1-v0.so libtest1-v1.so 1196 Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function 1197 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1198 1199As you can see, ``abidiff`` does not report the change anymore; it 1200tells us that it was filtered out instead. 1201 1202Suppressing change reports about types with data member 1203insertions 1204 1205Suppose the first version of a library named ``libtest3-v0.so`` 1206has this source code: :: 1207 1208 /* Compile this with: 1209 gcc -g -Wall -shared -o libtest3-v0.so test3-v0.c 1210 */ 1211 1212 struct S 1213 { 1214 char member0; 1215 int member1; /* 1216 between member1 and member2, there is some padding, 1217 at least on some popular platforms. On 1218 these platforms, adding a small enough data 1219 member into that padding shouldn't change 1220 the offset of member1. Right? 1221 */ 1222 }; 1223 1224 int 1225 foo(struct S* s) 1226 { 1227 return s->member0 + s->member1; 1228 } 1229 1230Now, suppose the second version of the library named 1231``libtest3-v1.so`` has this source code in which a data member 1232has been added in the padding space of struct S and another data 1233member has been added at its end: :: 1234 1235 /* Compile this with: 1236 gcc -g -Wall -shared -o libtest3-v1.so test3-v1.c 1237 */ 1238 1239 struct S 1240 { 1241 char member0; 1242 char inserted1; /* <---- A data member has been added here... */ 1243 int member1; 1244 char inserted2; /* <---- ... and another one has been added here. */ 1245 }; 1246 1247 int 1248 foo(struct S* s) 1249 { 1250 return s->member0 + s->member1; 1251 } 1252 1253 1254In libtest3-v1.so, adding char data members ``S::inserted1`` and 1255``S::inserted2`` can be considered harmless (from an ABI compatibility 1256perspective), at least on the x86 platform, because that doesn't 1257change the offsets of the data members S::member0 and S::member1. But 1258then running ``abidiff`` on these two versions of library yields: :: 1259 1260 $ abidiff libtest3-v0.so libtest3-v1.so 1261 Functions changes summary: 0 Removed, 1 Changed, 0 Added function 1262 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1263 1264 1 function with some indirect sub-type change: 1265 1266 [C]'function int foo(S*)' has some indirect sub-type changes: 1267 parameter 0 of type 'S*' has sub-type changes: 1268 in pointed to type 'struct S': 1269 type size changed from 64 to 96 bits 1270 2 data member insertions: 1271 'char S::inserted1', at offset 8 (in bits) 1272 'char S::inserted2', at offset 64 (in bits) 1273 $ 1274 1275 1276 1277That is, ``abidiff`` shows us the two changes, even though we (the 1278developers of that very involved library) know that these changes 1279are harmless in this particular context. 1280 1281Luckily, we can devise a suppression specification that essentially 1282tells abidiff to filter out change reports about adding a data 1283member between ``S::member0`` and ``S::member1``, and adding a data 1284member at the end of struct S. We have written such a suppression 1285specification in a file called test3-1.suppr and it unsurprisingly 1286looks like: :: 1287 1288 [suppress_type] 1289 name = S 1290 has_data_member_inserted_between = {offset_after(member0), offset_of(member1)} 1291 has_data_member_inserted_at = end 1292 1293 1294Now running ``abidiff`` with this suppression specification yields: :: 1295 1296 $ ../build/tools/abidiff --suppressions test3-1.suppr libtest3-v0.so libtest3-v1.so 1297 Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function 1298 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1299 1300 $ 1301 1302 1303Hooora! \\o/ (I guess) 1304 1305.. _example_accessed_through_label: 1306 1307Suppressing change reports about types accessed either directly 1308or through pointers 1309 1310Suppose we have a first version of an object file which source 1311code is the file widget-v0.cc below: :: 1312 1313 // Compile with: g++ -g -c widget-v0.cc 1314 1315 struct widget 1316 { 1317 int x; 1318 int y; 1319 1320 widget() 1321 :x(), y() 1322 {} 1323 }; 1324 1325 void 1326 fun0(widget*) 1327 { 1328 // .. do stuff here. 1329 } 1330 1331 void 1332 fun1(widget&) 1333 { 1334 // .. do stuff here .. 1335 } 1336 1337 void 1338 fun2(widget w) 1339 { 1340 // ... do other stuff here ... 1341 } 1342 1343Now suppose in the second version of that file, named 1344widget-v1.cc, we have added some data members at the end of 1345the type ``struct widget``; here is what the content of that file 1346would look like: :: 1347 1348 // Compile with: g++ -g -c widget-v1.cc 1349 1350 struct widget 1351 { 1352 int x; 1353 int y; 1354 int w; // We have added these two new data members here .. 1355 int h; // ... and here. 1356 1357 widget() 1358 : x(), y(), w(), h() 1359 {} 1360 }; 1361 1362 void 1363 fun0(widget*) 1364 { 1365 // .. do stuff here. 1366 } 1367 1368 void 1369 fun1(widget&) 1370 { 1371 // .. do stuff here .. 1372 } 1373 1374 void 1375 fun2(widget w) 1376 { 1377 // ... do other stuff here ... 1378 } 1379 1380When we invoke ``abidiff`` on the object files resulting from the 1381compilation of the two file above, here is what we get: :: 1382 1383 $ abidiff widget-v0.o widget-v1.o 1384 Functions changes summary: 0 Removed, 2 Changed (1 filtered out), 0 Added functions 1385 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1386 1387 2 functions with some indirect sub-type change: 1388 1389 [C]'function void fun0(widget*)' has some indirect sub-type changes: 1390 parameter 1 of type 'widget*' has sub-type changes: 1391 in pointed to type 'struct widget': 1392 type size changed from 64 to 128 bits 1393 2 data member insertions: 1394 'int widget::w', at offset 64 (in bits) 1395 'int widget::h', at offset 96 (in bits) 1396 1397 [C]'function void fun2(widget)' has some indirect sub-type changes: 1398 parameter 1 of type 'struct widget' has sub-type changes: 1399 details were reported earlier 1400 $ 1401 1402I guess a little bit of explaining is due here. ``abidiff`` 1403detects that two data member got added at the end of ``struct 1404widget``. it also tells us that the type change impacts the 1405exported function ``fun0()`` which uses the type ``struct 1406widget`` through a pointer, in its signature. 1407 1408Careful readers will notice that the change to ``struct widget`` 1409also impacts the exported function ``fun1()``, that uses type 1410``struct widget`` through a reference. But then ``abidiff`` 1411doesn't tell us about the impact on that function ``fun1()`` 1412because it has evaluated that change as being **redundant** with 1413the change it reported on ``fun0()``. It has thus filtered it 1414out, to avoid cluttering the output with noise. 1415 1416Redundancy detection and filtering is fine and helpful to avoid 1417burying the important information in a sea of noise. However, it 1418must be treated with care, by fear of mistakenly filtering out 1419relevant and important information. 1420 1421That is why ``abidiff`` tells us about the impact that the change 1422to ``struct widget`` has on function ``fun2()``. In this case, 1423that function uses the type ``struct widget`` **directly** (in 1424its signature). It does not use it via a pointer or a reference. 1425In this case, the direct use of this type causes ``fun2()`` to be 1426exposed to a potentially harmful ABI change. Hence, the report 1427about ``fun2()`` is not filtered out, even though it's about that 1428same change on ``struct widget``. 1429 1430To go further in suppressing reports about changes that are 1431harmless and keeping only those that we know are harmful, we 1432would like to go tell abidiff to suppress reports about this 1433particular ``struct widget`` change when it impacts uses of 1434``struct widget`` through a pointer or reference. In other 1435words, suppress the change reports about ``fun0()`` **and** 1436``fun1()``. We would then write this suppression specification, 1437in file ``widget.suppr``: :: 1438 1439 [suppress_type] 1440 name = widget 1441 type_kind = struct 1442 has_data_member_inserted_at = end 1443 accessed_through = reference-or-pointer 1444 1445 # So this suppression specification says to suppress reports about 1446 # the type 'struct widget', if this type was added some data member 1447 # at its end, and if the change impacts uses of the type through a 1448 # reference or a pointer. 1449 1450Invoking ``abidiff`` on ``widget-v0.o`` and ``widget-v1.o`` with 1451this suppression specification yields: :: 1452 1453 $ abidiff --suppressions widget.suppr widget-v0.o widget-v1.o 1454 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function 1455 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1456 1457 1 function with some indirect sub-type change: 1458 1459 [C]'function void fun2(widget)' has some indirect sub-type changes: 1460 parameter 1 of type 'struct widget' has sub-type changes: 1461 type size changed from 64 to 128 bits 1462 2 data member insertions: 1463 'int widget::w', at offset 64 (in bits) 1464 'int widget::h', at offset 96 (in bits) 1465 $ 1466 1467As expected, I guess. 1468 1469Suppressing change reports about functions. 1470 1471Suppose we have a first version a library named 1472``libtest2-v0.so`` whose source code is: :: 1473 1474 $ cat -n test2-v0.cc 1475 1476 1 struct S1 1477 2 { 1478 3 int m0; 1479 4 1480 5 S1() 1481 6 : m0() 1482 7 {} 1483 8 }; 1484 9 1485 10 struct S2 1486 11 { 1487 12 int m0; 1488 13 1489 14 S2() 1490 15 : m0() 1491 16 {} 1492 17 }; 1493 18 1494 19 struct S3 1495 20 { 1496 21 int m0; 1497 22 1498 23 S3() 1499 24 : m0() 1500 25 {} 1501 26 }; 1502 27 1503 28 int 1504 29 func(S1&) 1505 30 { 1506 31 // suppose the code does something with the argument. 1507 32 return 0; 1508 33 1509 34 } 1510 35 1511 36 char 1512 37 func(S2*) 1513 38 { 1514 39 // suppose the code does something with the argument. 1515 40 return 0; 1516 41 } 1517 42 1518 43 unsigned 1519 44 func(S3) 1520 45 { 1521 46 // suppose the code does something with the argument. 1522 47 return 0; 1523 48 } 1524 $ 1525 1526And then we come up with a second version ``libtest2-v1.so`` of 1527that library; the source code is modified by making the 1528structures ``S1``, ``S2``, ``S3`` inherit another struct: :: 1529 1530 $ cat -n test2-v1.cc 1531 1 struct base_type 1532 2 { 1533 3 int m_inserted; 1534 4 }; 1535 5 1536 6 struct S1 : public base_type // <--- S1 now has base_type as its base 1537 7 // type. 1538 8 { 1539 9 int m0; 1540 10 1541 11 S1() 1542 12 : m0() 1543 13 {} 1544 14 }; 1545 15 1546 16 struct S2 : public base_type // <--- S2 now has base_type as its base 1547 17 // type. 1548 18 { 1549 19 int m0; 1550 20 1551 21 S2() 1552 22 : m0() 1553 23 {} 1554 24 }; 1555 25 1556 26 struct S3 : public base_type // <--- S3 now has base_type as its base 1557 27 // type. 1558 28 { 1559 29 int m0; 1560 30 1561 31 S3() 1562 32 : m0() 1563 33 {} 1564 34 }; 1565 35 1566 36 int 1567 37 func(S1&) 1568 38 { 1569 39 // suppose the code does something with the argument. 1570 40 return 0; 1571 41 1572 42 } 1573 43 1574 44 char 1575 45 func(S2*) 1576 46 { 1577 47 // suppose the code does something with the argument. 1578 48 return 0; 1579 49 } 1580 50 1581 51 unsigned 1582 52 func(S3) 1583 53 { 1584 54 // suppose the code does something with the argument. 1585 55 return 0; 1586 56 } 1587 $ 1588 1589Now let's build the two libraries: :: 1590 1591 g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc 1592 g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc 1593 1594Let's look at the output of ``abidiff``: :: 1595 1596 $ abidiff libtest2-v0.so libtest2-v1.so 1597 Functions changes summary: 0 Removed, 3 Changed, 0 Added functions 1598 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1599 1600 3 functions with some indirect sub-type change: 1601 1602 [C]'function unsigned int func(S3)' has some indirect sub-type changes: 1603 parameter 0 of type 'struct S3' has sub-type changes: 1604 size changed from 32 to 64 bits 1605 1 base class insertion: 1606 struct base_type 1607 1 data member change: 1608 'int S3::m0' offset changed from 0 to 32 1609 1610 [C]'function char func(S2*)' has some indirect sub-type changes: 1611 parameter 0 of type 'S2*' has sub-type changes: 1612 in pointed to type 'struct S2': 1613 size changed from 32 to 64 bits 1614 1 base class insertion: 1615 struct base_type 1616 1 data member change: 1617 'int S2::m0' offset changed from 0 to 32 1618 1619 [C]'function int func(S1&)' has some indirect sub-type changes: 1620 parameter 0 of type 'S1&' has sub-type changes: 1621 in referenced type 'struct S1': 1622 size changed from 32 to 64 bits 1623 1 base class insertion: 1624 struct base_type 1625 1 data member change: 1626 'int S1::m0' offset changed from 0 to 32 1627 $ 1628 1629Let's tell ``abidiff`` to avoid showing us the differences on the 1630overloads of ``func`` that takes either a pointer or a reference. 1631For that, we author this simple suppression specification: :: 1632 1633 $ cat -n libtest2.suppr 1634 1 [suppress_function] 1635 2 name = func 1636 3 parameter = '0 S1& 1637 4 1638 5 [suppress_function] 1639 6 name = func 1640 7 parameter = '0 S2* 1641 $ 1642 1643And then let's invoke ``abidiff`` with the suppression 1644specification: :: 1645 1646 $ ../build/tools/abidiff --suppressions libtest2.suppr libtest2-v0.so libtest2-v1.so 1647 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function 1648 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1649 1650 1 function with some indirect sub-type change: 1651 1652 [C]'function unsigned int func(S3)' has some indirect sub-type changes: 1653 parameter 0 of type 'struct S3' has sub-type changes: 1654 size changed from 32 to 64 bits 1655 1 base class insertion: 1656 struct base_type 1657 1 data member change: 1658 'int S3::m0' offset changed from 0 to 32 1659 1660 1661The suppression specification could be reduced using 1662:ref:`regular expressions <suppr_regexp_label>`: :: 1663 1664 $ cat -n libtest2-1.suppr 1665 1 [suppress_function] 1666 2 name = func 1667 3 parameter = '0 /^S.(&|\\*)/ 1668 $ 1669 1670 $ ../build/tools/abidiff --suppressions libtest2-1.suppr libtest2-v0.so libtest2-v1.so 1671 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function 1672 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable 1673 1674 1 function with some indirect sub-type change: 1675 1676 [C]'function unsigned int func(S3)' has some indirect sub-type changes: 1677 parameter 0 of type 'struct S3' has sub-type changes: 1678 size changed from 32 to 64 bits 1679 1 base class insertion: 1680 struct base_type 1681 1 data member change: 1682 'int S3::m0' offset changed from 0 to 32 1683 1684 $ 1685 1686.. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format 1687 1688.. _Ini File Syntax: http://en.wikipedia.org/wiki/INI_file 1689 1690.. _GNU C Library: http://www.gnu.org/software/libc 1691