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