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