5 .. _abi_artifacts_label:
10 An ABI artifact is a relevant part of the ABI of a shared library or
11 program. Examples of ABI artifacts are exported types, variables,
12 functions, or `ELF`_ symbols exported by a shared library.
14 The set of ABI artifact for a binary is called an ABI Corpus.
16 .. _harmfulchangeconcept_label:
21 A change in the diff report is considered harmful if it might cause
22 ABI compatibility issues. That is, it might prevent an application
23 dynamically linked against a given version of a library to keep
24 working with the changed subsequent versions of the same library.
26 .. _harmlesschangeconcept_label:
31 A change in the diff report is considered harmless if it will not
32 cause any ABI compatibility issue. That is, it will not prevent an
33 application dynamically linked against given version of a library to
34 keep working with the changed subsequent versions of the same library.
36 By default, ``abidiff`` filters harmless changes from the diff report.
40 Suppression specifications
41 ==========================
47 A suppression specification file is a way for a user to instruct
48 :ref:`abidiff <abidiff_label>`, :ref:`abipkgdiff <abipkgdiff_label>`
49 or any other relevant libabigail tool to avoid emitting reports for
50 changes involving certain :ref:`ABI artifacts<abi_artifacts_label>`.
52 It contains directives (or specifications) that describe the set of
53 ABI artifacts to avoid emitting change reports about.
58 Its syntax is based on a simplified and customized form of `Ini File
59 Syntax`_. For instance, to specify that change reports on a type
60 named FooPrivateType should be suppressed, one could write this
61 suppression specification: ::
66 If we want to ensure that only change reports about structures named
67 FooPrivateType should be suppressed, we could write: ::
73 But we could also want to suppress change reports avoid typedefs named
74 FooPrivateType. In that case we would write: ::
80 Or, we could want to suppress change reports about all struct which
81 names end with the string "PrivateType": ::
85 name_regexp = ^.*PrivateType
87 Let's now look at the generic syntax of suppression specification
96 More generally, the format of suppression lists is organized around
97 the concept of `property`. Every property has a name and a value,
98 delimited by the ``=`` sign. E.g: ::
102 Leading and trailing white spaces are ignored around property names
105 .. _suppr_regexp_label:
110 The value of some properties might be a regular expression. In that
111 case, they must comply with the syntax of `extended POSIX regular
113 <http://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002dextended-regular-expression-syntax.html#posix_002dextended-regular-expression-syntax>`_.
114 Note that Libabigail uses the regular expression engine of the `GNU C
117 Escaping a character in a regular expression
118 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
120 When trying to match a string that contains a ``*`` character, like in
121 the pointer type ``int*``, one must be careful to notice that the
122 character ``*`` is a special character in the extended POSIX regular
123 expression syntax. And that character must be escaped for the regular
124 expression engine. Thus the regular expression that would match the
125 string ``int*`` in a suppression file should be ::
129 Wait; but then why the two ``\`` characters? Well, because the ``\``
130 character is a special character in the `Ini File Syntax`_ used for
131 specifying suppressions. So it must be escaped as well, so that the
132 Ini File parser leaves a ``\`` character intact in the data stream
133 that is handed to the regular expression engine. Hence the ``\\``
134 targeted at the Ini File parser.
136 So, in short, to escape a character in a regular expression, always
137 prefix the character with the ``\\`` sequence.
143 Suppression specifications can be applied at two different points of
144 the processing pipeline of libabigail.
146 .. _late_suppression_mode_label:
148 In the default operating mode called "late suppression mode",
149 suppression specifications are applied to the result of comparing the
150 in-memory internal representations of two ABIs. In this mode, if an
151 ABI artifact matches a suppression specification, its changes are not
152 mentioned in the ABI change report. The internal representation of
153 the "suppressed" changed ABI artifact is still present in memory; it
154 is just not mentioned in the ABI change report. The change report can
155 still mention statistics about the number of changed ABI artifacts
156 that were suppressed.
158 .. _early_suppression_mode_label:
160 There is another operating mode called the "early suppression mode"
161 where suppression specifications are applied during the construction
162 of the in-memory internal representation of a given ABI. In that
163 mode, if an ABI artifact matches a suppression specification, no
164 in-memory internal representation is built for it. As a result, no
165 change about the matched ABI artifact is going to be mentioned in the
166 ABI change report and no statistic about the number of suppressed ABI
167 changes is available. Also, please note that because suppressed ABI
168 artifacts are removed from the in-memory internal representation in
169 this mode, the amount memory used by the internal representation is
170 potentially smaller than the memory consumption in the late
176 Properties are then grouped into arbitrarily named sections that shall
177 not be nested. The name of the section is on a line by itself and is
178 surrounded by square brackets, i.e: ::
181 property1_name = property1_value
182 property2_name = property2_value
185 A section might or might not have properties. Sections that expect to
186 have properties and which are found nonetheless empty are just
187 ignored. Properties that are not recognized by the reader are ignored
193 Each different section can be thought of as being a directive to
194 suppress ABI change reports for a particular kind of ABI artifact.
199 This directive prevents a given tool from loading a file (binary or
200 not) if its file name matches certain properties. Thus, if the tool
201 is meant to compare the ABIs of two files, and if the directive
202 prevents it from loading either one of the files, then no comparison
205 Note that for the ``[suppress_file]`` directive to work, at least one
206 of the following properties must be provided:
208 ``file_name_regexp``, ``file_name_not_regexp``.
210 The potential properties of this sections are listed below:
212 * ``file_name_regexp``
216 ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
218 Prevents the system from loading the file which name matches the
219 regular expression specified as value of this property.
221 * ``file_name_not_regexp``
225 ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
227 Prevents the system from loading the file which name does not match
228 the regular expression specified as value of this property.
235 ``label`` ``=`` <some-value>
237 Define a label for the section. A label is just an informative
238 string that might be used by the tool to refer to a type suppression
244 This directive suppresses report messages about a type change.
246 Note that for the ``[suppress_type]`` directive to work, at least one
247 of the following properties must be provided:
249 ``file_name_regexp``, ``file_name_not_regexp``, ``soname_regexp``,
250 ``soname_not_regexp``, ``name``, ``name_regexp``,
251 ``name_not_regexp``, ``type_kind``, ``source_location_not_in``,
252 ``source_location_not_regexp``.
254 If none of the following properties are provided, then the
255 ``[suppress_type]`` directive is simply ignored.
257 The potential properties of this sections are listed below:
259 * ``file_name_regexp``
263 ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
265 Suppresses change reports about ABI artifacts that are defined in a
266 binary file which name matches the regular expression specified as
267 value of this property.
269 * ``file_name_not_regexp``
273 ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
275 Suppresses change reports about ABI artifacts that are defined in a
276 binary file which name does not match the regular expression
277 specified as value of this property.
284 ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
286 Suppresses change reports about ABI artifacts that are defined in a
287 shared library which SONAME property matches the regular expression
288 specified as value of this property.
290 * ``soname_not_regexp``
294 ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
296 Suppresses change reports about ABI artifacts that are defined in a
297 shared library which SONAME property does not match the regular
298 expression specified as value of this property.
304 ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
306 Suppresses change reports involving types whose name matches the
307 regular expression specified as value of this property.
310 * ``name_not_regexp``
314 ``name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
316 Suppresses change reports involving types whose name does *NOT* match
317 the regular expression specified as value of this property. Said
318 otherwise, this property specifies which types to keep, rather than
319 types to suppress from reports.
325 ``name`` ``=`` <a-value>
327 Suppresses change reports involving types whose name equals the value
334 ``type_kind`` ``=`` ``class`` | ``struct`` | ``union`` | ``enum`` |
335 ``array`` | ``typedef`` | ``builtin``
337 Suppresses change reports involving a certain kind of type. The kind
338 of type to suppress change reports for is specified by the possible
341 - ``class``: suppress change reports for class types. Note that
342 even if class types don't exist for C, this value still
343 triggers the suppression of change reports for struct types,
344 in C. In C++ however, it should do what it suggests.
346 - ``struct``: suppress change reports for struct types in C or C++.
347 Note that the value ``class`` above is a super-set of this
350 - ``union``: suppress change reports for union types.
352 - ``enum``: suppress change reports for enum types.
354 - ``array``: suppress change reports for array types.
356 - ``typedef``: suppress change reports for typedef types.
358 - ``builtin``: suppress change reports for built-in (or native)
359 types. Example of built-in types are char, int, unsigned int,
362 .. _suppr_source_location_not_in_label:
364 * ``source_location_not_in``
368 ``source_location_not_in`` ``=`` <``list-of-file-paths``>
370 Suppresses change reports involving a type which is defined in a file
371 which path is *NOT* listed in the value ``list-of-file-paths``. Note
372 that the value is a comma-separated list of file paths e.g, this
375 source_location_not_in = libabigail/abg-ir.h, libabigail/abg-dwarf-reader.h
377 suppresses change reports about all the types that are *NOT* defined
378 in header files whose path end up with the strings
379 libabigail/abg-ir.h or libabigail/abg-dwarf-reader.h.
381 .. _suppr_source_location_not_regexp_label:
383 * ``source_location_not_regexp``
387 ``source_location_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
389 Suppresses change reports involving a type which is defined in a file
390 which path does *NOT* match the :ref:`regular expression
391 <suppr_regexp_label>` provided as value of the property. E.g, this
394 source_location_not_regexp = libabigail/abg-.*\\.h
396 suppresses change reports involving all the types that are *NOT*
397 defined in header files whose path match the regular expression
398 provided a value of the property.
400 .. _suppr_has_data_member_inserted_at_label:
402 * ``has_data_member_inserted_at``
406 ``has_data_member_inserted_at`` ``=`` <``offset-in-bit``>
408 Suppresses change reports involving a type which has at least one
409 data member inserted at an offset specified by the property value
410 ``offset-in-bit``. The value ``offset-in-bit`` is either:
412 - an integer value, expressed in bits, which denotes the
413 offset of the insertion point of the data member, starting
414 from the beginning of the relevant structure or class.
416 - the keyword ``end`` which is a named constant which value
417 equals the offset of the end of the of the structure or
420 - the function call expression
421 ``offset_of(data-member-name)`` where `data-member-name` is
422 the name of a given data member of the relevant structure
423 or class. The value of this function call expression is an
424 integer that represents the offset of the data member
425 denoted by ``data-member-name``.
427 - the function call expression
428 ``offset_after(data-member-name)`` where `data-member-name`
429 is the name of a given data member of the relevant
430 structure or class. The value of this function call
431 expression is an integer that represents the offset of the
432 point that comes right after the region occupied by the
433 data member denoted by ``data-member-name``.
435 .. _suppr_has_data_member_inserted_between_label:
438 * ``has_data_member_inserted_between``
442 ``has_data_member_inserted_between`` ``=`` {<``range-begin``>, <``range-end``>}
444 Suppresses change reports involving a type which has at least one
445 data mber inserted at an offset that is comprised in the range
446 between range-begin`` and ``range-end``. Please note that each of
447 the lues ``range-begin`` and ``range-end`` can be of the same form as
448 the :ref:`has_data_member_inserted_at
449 <suppr_has_data_member_inserted_at_label>` property above.
451 Usage examples of this properties are: ::
453 has_data_member_inserted_between = {8, 64}
457 has_data_member_inserted_between = {16, end}
461 has_data_member_inserted_between = {offset_after(member1), end}
463 .. _suppr_has_data_members_inserted_between_label:
466 * ``has_data_members_inserted_between``
470 ``has_data_members_inserted_between`` ``=`` {<sequence-of-ranges>}
472 Suppresses change reports involving a type which has multiple data
473 member inserted in various offset ranges. A usage example of this
474 property is, for instance: ::
476 has_data_members_inserted_between = {{8, 31}, {72, 95}}
478 This usage example suppresses change reports involving a type which
479 has data members inserted in bit offset ranges [8 31] and [72 95].
480 The length of the sequence of ranges or this
481 ``has_data_members_inserted_between`` is not bounded; it can be as
482 long as the system can cope with. The values of the boundaries of
483 the ranges are of the same kind as for the
484 :ref:`has_data_member_inserted_at
485 <suppr_has_data_member_inserted_at_label>` property above.
487 Another usage example of this property is thus: ::
489 has_data_members_inserted_between =
491 {offset_after(member0), offset_of(member1)},
495 .. _suppr_accessed_through_property_label:
497 * ``accessed_through``
501 ``accessed_through`` ``=`` <some-predefined-values>
503 Suppress change reports involving a type which is referred to either
504 directly or through a pointer or a reference. The potential values
505 of this property are the predefined keywords below:
509 So if the ``[suppress_type]`` contains the property
512 accessed_through = direct
514 then changes about a type that is referred-to
515 directly (i.e, not through a pointer or a reference)
516 are going to be suppressed.
520 If the ``accessed_through`` property is set to the
521 value ``pointer`` then changes about a type that is
522 referred-to through a pointer are going to be
527 If the ``accessed_through`` property is set to the
528 value ``reference`` then changes about a type that is
529 referred-to through a reference are going to be
532 * ``reference-or-pointer``
534 If the ``accessed_through`` property is set to the
535 value ``reference-or-pointer`` then changes about a
536 type that is referred-to through either a reference
537 or a pointer are going to be suppressed.
539 For an extensive example of how to use this property, please check
540 out the example below about :ref:`suppressing change reports about
541 types accessed either directly or through pointers
542 <example_accessed_through_label>`.
548 ``drop`` ``=`` yes | no
550 If a type is matched by a suppression specification which contains
551 the "drop" property set to "yes" (or to "true") then the type is not
552 even going to be represented in the internal representation of the
553 ABI being analyzed. This property makes its enclosing suppression
554 specification to be applied in the :ref:`early suppression
555 specification mode <early_suppression_mode_label>`. The net effect
556 is that it potentially reduces the memory used to represent the ABI
559 Please note that for this property to be effective, the enclosing
560 suppression specification must have at least one of the following
561 properties specified: ``name_regexp``, ``name``, ``name_regexp``,
562 ``source_location_not_in`` or ``source_location_not_regexp``.
564 .. _suppr_label_property_label:
570 ``label`` ``=`` <some-value>
572 Define a label for the section. A label is just an informative
573 string that might be used by a tool to refer to a type suppression in
576 .. _suppr_changed_enumerators_label:
578 * ``changed_enumerators``
582 ``changed_enumerators`` ``=`` <list-of-enumerators>
584 Suppresses change reports involving changes in the value of
585 enumerators of a given enum type. This property is applied if the
586 ``type_kind`` property is set to the value ``enum``, at least. The
587 value of the ``changed_enumerators`` is a comma-separated list of
588 the enumerators that the user expects to change. For instance: ::
590 changed_enumerators = LAST_ENUMERATORS0, LAST_ENUMERATOR1
592 ``[suppress_function]``
593 $$$$$$$$$$$$$$$$$$$$$$$$
595 This directive suppresses report messages about changes on a set of
598 Note that for the ``[suppress_function]`` directive to work, at least
599 one of the following properties must be provided:
601 ``label``, ``file_name_regexp``, ``file_name_not_regexp``,
602 ``soname_regexp``, ``soname_not_regexp``, ``name``, ``name_regexp``,
603 ``name_not_regexp``, ``parameter``, ``return_type_name``,
604 ``symbol_name``, ``symbol_name_regexp``, ``symbol_version``,
605 ``symbol_version_regexp``.
607 If none of the following properties are provided, then the
608 ``[suppress_function]`` directive is simply ignored.
610 The potential properties of this sections are:
616 ``label`` ``=`` <some-value>
618 This property is the same as the :ref:`label property
619 <suppr_label_property_label>` defined above.
622 * ``file_name_regexp``
626 ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
628 Suppresses change reports about ABI artifacts that are defined in a
629 binary file which name matches the regular expression specified as
630 value of this property.
633 * ``file_name_not_regexp``
637 ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
639 Suppresses change reports about ABI artifacts that are defined in a
640 binary file which name does not match the regular expression
641 specified as value of this property.
647 ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
649 Suppresses change reports about ABI artifacts that are defined in a
650 shared library which SONAME property matches the regular expression
651 specified as value of this property.
653 * ``soname_not_regexp``
657 ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
659 Suppresses change reports about ABI artifacts that are defined in a
660 shared library which SONAME property does not match the regular
661 expression specified as value of this property.
668 ``name`` ``=`` <some-value>
670 Suppresses change reports involving functions whose name equals the
671 value of this property.
677 ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
679 Suppresses change reports involving functions whose name matches the
680 regular expression specified as value of this property.
682 Let's consider the case of functions that have several symbol names.
683 This happens when the underlying symbol for the function has
684 aliases. Each symbol name is actually one alias name.
686 In this case, if the regular expression matches the name of
687 at least one of the aliases names, then it must match the names of
688 all of the aliases of the function for the directive to actually
689 suppress the diff reports for said function.
692 * ``name_not_regexp``
696 ``name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
698 Suppresses change reports involving functions whose names don't match
699 the regular expression specified as value of this property.
701 The rules for functions that have several symbol names are the same
702 rules as for the ``name_regexp`` property above.
704 .. _suppr_change_kind_property_label:
711 ``change_kind`` ``=`` <predefined-possible-values>
713 Specifies the kind of changes this suppression specification should
714 apply to. The possible values of this property as well as their
715 meaning are listed below:
717 - ``function-subtype-change``
719 This suppression specification applies to functions
720 that which have at least one sub-type that has
725 This suppression specification applies to functions
726 that have been added to the binary.
728 - ``deleted-function``
730 This suppression specification applies to functions
731 that have been removed from the binary.
735 This suppression specification applies to functions
736 that have all of the changes above. Note that not
737 providing the ``change_kind`` property at all is
738 equivalent to setting it to the value ``all``.
745 ``parameter`` ``=`` <function-parameter-specification>
747 Suppresses change reports involving functions whose
748 parameters match the parameter specification indicated as
749 value of this property.
751 The format of the function parameter specification is:
753 ``'`` ``<parameter-index>`` ``<space>`` ``<type-name-or-regular-expression>``
755 That is, an apostrophe followed by a number that is the
756 index of the parameter, followed by one of several spaces,
757 followed by either the name of the type of the parameter,
758 or a regular expression describing a family of parameter
761 If the parameter type name is designated by a regular
762 expression, then said regular expression must be enclosed
763 between two slashes; like ``/some-regular-expression/``.
765 The index of the first parameter of the function is zero.
766 Note that for member functions (methods of classes), the
767 this is the first parameter that comes after the implicit
768 "this" pointer parameter.
770 Examples of function parameter specifications are: ::
774 Which means, the parameter at index 0, whose type name is
779 Which means, the parameter at index 4, whose type name is
780 ``unsigned char*``. ::
784 Which means, the parameter at index 2, whose type name
785 starts with the string "foo" and ends with an '&'. In
786 other words, this is the third parameter and it's a
787 reference on a type that starts with the string "foo".
789 * ``return_type_name``
793 ``return_type_name`` ``=`` <some-value>
795 Suppresses change reports involving functions whose return type name
796 equals the value of this property.
798 * ``return_type_regexp``
802 ``return_type_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
804 Suppresses change reports involving functions whose return type name
805 matches the regular expression specified as value of this property.
811 ``symbol_name`` ``=`` <some-value>
813 Suppresses change reports involving functions whose symbol name equals
814 the value of this property.
816 * ``symbol_name_regexp``
820 ``symbol_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
822 Suppresses change reports involving functions whose symbol name
823 matches the regular expression specified as value of this property.
825 Let's consider the case of functions that have several symbol names.
826 This happens when the underlying symbol for the function has
827 aliases. Each symbol name is actually one alias name.
829 In this case, the regular expression must match the names of all of
830 the aliases of the function for the directive to actually suppress
831 the diff reports for said function.
837 ``symbol_version`` ``=`` <some-value>
839 Suppresses change reports involving functions whose symbol version
840 equals the value of this property.
842 * ``symbol_version_regexp``
846 ``symbol_version_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
848 Suppresses change reports involving functions whose symbol version
849 matches the regular expression specified as value of this property.
855 ``drop`` ``=`` yes | no
857 If a function is matched by a suppression specification which
858 contains the "drop" property set to "yes" (or to "true") then the
859 function is not even going to be represented in the internal
860 representation of the ABI being analyzed. This property makes its
861 enclosing suppression specification to be applied in the :ref:`early
862 suppression specification mode <early_suppression_mode_label>`. The
863 net effect is that it potentially reduces the memory used to
864 represent the ABI being analyzed.
866 Please note that for this property to be effective, the enclosing
867 suppression specification must have at least one of the following
868 properties specified: ``name_regexp``, ``name``, ``name_regexp``,
869 ``source_location_not_in`` or ``source_location_not_regexp``.
871 ``[suppress_variable]``
872 $$$$$$$$$$$$$$$$$$$$$$$$
874 This directive suppresses report messages about changes on a set of
877 Note that for the ``[suppress_variable]`` directive to work, at least
878 one of the following properties must be provided:
880 ``label``, ``file_name_regexp``, ``file_name_not_regexp``,
881 ``soname_regexp``, ``soname_not_regexp``, ``name``, ``name_regexp``,
882 ``symbol_name``, ``symbol_name_regexp``, ``symbol_version``,
883 ``symbol_version_regexp``.
885 If none of the following properties are provided, then the
886 ``[suppres_variable]`` directive is simply ignored.
888 The potential properties of this sections are:
894 ``label`` ``=`` <some-value>
896 This property is the same as the :ref:`label property
897 <suppr_label_property_label>` defined above.
900 * ``file_name_regexp``
904 ``file_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
906 Suppresses change reports about ABI artifacts that are defined in a
907 binary file which name matches the regular expression specified as
908 value of this property.
910 * ``file_name_not_regexp``
914 ``file_name_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
916 Suppresses change reports about ABI artifacts that are defined in a
917 binary file which name does not match the regular expression
918 specified as value of this property.
925 ``soname_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
927 Suppresses change reports about ABI artifacts that are defined in a
928 shared library which SONAME property matches the regular expression
929 specified as value of this property.
932 * ``soname_not_regexp``
936 ``soname_not_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
938 Suppresses change reports about ABI artifacts that are defined in a
939 shared library which SONAME property does not match the regular
940 expression specified as value of this property.
947 ``name`` ``=`` <some-value>
949 Suppresses change reports involving variables whose name equals the
950 value of this property.
956 ``name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
958 Suppresses change reports involving variables whose name matches the
959 regular expression specified as value of this property.
965 ``change_kind`` ``=`` <predefined-possible-values>
967 Specifies the kind of changes this suppression specification should
968 apply to. The possible values of this property as well as their
969 meaning are the same as when it's :ref:`used in the
970 [suppress_function] section <suppr_change_kind_property_label>`.
976 ``symbol_name`` ``=`` <some-value>
978 Suppresses change reports involving variables whose symbol name equals
979 the value of this property.
985 ``symbol_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
987 Suppresses change reports involving variables whose symbol name
988 matches the regular expression specified as value of this property.
995 ``symbol_version`` ``=`` <some-value>
997 Suppresses change reports involving variables whose symbol version
998 equals the value of this property.
1000 * ``symbol_version_regexp``
1004 ``symbol_version_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1006 Suppresses change reports involving variables whose symbol version
1007 matches the regular expression specified as value of this property.
1013 ``type_name`` ``=`` <some-value>
1015 Suppresses change reports involving variables whose type name equals
1016 the value of this property.
1018 * ``type_name_regexp``
1022 ``type_name_regexp`` ``=`` <:ref:`regular-expression <suppr_regexp_label>`>
1024 Suppresses change reports involving variables whose type name matches
1025 the regular expression specified as value of this property.
1030 ``;`` or ``#`` ASCII character at the beginning of a line
1031 indicates a comment. Comment lines are ignored.
1036 1. Suppressing change reports about types.
1038 Suppose we have a library named ``libtest1-v0.so`` which
1039 contains this very useful code: ::
1041 $ cat -n test1-v0.cc
1042 1 // A forward declaration for a type considered to be opaque to
1043 2 // function foo() below.
1044 3 struct opaque_type;
1046 5 // This function cannot touch any member of opaque_type. Hence,
1047 6 // changes to members of opaque_type should not impact foo, as far as
1048 7 // ABI is concerned.
1054 13 struct opaque_type
1061 Let's change the layout of struct opaque_type by inserting a data
1062 member around line 15, leading to a new version of the library,
1063 that we shall name ``libtest1-v1.so``: ::
1065 $ cat -n test1-v1.cc
1066 1 // A forward declaration for a type considered to be opaque to
1067 2 // function foo() below.
1068 3 struct opaque_type;
1070 5 // This function cannot touch any member of opaque_type; Hence,
1071 6 // changes to members of opaque_type should not impact foo, as far as
1072 7 // ABI is concerned.
1078 13 struct opaque_type
1080 15 char added_member; // <-- a new member got added here now.
1086 Let's compile both examples. We shall not forget to compile them
1087 with debug information generation turned on: ::
1089 $ g++ -shared -g -Wall -o libtest1-v0.so test1-v0.cc
1090 $ g++ -shared -g -Wall -o libtest1-v1.so test1-v1.cc
1092 Let's ask :ref:`abidiff <abidiff_label>` which ABI differences it sees
1093 between ``libtest1-v0.so`` and ``libtest1-v1.so``: ::
1095 $ abidiff libtest1-v0.so libtest1-v1.so
1096 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
1097 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1099 1 function with some indirect sub-type change:
1101 [C]'function void foo(opaque_type*)' has some indirect sub-type changes:
1102 parameter 0 of type 'opaque_type*' has sub-type changes:
1103 in pointed to type 'struct opaque_type':
1104 size changed from 64 to 96 bits
1105 1 data member insertion:
1106 'char opaque_type::added_member', at offset 0 (in bits)
1107 2 data member changes:
1108 'int opaque_type::member0' offset changed from 0 to 32
1109 'char opaque_type::member1' offset changed from 32 to 64
1112 So ``abidiff`` reports that the opaque_type's layout has changed
1113 in a significant way, as far as ABI implications are concerned, in
1114 theory. After all, a sub-type (``struct opaque_type``) of an
1115 exported function (``foo()``) has seen its layout change. This
1116 might have non negligible ABI implications. But in practice here,
1117 the programmer of the litest1-v1.so library knows that the "soft"
1118 contract between the function ``foo()`` and the type ``struct
1119 opaque_type`` is to stay away from the data members of the type.
1120 So layout changes of ``struct opaque_type`` should not impact
1123 Now to teach ``abidiff`` about this soft contract and have it
1124 avoid emitting what amounts to false positives in this case, we
1125 write the suppression specification file below: ::
1132 Translated in plain English, this suppression specification would
1133 read: "Do not emit change reports about a struct which name is
1136 Let's now invoke ``abidiff`` on the two versions of the library
1137 again, but this time with the suppression specification: ::
1139 $ abidiff --suppressions test1.suppr libtest1-v0.so libtest1-v1.so
1140 Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
1141 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1143 As you can see, ``abidiff`` does not report the change anymore; it
1144 tells us that it was filtered out instead.
1146 Suppressing change reports about types with data member
1149 Suppose the first version of a library named ``libtest3-v0.so``
1150 has this source code: ::
1152 /* Compile this with:
1153 gcc -g -Wall -shared -o libtest3-v0.so test3-v0.c
1160 between member1 and member2, there is some padding,
1161 at least on some popular platforms. On
1162 these platforms, adding a small enough data
1163 member into that padding shouldn't change
1164 the offset of member1. Right?
1171 return s->member0 + s->member1;
1174 Now, suppose the second version of the library named
1175 ``libtest3-v1.so`` has this source code in which a data member
1176 has been added in the padding space of struct S and another data
1177 member has been added at its end: ::
1179 /* Compile this with:
1180 gcc -g -Wall -shared -o libtest3-v1.so test3-v1.c
1186 char inserted1; /* <---- A data member has been added here... */
1188 char inserted2; /* <---- ... and another one has been added here. */
1194 return s->member0 + s->member1;
1198 In libtest3-v1.so, adding char data members ``S::inserted1`` and
1199 ``S::inserted2`` can be considered harmless (from an ABI compatibility
1200 perspective), at least on the x86 platform, because that doesn't
1201 change the offsets of the data members S::member0 and S::member1. But
1202 then running ``abidiff`` on these two versions of library yields: ::
1204 $ abidiff libtest3-v0.so libtest3-v1.so
1205 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
1206 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1208 1 function with some indirect sub-type change:
1210 [C]'function int foo(S*)' has some indirect sub-type changes:
1211 parameter 0 of type 'S*' has sub-type changes:
1212 in pointed to type 'struct S':
1213 type size changed from 64 to 96 bits
1214 2 data member insertions:
1215 'char S::inserted1', at offset 8 (in bits)
1216 'char S::inserted2', at offset 64 (in bits)
1221 That is, ``abidiff`` shows us the two changes, even though we (the
1222 developers of that very involved library) know that these changes
1223 are harmless in this particular context.
1225 Luckily, we can devise a suppression specification that essentially
1226 tells abidiff to filter out change reports about adding a data
1227 member between ``S::member0`` and ``S::member1``, and adding a data
1228 member at the end of struct S. We have written such a suppression
1229 specification in a file called test3-1.suppr and it unsurprisingly
1234 has_data_member_inserted_between = {offset_after(member0), offset_of(member1)}
1235 has_data_member_inserted_at = end
1238 Now running ``abidiff`` with this suppression specification yields: ::
1240 $ ../build/tools/abidiff --suppressions test3-1.suppr libtest3-v0.so libtest3-v1.so
1241 Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
1242 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1247 Hooora! \\o/ (I guess)
1249 .. _example_accessed_through_label:
1251 Suppressing change reports about types accessed either directly
1254 Suppose we have a first version of an object file which source
1255 code is the file widget-v0.cc below: ::
1257 // Compile with: g++ -g -c widget-v0.cc
1272 // .. do stuff here.
1278 // .. do stuff here ..
1284 // ... do other stuff here ...
1287 Now suppose in the second version of that file, named
1288 widget-v1.cc, we have added some data members at the end of
1289 the type ``struct widget``; here is what the content of that file
1292 // Compile with: g++ -g -c widget-v1.cc
1298 int w; // We have added these two new data members here ..
1299 int h; // ... and here.
1302 : x(), y(), w(), h()
1309 // .. do stuff here.
1315 // .. do stuff here ..
1321 // ... do other stuff here ...
1324 When we invoke ``abidiff`` on the object files resulting from the
1325 compilation of the two file above, here is what we get: ::
1327 $ abidiff widget-v0.o widget-v1.o
1328 Functions changes summary: 0 Removed, 2 Changed (1 filtered out), 0 Added functions
1329 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1331 2 functions with some indirect sub-type change:
1333 [C]'function void fun0(widget*)' has some indirect sub-type changes:
1334 parameter 1 of type 'widget*' has sub-type changes:
1335 in pointed to type 'struct widget':
1336 type size changed from 64 to 128 bits
1337 2 data member insertions:
1338 'int widget::w', at offset 64 (in bits)
1339 'int widget::h', at offset 96 (in bits)
1341 [C]'function void fun2(widget)' has some indirect sub-type changes:
1342 parameter 1 of type 'struct widget' has sub-type changes:
1343 details were reported earlier
1346 I guess a little bit of explaining is due here. ``abidiff``
1347 detects that two data member got added at the end of ``struct
1348 widget``. it also tells us that the type change impacts the
1349 exported function ``fun0()`` which uses the type ``struct
1350 widget`` through a pointer, in its signature.
1352 Careful readers will notice that the change to ``struct widget``
1353 also impacts the exported function ``fun1()``, that uses type
1354 ``struct widget`` through a reference. But then ``abidiff``
1355 doesn't tell us about the impact on that function ``fun1()``
1356 because it has evaluated that change as being **redundant** with
1357 the change it reported on ``fun0()``. It has thus filtered it
1358 out, to avoid cluttering the output with noise.
1360 Redundancy detection and filtering is fine and helpful to avoid
1361 burying the important information in a sea of noise. However, it
1362 must be treated with care, by fear of mistakenly filtering out
1363 relevant and important information.
1365 That is why ``abidiff`` tells us about the impact that the change
1366 to ``struct widget`` has on function ``fun2()``. In this case,
1367 that function uses the type ``struct widget`` **directly** (in
1368 its signature). It does not use it via a pointer or a reference.
1369 In this case, the direct use of this type causes ``fun2()`` to be
1370 exposed to a potentially harmful ABI change. Hence, the report
1371 about ``fun2()`` is not filtered out, even though it's about that
1372 same change on ``struct widget``.
1374 To go further in suppressing reports about changes that are
1375 harmless and keeping only those that we know are harmful, we
1376 would like to go tell abidiff to suppress reports about this
1377 particular ``struct widget`` change when it impacts uses of
1378 ``struct widget`` through a pointer or reference. In other
1379 words, suppress the change reports about ``fun0()`` **and**
1380 ``fun1()``. We would then write this suppression specification,
1381 in file ``widget.suppr``: ::
1386 has_data_member_inserted_at = end
1387 accessed_through = reference-or-pointer
1389 # So this suppression specification says to suppress reports about
1390 # the type 'struct widget', if this type was added some data member
1391 # at its end, and if the change impacts uses of the type through a
1392 # reference or a pointer.
1394 Invoking ``abidiff`` on ``widget-v0.o`` and ``widget-v1.o`` with
1395 this suppression specification yields: ::
1397 $ abidiff --suppressions widget.suppr widget-v0.o widget-v1.o
1398 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
1399 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1401 1 function with some indirect sub-type change:
1403 [C]'function void fun2(widget)' has some indirect sub-type changes:
1404 parameter 1 of type 'struct widget' has sub-type changes:
1405 type size changed from 64 to 128 bits
1406 2 data member insertions:
1407 'int widget::w', at offset 64 (in bits)
1408 'int widget::h', at offset 96 (in bits)
1411 As expected, I guess.
1413 Suppressing change reports about functions.
1415 Suppose we have a first version a library named
1416 ``libtest2-v0.so`` whose source code is: ::
1418 $ cat -n test2-v0.cc
1450 31 // suppose the code does something with the argument.
1458 39 // suppose the code does something with the argument.
1465 46 // suppose the code does something with the argument.
1470 And then we come up with a second version ``libtest2-v1.so`` of
1471 that library; the source code is modified by making the
1472 structures ``S1``, ``S2``, ``S3`` inherit another struct: ::
1474 $ cat -n test2-v1.cc
1480 6 struct S1 : public base_type // <--- S1 now has base_type as its base
1490 16 struct S2 : public base_type // <--- S2 now has base_type as its base
1500 26 struct S3 : public base_type // <--- S3 now has base_type as its base
1513 39 // suppose the code does something with the argument.
1521 47 // suppose the code does something with the argument.
1528 54 // suppose the code does something with the argument.
1533 Now let's build the two libraries: ::
1535 g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc
1536 g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc
1538 Let's look at the output of ``abidiff``: ::
1540 $ abidiff libtest2-v0.so libtest2-v1.so
1541 Functions changes summary: 0 Removed, 3 Changed, 0 Added functions
1542 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1544 3 functions with some indirect sub-type change:
1546 [C]'function unsigned int func(S3)' has some indirect sub-type changes:
1547 parameter 0 of type 'struct S3' has sub-type changes:
1548 size changed from 32 to 64 bits
1549 1 base class insertion:
1551 1 data member change:
1552 'int S3::m0' offset changed from 0 to 32
1554 [C]'function char func(S2*)' has some indirect sub-type changes:
1555 parameter 0 of type 'S2*' has sub-type changes:
1556 in pointed to type 'struct S2':
1557 size changed from 32 to 64 bits
1558 1 base class insertion:
1560 1 data member change:
1561 'int S2::m0' offset changed from 0 to 32
1563 [C]'function int func(S1&)' has some indirect sub-type changes:
1564 parameter 0 of type 'S1&' has sub-type changes:
1565 in referenced type 'struct S1':
1566 size changed from 32 to 64 bits
1567 1 base class insertion:
1569 1 data member change:
1570 'int S1::m0' offset changed from 0 to 32
1573 Let's tell ``abidiff`` to avoid showing us the differences on the
1574 overloads of ``func`` that takes either a pointer or a reference.
1575 For that, we author this simple suppression specification: ::
1577 $ cat -n libtest2.suppr
1578 1 [suppress_function]
1580 3 parameter = '0 S1&
1582 5 [suppress_function]
1584 7 parameter = '0 S2*
1587 And then let's invoke ``abidiff`` with the suppression
1590 $ ../build/tools/abidiff --suppressions libtest2.suppr libtest2-v0.so libtest2-v1.so
1591 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
1592 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1594 1 function with some indirect sub-type change:
1596 [C]'function unsigned int func(S3)' has some indirect sub-type changes:
1597 parameter 0 of type 'struct S3' has sub-type changes:
1598 size changed from 32 to 64 bits
1599 1 base class insertion:
1601 1 data member change:
1602 'int S3::m0' offset changed from 0 to 32
1605 The suppression specification could be reduced using
1606 :ref:`regular expressions <suppr_regexp_label>`: ::
1608 $ cat -n libtest2-1.suppr
1609 1 [suppress_function]
1611 3 parameter = '0 /^S.(&|\\*)/
1614 $ ../build/tools/abidiff --suppressions libtest2-1.suppr libtest2-v0.so libtest2-v1.so
1615 Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
1616 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1618 1 function with some indirect sub-type change:
1620 [C]'function unsigned int func(S3)' has some indirect sub-type changes:
1621 parameter 0 of type 'struct S3' has sub-type changes:
1622 size changed from 32 to 64 bits
1623 1 base class insertion:
1625 1 data member change:
1626 'int S3::m0' offset changed from 0 to 32
1630 .. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format
1632 .. _Ini File Syntax: http://en.wikipedia.org/wiki/INI_file
1634 .. _GNU C Library: http://www.gnu.org/software/libc