Provided by: abigail-doc_2.4-3build1_all bug

NAME

       libabigail - Library to analyze and compare ELF ABIs

OVERVIEW OF THE ABIGAIL FRAMEWORK

       ABIGAIL stands for the Application Binary Interface Generic Analysis and Instrumentation Library.

       It’s  a  framework  which  aims  at helping developers and software distributors to spot some ABI-related
       issues like interface incompatibility in ELF shared libraries by performing a static analysis of the  ELF
       binaries at hand.

       The type of interface incompatibilities that Abigail focuses on is related to changes on the exported ELF
       functions and variables symbols, as well as layout and size changes of data types of  the  functions  and
       variables exported by shared libraries.

       In  other words, if the return type of a function exported by a shared library changes in an incompatible
       way from one version of a given shared library to another, we want Abigail to help people catch that.

       In more concrete terms, the Abigail framwork provides a shared library named libabigail which exposes  an
       API  to  parse a shared library in ELF format (accompanied with its associated debug information in DWARF
       format) build an internal representation of all the functions and variables it exports, along with  their
       types.   Libabigail  also  builds  an  internal  representation of the ELF symbols of these functions and
       variables.  That information about these exported functions and variables is roughly what we consider  as
       being the ABI of the shared library, at least, in the scope of Libabigail.

       Aside  of this internal representation, libabigail provides facilities to perform deep comparisons of two
       ABIs.  That is, it can compare the types of two sets of functions or variables and represents the  result
       in a way that allows it to emit textual reports about the differences.

       This allows us to write tools like abidiff that can compare the ABI of two shared libraries and represent
       the result in a meaningful enough way to help us spot ABI incompatibilities.   There  are  several  other
       tools that are built using the Abigail framwork.

TOOLS

   Overview
       The  upstream  code  repository of Libabigail contains several tools written using the library.  They are
       maintained and released as part of the project.  All tools come with a bash-completion script.

   Tools manuals
   abidiff
       abidiff compares the Application Binary Interfaces (ABI) of two shared libraries in ELF format.  It emits
       a meaningful report describing the differences between the two ABIs.

       This  tool  can  also  compare  the textual representations of the ABI of two ELF binaries (as emitted by
       abidw) or an ELF binary against a textual representation of another ELF binary.

       For a comprehensive ABI change report between two input shared  libraries  that  includes  changes  about
       function  and variable sub-types, abidiff uses by default, debug information in DWARF format, if present,
       otherwise it compares interfaces using debug information in CTF or BTF formats, if present.  Finally,  if
       no debug info in these formats is found, it only considers ELF symbols and report about their addition or
       removal.

       This tool uses the libabigail library to analyze the binary as well as its associated debug  information.
       Here is its general mode of operation.

       When  instructed  to  do so, a binary and its associated debug information is read and analyzed.  To that
       effect, libabigail analyzes by default  the  descriptions  of  the  types  reachable  by  the  interfaces
       (functions  and  variables)  that  are  visible outside of their translation unit.  Once that analysis is
       done, an Application Binary Interface Corpus is constructed by  only  considering  the  subset  of  types
       reachable  from  interfaces  associated to ELF symbols that are defined and exported by the binary.  It’s
       that final ABI corpus which libabigail considers as representing the ABI of the analyzed binary.

       Libabigail then has capabilities to generate  textual  representations  of  ABI  Corpora,  compare  them,
       analyze their changes and report about them.

   Invocation
          abidiff [options] <first-shared-library> <second-shared-library>

   Environment
       abidiff loads two default suppression specifications files, merges their content and use it to filter out
       ABI change reports that might be considered as false positives to users.

       • Default system-wide suppression specification file

         It’s located by the optional environment variable LIBABIGAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE.  If  that
         environment   variable   is   not   set,   then   abidiff   tries   to   load   the   suppression  file
         $libdir/libabigail/libabigail-default.abignore.   If  that  file  is  not  present,  then  no   default
         system-wide suppression specification file is loaded.

       • Default user suppression specification file.

         It’s located by the optional environment LIBABIGAIL_DEFAULT_USER_SUPPRESSION_FILE.  If that environment
         variable is not set, then abidiff tries to load the suppression file $HOME/.abignore.  If that file  is
         not present, then no default user suppression specification is loaded.

   Options--help | -h

            Display a short help about the command and exit.

          • --debug-self-comparison

            In  this  mode,  error  messages  are  emitted  for  types which fail type canonicalization, in some
            circumstances, when comparing a binary against itself.

            When comparing a binary against itself, canonical types of the second binary  should  be  equal  (as
            much  as  possible) to canonical types of the first binary.  When some discrepancies are detected in
            this mode, an abort signal is emitted and execution is halted.  This option  should  be  used  while
            executing the tool in a debugger, for troubleshooting purposes.

            This is an optional debugging and sanity check option.  To enable it the libabigail package needs to
            be configured with the –enable-debug-self-comparison configure option.

          • --debug-tc

            In this mode, the process of type canonicalization is put under heavy scrutiny.   Basically,  during
            type canonicalization, each type comparison is performed twice: once in a structural mode (comparing
            every sub-type member-wise), and once using canonical comparison.  The two comparisons should  yield
            the  same  result.   Otherwise,  an  abort  signal  is  emitted  and  the process can be debugged to
            understand why the two kinds of comparison yield different results.

            This is an optional debugging and sanity check option.  To enable it the libabigail package needs to
            be configured with the –enable-debug-type-canonicalization configure option.

          • --version | -v

            Display the version of the program and exit.

          • --debug-info-dir1 | --d1 <di-path1>

            For  cases  where  the debug information for first-shared-library is split out into a separate file,
            tells abidiff where to find that separate debug information file.

            Note that di-path must point to the root directory under which the debug information is arranged  in
            a tree-like manner.  Under Red Hat based systems, that directory is usually <root>/usr/lib/debug.

            This  option  can  be provided several times with different root directories.  In that case, abidiff
            will  potentially  look  into  all  those  root  directories  to  find  the  split  debug  info  for
            first-shared-library.

            Note  also  that this option is not mandatory for split debug information installed by your system’s
            package manager because then abidiff knows where to find it.

          • --debug-info-dir2 | --d2 <di-path2>

            Like --debug-info-dir1, this options tells abidiff where to find the split debug information for the
            second-shared-library file.

            This  option  can  be provided several times with different root directories.  In that case, abidiff
            will  potentially  look  into  all  those  root  directories  to  find  the  split  debug  info  for
            second-shared-library.

          • --headers-dir1 | --hd1 <headers-directory-path-1>

            Specifies  where  to find the public headers of the first shared library (or binary in general) that
            the tool has to consider.  The tool will thus filter out ABI changes on types that are  not  defined
            in public headers.

            Note  that several public header directories can be specified for the first shared library.  In that
            case the --headers-dir1 option should be present several times on the  command  line,  like  in  the
            following example:

                $ abidiff --headers-dir1 /some/path       \
                          --headers-dir1 /some/other/path \
                          binary-version-1 binary-version-2

          • --header-file1 | --hf1 <header-file-path-1>

            Specifies where to find one public header of the first shared library that the tool has to consider.
            The tool will thus filter out ABI changes on types that are not defined in public headers.

          • --headers-dir2 | --hd2 <headers-directory-path-2>

            Specifies where to find the public headers of the  second  shared  library  that  the  tool  has  to
            consider.   The  tool  will  thus  filter  out  ABI  changes on types that are not defined in public
            headers.

            Note that several public header directories can be specified for the second shared library.  In that
            case the --headers-dir2 option should be present several times like in the following example:

                $ abidiff --headers-dir2 /some/path       \
                          --headers-dir2 /some/other/path \
                          binary-version-1 binary-version-2

          • --header-file2 | --hf2 <header-file-path-2>

            Specifies  where  to  find  one  public  header  of  the  second shared library that the tool has to
            consider.  The tool will thus filter out ABI changes  on  types  that  are  not  defined  in  public
            headers.

          • --add-binaries1 <bin1,bin2,bin3,..>

            For each of the comma-separated binaries given in argument to this option, if the binary is found in
            the directory specified by the --added-binaries-dir1 option, then abidiff loads the  ABI  corpus  of
            the  binary  and  adds  it  to a set of corpora (called an ABI Corpus Group) that includes the first
            argument of abidiff.

            That ABI corpus group is then compared against the second corpus group given in argument to abidiff.

          • --add-binaries2 <bin1,bin2,bin3,..>

            For each of the comma-separated binaries given in argument to this option, if the binary is found in
            the  directory  specified  by the --added-binaries-dir2 option, then abidiff loads the ABI corpus of
            the binary and adds it to a set of corpora(called an ABI Corpus  Group)  that  includes  the  second
            argument of abidiff.

            That ABI corpus group is then compared against the first corpus group given in argument to abidiff.

          • --follow-dependencies | --fdeps

            For  each  dependency  of the first argument of abidiff, if it’s found in the directory specified by
            the --added-binaries-dir1 option, then construct an ABI corpus out of the dependency, add  it  to  a
            set of corpora (called an ABI Corpus Group) that includes the first argument of abidiff.

            Similarly,  for  each  dependency  of the second argument of abidiff, if it’s found in the directory
            specified by the --added-binaries-dir2 option, then construct an ABI corpus out of  the  dependency,
            add it to an ABI corpus group that includes the second argument of abidiff.

            These two ABI corpus groups are then compared against each other.

            Said  otherwise,  this makes abidiff compare the set of its first input and its dependencies against
            the set of its second input and its dependencies.

          • list-dependencies | --ldeps

            This option lists all the dependencies of the input arguments of  abidiff  that  are  found  in  the
            directories specified by the options --added-binaries-dir1 and --added-binaries-dir2--added-binaries-dir1 | --abd1 <added-binaries-directory-1>

            This  option  is  to  be  used  in  conjunction  with the --add-binaries1, --follow-dependencies and
            --list-dependencies options.  Binaries referred to by these  options,  if  found  in  the  directory
            added-binaries-directory-1,  are  loaded  as  ABI corpus and are added to the first ABI corpus group
            that is to be used in the comparison.

          • --added-binaries-dir2 | --abd2 <added-binaries-directory-2>

            This option is to be  used  in  conjunction  with  the  --add-binaries2,  --follow-dependencies  and
            --list-dependencies  options.   Binaries  referred  to  by  these options, if found in the directory
            added-binaries-directory-2, are loaded as ABI corpus and are added to the second ABI corpus group to
            be used in the comparison.

          • --no-linux-kernel-mode

            Without this option, if abidiff detects that the binaries it is looking at are Linux Kernel binaries
            (either vmlinux or modules) then it only considers functions and variables  which  ELF  symbols  are
            listed in the __ksymtab and __ksymtab_gpl sections.

            With  this  option,  abidiff  considers  the  binary as a non-special ELF binary.  It thus considers
            functions and variables which are defined and exported in the ELF sense.

          • --kmi-whitelist | -kaw <path-to-whitelist>

            When analyzing a Linux kernel binary, this option points to the white list of names of  ELF  symbols
            of functions and variables which ABI must be considered.  That white list is called a “Kernel Module
            Interface white list”.  This is because for the Kernel, we don’t talk  about  ABI;  we  rather  talk
            about the interface between the Kernel and its module. Hence the term KMI rather than ABI.

            Any  other  function  or  variable  which  ELF symbol are not present in that white list will not be
            considered by this tool.

            If this option is not provided – thus if no white list is provided – then the entire KMI,  that  is,
            the  set  of  all  publicly  defined and exported functions and global variables by the Linux Kernel
            binaries, is considered.

          • --drop-private-types

            This option is to be used with the --headers-dir1,  header-file1,  header-file2  and  --headers-dir2
            options.   With this option, types that are NOT defined in the headers are entirely dropped from the
            internal representation build by Libabigail to represent the  ABI.   They  thus  don’t  have  to  be
            filtered  out  from  the  final  ABI change report because they are not even present in Libabigail’s
            representation.

            Without this option however, those private types are kept in the internal representation  and  later
            filtered out from the report.

            This options thus potentially makes Libabigail consume less memory.  It’s meant to be mainly used to
            optimize the memory consumption of the tool on binaries with a lot of publicly defined and  exported
            types.

          • --exported-interfaces-only

            By  default,  when  looking  at  the debug information accompanying a binary, this tool analyzes the
            descriptions of the types reachable by the interfaces (functions and  variables)  that  are  visible
            outside of their translation unit.  Once that analysis is done, an ABI corpus is constructed by only
            considering the subset of types reachable from interfaces associated to ELF symbols that are defined
            and exported by the binary.  It’s those final ABI Corpora that are compared by this tool.

            The  problem  with  that approach however is that analyzing all the interfaces that are visible from
            outside their translation unit can amount to a lot of  data,  especially  when  those  binaries  are
            applications, as opposed to shared libraries.  One example of such applications is the Linux Kernel.
            Analyzing massive ABI corpora like these can be extremely slow.

            To mitigate that performance issue, this option allows libabigail to only  analyze  types  that  are
            reachable from interfaces associated with defined and exported ELF symbols.

            Note  that  this  option  is  turned on by default when analyzing the Linux Kernel.  Otherwise, it’s
            turned off by default.

          • --allow-non-exported-interfaces

            When looking at the debug information accompanying a binary, this tool analyzes the descriptions  of
            the  types  reachable  by the interfaces (functions and variables) that are visible outside of their
            translation unit.  Once that analysis is done, an ABI corpus is constructed by only considering  the
            subset of types reachable from interfaces associated to ELF symbols that are defined and exported by
            the binary.  It’s those final ABI Corpora that are compared by this tool.

            The problem with that approach however is that analyzing all the interfaces that  are  visible  from
            outside  their  translation  unit  can  amount  to a lot of data, especially when those binaries are
            applications, as opposed to shared libraries.  One example of such applications is the Linux Kernel.
            Analyzing massive ABI Corpora like these can be extremely slow.

            In  the  presence  of an “average sized” binary however one can afford having libabigail analyze all
            interfaces that are visible outside of their translation unit, using this option.

            Note that this option is turned on by default, unless we are in the presence of the Linux Kernel.

          • --stat

            Rather  than  displaying   the   detailed   ABI   differences   between   first-shared-library   and
            second-shared-library, just display some summary statistics about these differences.

          • --symtabs

            Only display the symbol tables of the first-shared-library and second-shared-library.

          • --deleted-fns

            In    the    resulting    report    about   the   differences   between   first-shared-library   and
            second-shared-library,  only  display  the  globally  defined  functions  that  got   deleted   from
            first-shared-library.

          • --changed-fns

            In    the    resulting    report    about   the   differences   between   first-shared-library   and
            second-shared-library, only display the changes in sub-types of  the  global  functions  defined  in
            first-shared-library.

          • --added-fns

            In    the    resulting    report    about   the   differences   between   first-shared-library   and
            second-shared-library,  only  display  the  globally  defined   functions   that   were   added   to
            second-shared-library.

          • --deleted-vars

            In    the    resulting    report    about   the   differences   between   first-shared-library   and
            second-shared-library,  only  display  the  globally  defined  variables  that  were  deleted   from
            first-shared-library.

          • --changed-vars

            In    the    resulting    report    about   the   differences   between   first-shared-library   and
            second-shared-library, only display the changes in the sub-types of the global variables defined  in
            first-shared-library--added-vars

            In    the    resulting    report    about   the   differences   between   first-shared-library   and
            second-shared-library,  only  display  the  global  variables   that   were   added   (defined)   to
            second-shared-library.

          • --non-reachable-types|-t

            Analyze  and  emit  change  reports  for  all  the types of the binary, including those that are not
            reachable from global functions and variables.

            This option might incur some serious performance degradation as the number of types analyzed can  be
            huge.   However,  if  paired  with  the  --headers-dir{1,2}  and/or  header-file{1,2}  options,  the
            additional non-reachable types analyzed are restricted to those defined  in  public  headers  files,
            thus hopefully making the performance hit acceptable.

            Also,  using  this  option  alongside  suppression  specifications (by also using the --suppressions
            option) might help keep the number of analyzed types (and the potential performance degradation)  in
            control.

            Note that without this option, only types that are reachable from global functions and variables are
            analyzed, so the tool detects and reports changes on these reachable types only.

          • --no-added-syms

            In   the   resulting   report   about   the    differences    between    first-shared-library    and
            second-shared-library,  do not display added functions or variables.  Do not display added functions
            or variables ELF symbols either.   All  other  kinds  of  changes  are  displayed  unless  they  are
            explicitely forbidden by other options on the command line.

          • --no-linkage-name

            In  the  resulting  report,  do  not  display  the  linkage  names of the added, removed, or changed
            functions or variables.

          • --no-show-locs
              Do not show information about where in the second shared library the respective type was changed.

          • --show-bytes

            Show sizes and offsets in bytes, not bits.  By default, sizes and offsets are shown in bits.

          • --show-bits

            Show sizes and offsets in bits, not bytes.  This option is activated by default.

          • --show-hex

            Show sizes and offsets in hexadecimal base.

          • --show-dec

            Show sizes and offsets in decimal base.  This option is activated by default.

          • --ignore-soname

            Ignore differences in the SONAME when doing a comparison

          • --no-show-relative-offset-changes

            Without this option, when the offset of a data member changes, the change report not  only  mentions
            the  older  and  newer  offset, but it also mentions by how many bits the data member changes.  With
            this option, the latter is not shown.

          • --no-unreferenced-symbols

            In the resulting report, do not display change information about function and variable symbols  that
            are  not  referenced  by  any  debug information.  Note that for these symbols not referenced by any
            debug information, the change information displayed is either added or removed symbols.

          • --no-default-suppression

            Do not load the default suppression specification files.

          • --suppressions | --suppr <path-to-suppressions>

            Use a suppression specification file located at path-to-suppressions.  Note  that  this  option  can
            appear  multiple  times  on  the  command  line.   In  that  case,  all  of the provided suppression
            specification files are taken into account.

            Please note that, by default,  if  this  option  is  not  provided,  then  the  default  suppression
            specification files are loaded .

          • --drop <regex>

            When  reading  the first-shared-library and second-shared-library ELF input files, drop the globally
            defined functions and variables which name match the regular expression  regex.   As  a  result,  no
            change involving these functions or variables will be emitted in the diff report.

          • --drop-fn <regex>

            When  reading  the first-shared-library and second-shared-library ELF input files, drop the globally
            defined functions which name match the regular expression regex.  As a result, no  change  involving
            these functions will be emitted in the diff report.

          • --drop-var <regex>

            When  reading  the first-shared-library and second-shared-library ELF input files, drop the globally
            defined variables matching a the regular expression regex.

          • --keep <regex>

            When reading the first-shared-library and second-shared-library ELF input files, keep  the  globally
            defined functions and variables which names match the regular expression regex.  All other functions
            and variables are dropped on the floor and will thus not appear in the resulting diff report.

          • --keep-fn <regex>

            When reading the first-shared-library and second-shared-library ELF input files, keep  the  globally
            defined functions which name match the regular expression regex.  All other functions are dropped on
            the floor and will thus not appear in the resulting diff report.

          • --keep-var <regex>

            When reading the first-shared-library and second-shared-library ELF input files, keep  the  globally
            defined  which  names  match  the  regular expression regex.  All other variables are dropped on the
            floor and will thus not appear in the resulting diff report.

          • --harmless

            In the diff report, display only the  harmless  changes.   By  default,  the  harmless  changes  are
            filtered out of the diff report keep the clutter to a minimum and have a greater chance to spot real
            ABI issues.

          • --no-harmful

            In the diff report, do not display the harmful changes.  By default, only the  harmful  changes  are
            displayed in diff report.

          • --redundant

            In  the  diff  report,  do  display redundant changes.  A redundant change is a change that has been
            displayed elsewhere in the report.

          • --no-redundant

            In the diff report, do NOT display redundant changes.  A redundant change is a change that has  been
            displayed elsewhere in the report.  This option is switched on by default.

          • --no-architecture

            Do not take architecture in account when comparing ABIs.

          • --no-corpus-path

            Do not emit the path attribute for the ABI corpus.

          • --fail-no-debug-info

            If  no  debug  info  was found, then this option makes the program to fail.  Otherwise, without this
            option, the program will attempt to compare properties of the binaries that are not related to debug
            info, like pure ELF properties.

          • --leaf-changes-only|-l  only  show  leaf changes, so don’t show impact analysis report.  This option
            implies --redundant.

            The typical output of abidiff when comparing two binaries looks like this

                $ abidiff libtest-v0.so libtest-v1.so
                Functions changes summary: 0 Removed, 1 Changed, 0 Added function
                Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

                1 function with some indirect sub-type change:

                  [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
                    parameter 1 of type 'C&' has sub-type changes:
                      in referenced type 'struct C' at test-v1.cc:7:1:
                        type size hasn't changed
                        1 data member change:
                         type of 'leaf* C::m0' changed:
                           in pointed to type 'struct leaf' at test-v1.cc:1:1:
                             type size changed from 32 to 64 bits
                             1 data member insertion:
                               'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1

                $

            So in that example the report emits information about  how  the  data  member  insertion  change  of
            “struct  leaf”  is reachable from function “void fn(C&)”.  In other words, the report not only shows
            the data member change on “struct leaf”, but it also shows the impact of that change on the function
            “void fn(C&)”.

            In   abidiff   parlance,   the   change   on  “struct  leaf”  is  called  a  leaf  change.   So  the
            --leaf-changes-only --impacted-interfaces options show, well, only the leaf  change.   And  it  goes
            like this:

                $ abidiff -l libtest-v0.so libtest-v1.so
                'struct leaf' changed:
                  type size changed from 32 to 64 bits
                  1 data member insertion:
                    'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1

                  one impacted interface:
                    function void fn(C&)
                $

            Note how the report ends by showing the list of interfaces impacted by the leaf change.

            Now  if  you  don’t  want to see that list of impacted interfaces, then you can just avoid using the
            --impacted-interface option.  You can learn about that option below, in any case.

          • --impacted-interfaces

            When showing leaf changes, this option instructs abidiff to show the list  of  impacted  interfaces.
            This option is thus to be used in addition the --leaf-changes-only option, otherwise, it’s ignored.

          • --dump-diff-tree
              After the diff report, emit a textual representation of the diff nodes tree used by the comparison
              engine to represent the changed functions and variables.  That representation is  emitted  to  the
              error  output  for debugging purposes.  Note that this diff tree is relevant only to functions and
              variables that have some sub-type changes.  Added or removed functions and variables do  not  have
              any diff nodes tree associated to them.

          • --no-assume-odr-for-cplusplus

            When  analysing a binary originating from C++ code using DWARF debug information, libabigail assumes
            the One Definition Rule to speed-up the analysis.  In that case, when several types  have  the  same
            name in the binary, they are assumed to all be equal.

            This option disables that assumption and instructs libabigail to actually actually compare the types
            to determine if they are equal.

          • --no-leverage-dwarf-factorization

            When analysing a binary which DWARF debug information was processed with  the  DWZ  tool,  the  type
            information  is  supposed  to  be already factorized.  That context is used by libabigail to perform
            some speed optimizations.

            This option disables those optimizations.

          • --no-change-categorization | -x

            This option disables the categorization of changes into harmless and  harmful  changes.   Note  that
            this  categorization  is  a  pre-requisite for the filtering of changes so this option disables that
            filtering.  The goal of this option is to speed-up the execution of the program for cases where  the
            graph  of  changes  is  huge and where the user is just interested in looking at, for instance, leaf
            node changes without caring about their possible impact on interfaces.  In that  case,  this  option
            would be used along with the --leaf-changes-only one.

          • --ctf

            When comparing binaries, extract ABI information from CTF debug information, if present.

          • --btf

            When comparing binaries, extract ABI information from BTF debug information, if present.

          • --stats

            Emit statistics about various internal things.

          • --verbose

            Emit verbose logs about the progress of miscellaneous internal things.

   Return values
       The  exit code of the abidiff command is either 0 if the ABI of the binaries being compared are equal, or
       non-zero if they differ or if the tool encountered an error.

       In the later case, the exit code is a 8-bits-wide bit field in which each bit has a specific meaning.

       The first bit, of value 1, named ABIDIFF_ERROR means there was an error.

       The second bit, of value 2, named ABIDIFF_USAGE_ERROR means there was  an  error  in  the  way  the  user
       invoked  the  tool.   It might be set, for instance, if the user invoked the tool with an unknown command
       line switch, with a wrong number or argument, etc.  If this bit is set, then the ABIDIFF_ERROR  bit  must
       be set as well.

       The  third  bit,  of  value  4, named ABIDIFF_ABI_CHANGE means the ABI of the binaries being compared are
       different.

       The fourth bit, of value 8, named ABIDIFF_ABI_INCOMPATIBLE_CHANGE means the ABI of the binaries  compared
       are different in an incompatible way.  If this bit is set, then the ABIDIFF_ABI_CHANGE bit must be set as
       well.  If the ABIDIFF_ABI_CHANGE is set and the ABIDIFF_INCOMPATIBLE_CHANGE is NOT  set,  then  it  means
       that  the  ABIs  being  compared  might or might not be compatible.  In that case, a human being needs to
       review the ABI changes to decide if they are compatible or not.

       Note that, at the moment, there are only a few kinds of ABI changes that would result in setting the flag
       ABIDIFF_ABI_INCOMPATIBLE_CHANGE.  Those ABI changes are either:

          • the removal of the symbol of a function or variable that has been defined and exported.

          • the  modification  of  the  index  of  a  member  of  a virtual function table (for C++ programs and
            libraries).

       With time, when more ABI change patterns are found to always constitute incompatible ABI changes, we will
       adapt  the code to recognize those cases and set the ABIDIFF_ABI_INCOMPATIBLE_CHANGE accordingly.  So, if
       you find such patterns, please let us know.

       The remaining bits are not used for the moment.

   Usage examples
          1. Detecting a change in a sub-type of a function:

                 $ cat -n test-v0.cc
                          1      // Compile this with:
                          2      //   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
                          3
                          4      struct S0
                          5      {
                          6        int m0;
                          7      };
                          8
                          9      void
                         10      foo(S0* /*parameter_name*/)
                         11      {
                         12        // do something with parameter_name.
                         13      }
                 $
                 $ cat -n test-v1.cc
                          1      // Compile this with:
                          2      //   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
                          3
                          4      struct type_base
                          5      {
                          6        int inserted;
                          7      };
                          8
                          9      struct S0 : public type_base
                         10      {
                         11        int m0;
                         12      };
                         13
                         14      void
                         15      foo(S0* /*parameter_name*/)
                         16      {
                         17        // do something with parameter_name.
                         18      }
                 $
                 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
                 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
                 $
                 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
                 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
                 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

                 1 function with some indirect sub-type change:

                   [C]'function void foo(S0*)' has some indirect sub-type changes:
                         parameter 0 of type 'S0*' has sub-type changes:
                           in pointed to type 'struct S0':
                             size changed from 32 to 64 bits
                             1 base class insertion:
                               struct type_base
                             1 data member change:
                              'int S0::m0' offset changed from 0 to 32
                 $

          2. Detecting another change in a sub-type of a function:

                 $ cat -n test-v0.cc
                          1      // Compile this with:
                          2      //   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
                          3
                          4      struct S0
                          5      {
                          6        int m0;
                          7      };
                          8
                          9      void
                         10      foo(S0& /*parameter_name*/)
                         11      {
                         12        // do something with parameter_name.
                         13      }
                 $
                 $ cat -n test-v1.cc
                          1      // Compile this with:
                          2      //   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
                          3
                          4      struct S0
                          5      {
                          6        char inserted_member;
                          7        int m0;
                          8      };
                          9
                         10      void
                         11      foo(S0& /*parameter_name*/)
                         12      {
                         13        // do something with parameter_name.
                         14      }
                 $
                 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
                 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
                 $
                 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
                 Functions changes summary: 0 Removed, 1 Changed, 0 Added function
                 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

                 1 function with some indirect sub-type change:

                   [C]'function void foo(S0&)' has some indirect sub-type changes:
                         parameter 0 of type 'S0&' has sub-type changes:
                           in referenced type 'struct S0':
                             size changed from 32 to 64 bits
                             1 data member insertion:
                               'char S0::inserted_member', at offset 0 (in bits)
                             1 data member change:
                              'int S0::m0' offset changed from 0 to 32

                 $

          3. Detecting that functions got removed or added to a library:

                 $ cat -n test-v0.cc
                          1      // Compile this with:
                          2      //   g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
                          3
                          4      struct S0
                          5      {
                          6        int m0;
                          7      };
                          8
                          9      void
                         10      foo(S0& /*parameter_name*/)
                         11      {
                         12        // do something with parameter_name.
                         13      }
                 $
                 $ cat -n test-v1.cc
                          1      // Compile this with:
                          2      //   g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
                          3
                          4      struct S0
                          5      {
                          6        char inserted_member;
                          7        int m0;
                          8      };
                          9
                         10      void
                         11      bar(S0& /*parameter_name*/)
                         12      {
                         13        // do something with parameter_name.
                         14      }
                 $
                 $ g++ -g -Wall -shared -o libtest-v0.so test-v0.cc
                 $ g++ -g -Wall -shared -o libtest-v1.so test-v1.cc
                 $
                 $ ../build/tools/abidiff libtest-v0.so libtest-v1.so
                 Functions changes summary: 1 Removed, 0 Changed, 1 Added functions
                 Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

                 1 Removed function:
                   'function void foo(S0&)'    {_Z3fooR2S0}

                 1 Added function:
                   'function void bar(S0&)'    {_Z3barR2S0}

                 $

          4. Comparing two sets of binaries that are passed on the command line:

                 $ abidiff --add-binaries1=file2-v1              \
                           --add-binaries2=file2-v2,file2-v1     \
                           --added-binaries-dir1 dir1            \
                           --added-binaries-dir2 dir2            \
                           file1-v1 file1-v2

             Note that the files file2-v1, and file2-v2 are to be found in dir1  and  dir2  or  in  the  current
             directory.

          5. Compare two libraries and their dependencies:

                 $ abidiff --follow-dependencies                      \
                           --added-binaries-dir1 /some/where          \
                           --added-binaries-dir2 /some/where/else     \
                           foo bar

             This compares the set of binaries comprised by foo and its dependencies against the set of binaries
             comprised by bar and its dependencies.

   abipkgdiff
       abipkgdiff compares the Application Binary Interfaces (ABI) of the ELF binaries contained in two software
       packages.  The software package formats currently supported are Deb, RPM, tar archives (either compressed
       or not) and plain directories that contain binaries.

       For a comprehensive ABI change report that includes changes about function and  variable  sub-types,  the
       two  input  packages  must  be  accompanied  with  their  debug  information  packages that contain debug
       information either in DWARF, CTF or in BTF formats.  Please  note  however  that  some  packages  contain
       binaries  that  embed  the  debug  information  directly  in a section of said binaries.  In those cases,
       obviously, no separate debug information package is needed as the tool will find  the  debug  information
       inside the binaries.

       By default, abipkgdiff uses debug information in DWARF format, if present, otherwise it compares binaries
       interfaces using debug information in CTF or in BTF formats, if present. Finally, if  no  debug  info  in
       these formats is found, it only considers ELF symbols and report about their addition or removal.

       This  tool uses the libabigail library to analyze the binary as well as its associated debug information.
       Here is its general mode of operation.

       When instructed to do so, a binary and its associated debug information is read and  analyzed.   To  that
       effect,  libabigail  analyzes  by  default  the  descriptions  of  the  types reachable by the interfaces
       (functions and variables) that are visible outside of their translation  unit.   Once  that  analysis  is
       done,  an  Application  Binary  Interface  Corpus  is constructed by only considering the subset of types
       reachable from interfaces associated to ELF symbols that are defined and exported by  the  binary.   It’s
       that final ABI corpus which libabigail considers as representing the ABI of the analyzed binary.

       Libabigail  then  has  capabilities  to  generate  textual  representations of ABI Corpora, compare them,
       analyze their changes and report about them.

   Invocation
          abipkgdiff [option] <package1> <package2>

       package1 and package2 are the packages that contain the binaries to be compared.

   Environment
       abipkgdiff loads two default suppression specifications files, merges their content and use it to  filter
       out ABI change reports that might be considered as false positives to users.

       • Default system-wide suppression specification file

         It’s  located by the optional environment variable LIBABIGAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE.  If that
         environment  variable  is  not  set,   then   abipkgdiff   tries   to   load   the   suppression   file
         $libdir/libabigail/libabigail-default.abignore.    If  that  file  is  not  present,  then  no  default
         system-wide suppression specification file is loaded.

       • Default user suppression specification file.

         It’s located by the optional environment LIBABIGAIL_DEFAULT_USER_SUPPRESSION_FILE.  If that environment
         variable  is not set, then abipkgdiff tries to load the suppression file $HOME/.abignore.  If that file
         is not present, then no default user suppression specification is loaded.

       In addition to those default suppression specification  files,  abipkgdiff  will  also  look  inside  the
       packages  being  compared  and  if  it  sees  a file that ends with the extension .abignore, then it will
       consider it  as  a  suppression  specification  and  it  will  combine  it  to  the  default  suppression
       specification that might be already loaded.

       The  user  might  as  well  use the --suppressions option (that is documented further below) to provide a
       suppression specification.

   Options--help | -h

            Display a short help about the command and exit.

          • –version | -v

            Display the version of the program and exit.

          • --debug-info-pkg1 | --d1 <path>

            For cases where the debug information for  package1  is  split  out  into  a  separate  file,  tells
            abipkgdiff where to find that separate debug information package.

            Note  that  the  debug  info  for  package1  can  have  been split into several different debug info
            packages.  In that case, several instances of this options can be provided, along with those several
            different debug info packages.

          • --debug-info-pkg2 | --d2 <path>

            For  cases  where  the  debug  information  for  package2  is  split out into a separate file, tells
            abipkgdiff where to find that separate debug information package.

            Note that the debug info for package2  can  have  been  split  into  several  different  debug  info
            packages.  In that case, several instances of this options can be provided, along with those several
            different debug info packages.

          • --devel-pkg1 | --devel1 <path>

            Specifies where to find the Development Package associated with the first package  to  be  compared.
            That  Development Package at path should at least contain header files in which public types exposed
            by the libraries (of the first package to be compared) are defined.  When this option  is  provided,
            the tool filters out reports about ABI changes to types that are NOT defined in these header files.

          • --devel-pkg2 | --devel2 <path>

            Specifies  where  to find the Development Package associated with the second package to be compared.
            That Development Package at path should at least contains header files in which public types exposed
            by  the libraries (of the second package to be compared) are defined.  When this option is provided,
            the tool filters out reports about ABI changes to types that are NOT defined in these header files.

          • --drop-private-types

            This option is to be used with the --devel-pkg1 and --devel-pkg2 options.  With this  option,  types
            that  are  NOT defined in the headers are entirely dropped from the internal representation build by
            Libabigail to represent the ABI.  They thus don’t have to be filtered out from the final ABI  change
            report because they are not even present in Libabigail’s representation.

            Without  this  option however, those private types are kept in the internal representation and later
            filtered out from the report.

            This options thus potentially makes Libabigail consume less memory.  It’s meant to be mainly used to
            optimize  the memory consumption of the tool on binaries with a lot of publicly defined and exported
            types.

          • --dso-only

            Compare ELF files that are shared libraries, only.  Do not compare executable files, for instance.

          • --private-dso

            By default, abipkgdiff does not compare DSOs that are private to the RPM package.  A private DSO  is
            a DSO which SONAME is NOT advertised in the “provides” property of the RPM.

            This  option  instructs  abipkgdiff  to  also compare DSOs that are NOT advertised in the “provides”
            property of the RPM.

            Please note that the fact that (by default) abipkgdiff skips  private  DSO  is  a  feature  that  is
            available  only  for  RPMs,  at the moment.  We would happily accept patches adding that feature for
            other package formats.

          • --leaf-changes-only|-l only show leaf changes, so don’t show impact analysis  report.   This  option
            implies --redundant

            The  typical  output  of abipkgdiff and abidiff when comparing two binaries, that we shall call full
            impact report, looks like this

                $ abidiff libtest-v0.so libtest-v1.so
                Functions changes summary: 0 Removed, 1 Changed, 0 Added function
                Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

                1 function with some indirect sub-type change:

                  [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
                    parameter 1 of type 'C&' has sub-type changes:
                      in referenced type 'struct C' at test-v1.cc:7:1:
                        type size hasn't changed
                        1 data member change:
                         type of 'leaf* C::m0' changed:
                           in pointed to type 'struct leaf' at test-v1.cc:1:1:
                             type size changed from 32 to 64 bits
                             1 data member insertion:
                               'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1

                $

            So in that example the report emits information about  how  the  data  member  insertion  change  of
            “struct  leaf”  is reachable from function “void fn(C&)”.  In other words, the report not only shows
            the data member change on “struct leaf”, but it also shows the impact of that change on the function
            “void fn(C&)”.

            In  abidiff  (and abipkgdiff) parlance, the change on “struct leaf” is called a leaf change.  So the
            --leaf-changes-only --impacted-interfaces options show, well, only the leaf  change.   And  it  goes
            like this:

                $ abidiff -l libtest-v0.so libtest-v1.so
                'struct leaf' changed:
                  type size changed from 32 to 64 bits
                  1 data member insertion:
                    'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1

                  one impacted interface:
                    function void fn(C&)
                $

            Note  how  the report ends up by showing the list of interfaces impacted by the leaf change.  That’s
            the effect of the additional --impacted-interfaces option.

            Now if you don’t want to see that list of impacted interfaces, then you can  just  avoid  using  the
            --impacted-interface option.  You can learn about that option below, in any case.

            Please  note  that  when  comparing two Linux Kernel packages, it’s this leaf changes report that is
            emitted, by default.  The normal so-called full  impact  report  can  be  emitted  with  the  option
            --full-impact which is documented later below.

          • --impacted-interfaces

            When showing leaf changes, this option instructs abipkgdiff to show the list of impacted interfaces.
            This option is thus to be used in addition to the --leaf-changes-only option, or, when comparing two
            Linux Kernel packages.  Otherwise, it’s simply ignored.

          • --full-impact|-f

            When  comparing  two Linux Kernel packages, this function instructs abipkgdiff to emit the so-called
            full impact report, which is the default report kind emitted by the abidiff tool:

                $ abidiff libtest-v0.so libtest-v1.so
                Functions changes summary: 0 Removed, 1 Changed, 0 Added function
                Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

                1 function with some indirect sub-type change:

                  [C]'function void fn(C&)' at test-v1.cc:13:1 has some indirect sub-type changes:
                    parameter 1 of type 'C&' has sub-type changes:
                      in referenced type 'struct C' at test-v1.cc:7:1:
                        type size hasn't changed
                        1 data member change:
                         type of 'leaf* C::m0' changed:
                           in pointed to type 'struct leaf' at test-v1.cc:1:1:
                             type size changed from 32 to 64 bits
                             1 data member insertion:
                               'char leaf::m1', at offset 32 (in bits) at test-v1.cc:4:1

                $

          • --non-reachable-types|-t

            Analyze and emit change reports for all the types of  the  binary,  including  those  that  are  not
            reachable from global functions and variables.

            This  option might incur some serious performance degradation as the number of types analyzed can be
            huge.  However, if paired with the --devel-pkg{1,2}  options,  the  additional  non-reachable  types
            analyzed  are  restricted  to  those  defined  in the public headers files carried by the referenced
            development packages, thus hopefully making the performance hit acceptable.

            Also, using this option alongside suppression  specifications  (by  also  using  the  --suppressions
            option)  might help keep the number of analyzed types (and the potential performance degradation) in
            control.

            Note that without this option, only types that are reachable from global functions and variables are
            analyzed, so the tool detects and reports changes on these reachable types only.

          • --exported-interfaces-only

            By  default,  when  looking  at  the debug information accompanying a binary, this tool analyzes the
            descriptions of the types reachable by the interfaces (functions and  variables)  that  are  visible
            outside of their translation unit.  Once that analysis is done, an ABI corpus is constructed by only
            considering the subset of types reachable from interfaces associated to ELF symbols that are defined
            and exported by the binary.  It’s those final ABI Corpora that are compared by this tool.

            The  problem  with  that approach however is that analyzing all the interfaces that are visible from
            outside their translation unit can amount to a lot of  data,  especially  when  those  binaries  are
            applications, as opposed to shared libraries.  One example of such applications is the Linux Kernel.
            Analyzing massive ABI corpora like these can be extremely slow.

            To mitigate that performance issue, this option allows libabigail to only  analyze  types  that  are
            reachable from interfaces associated with defined and exported ELF symbols.

            Note  that  this  option  is  turned on by default when analyzing the Linux Kernel.  Otherwise, it’s
            turned off by default.

          • --allow-non-exported-interfaces

            When looking at the debug information accompanying a binary, this tool analyzes the descriptions  of
            the  types  reachable  by the interfaces (functions and variables) that are visible outside of their
            translation unit.  Once that analysis is done, an ABI corpus is constructed by only considering  the
            subset of types reachable from interfaces associated to ELF symbols that are defined and exported by
            the binary.  It’s those final ABI Corpora that are compared by this tool.

            The problem with that approach however is that analyzing all the interfaces that  are  visible  from
            outside  their  translation  unit  can  amount  to a lot of data, especially when those binaries are
            applications, as opposed to shared libraries.  One example of such applications is the Linux Kernel.
            Analyzing massive ABI Corpora like these can be extremely slow.

            In  the  presence  of an “average sized” binary however one can afford having libabigail analyze all
            interfaces that are visible outside of their translation unit, using this option.

            Note that this option is turned on by default, unless we are in the presence of the Linux Kernel.

          • --redundant
              In the diff reports, do display redundant changes.  A redundant change is a change that  has  been
              displayed elsewhere in a given report.

          • --harmless

            In  the  diff  report,  display  only  the  harmless  changes.  By default, the harmless changes are
            filtered out of the diff report keep the clutter to a minimum and have a greater chance to spot real
            ABI issues.

          • --no-linkage-name

            In  the  resulting  report,  do  not  display  the  linkage  names of the added, removed, or changed
            functions or variables.

          • --no-added-syms

            Do not show the list of functions, variables, or any symbol that was added.

          • --no-added-binaries

            Do not show the list of binaries that got added to the second package.

            Please note that the presence of such added binaries is not considered like an ABI  change  by  this
            tool;  as  such,  it  doesn’t  have  any  impact on the exit code of the tool.  It does only have an
            informational value.  Removed binaries are, however, considered as an ABI change.

          • --no-abignore

            Do not search the package for the presence of suppression files.

          • --no-parallel

            By default, abipkgdiff will use all the processors it has available to execute  concurrently.   This
            option tells it not to extract packages or run comparisons in parallel.

          • --no-default-suppression

            Do not load the default suppression specification files.

          • --suppressions | --suppr <path-to-suppressions>

            Use  a  suppression  specification  file located at path-to-suppressions.  Note that this option can
            appear multiple times on the command line.  In that case, all of the suppression specification files
            are taken into account.

            Please  note  that,  by  default,  if  this  option  is  not  provided, then the default suppression
            specification files are loaded .

          • --linux-kernel-abi-whitelist | -w <path-to-whitelist>

            When comparing two Linux kernel RPM packages, this option points to the white list of names  of  ELF
            symbols of functions and variables that must be compared for ABI changes.  That white list is called
            a “Linux kernel ABI white list”.

            Any other function or variable which ELF symbol are not present in  that  white  list  will  not  be
            considered by the ABI comparison process.

            If  this  option  is not provided – thus if no white list is provided – then the ABI of all publicly
            defined and exported functions and global variables by the Linux Kernel binaries are compared.

            Please note that if a white list package is given in parameter, this option handles  it  just  fine,
            like if the –wp option was used.

          • --wp <path-to-whitelist-package>

            When comparing two Linux kernel RPM packages, this option points an RPM package containining several
            white lists of names of ELF symbols of functions  and  variables  that  must  be  compared  for  ABI
            changes.  Those white lists are called “Linux kernel ABI white lists”.

            From  the content of that white list package, this program then chooses the appropriate Linux kernel
            ABI white list to consider when comparing the ABI of Linux kernel binaries contained  in  the  Linux
            kernel packages provided on the command line.

            That  choosen Linux kernel ABI white list contains the list of names of ELF symbols of functions and
            variables that must be compared for ABI changes.

            Any other function or variable which ELF symbol are not present in  that  white  list  will  not  be
            considered by the ABI comparison process.

            Note  that this option can be provided twice (not mor than twice), specifying one white list package
            for each Linux Kernel package that is provided on the command line.

            If this option is not provided – thus if no white list is provided – then the ABI  of  all  publicly
            defined and exported functions and global variables by the Linux Kernel binaries are compared.

          • --no-unreferenced-symbols

            In  the resulting report, do not display change information about function and variable symbols that
            are not referenced by any debug information.  Note that for these  symbols  not  referenced  by  any
            debug information, the change information displayed is either added or removed symbols.

          • --no-show-locs
              Do not show information about where in the second shared library the respective type was changed.

          • --show-bytes

            Show sizes and offsets in bytes, not bits.  By default, sizes and offsets are shown in bits.

          • --show-bits

            Show sizes and offsets in bits, not bytes.  This option is activated by default.

          • --show-hex

            Show sizes and offsets in hexadecimal base.

          • --show-dec

            Show sizes and offsets in decimal base.  This option is activated by default.

          • --no-show-relative-offset-changes

            Without  this  option, when the offset of a data member changes, the change report not only mentions
            the older and newer offset, but it also mentions by how many bits the  data  member  changes.   With
            this option, the latter is not shown.

          • --show-identical-binaries
              Show  the  names of the all binaries compared, including the binaries whose ABI compare equal.  By
              default, when this option is not provided, only binaries with ABI changes are  mentionned  in  the
              output.

          • --fail-no-dbg

            Make  the program fail and return a non-zero exit code if couldn’t read any of the debug information
            that comes from the debug info packages that were given on the  command  line.   If  no  debug  info
            package were provided on the command line then this option is not active.

            Note  that the non-zero exit code returned by the program as a result of this option is the constant
            ABIDIFF_ERROR.  To know the numerical value  of  that  constant,  please  refer  to  the  exit  code
            documentation.

          • --keep-tmp-files

            Do not erase the temporary directory files that are created during the execution of the tool.

          • --verbose

            Emit verbose progress messages.

          • --self-check

            This  is  used to test the underlying Libabigail library.  When in used, the command expects only on
            input package, along with its associated debug info packages.  The command then compares each binary
            inside  the package against its own ABIXML representation. The result of the comparison should yield
            the empty set if Libabigail behaves correctly.  Otherwise, it means there is an issue that ought  to
            be fixed.  This option is used by people interested in Libabigail development for regression testing
            purposes.  Here is an example of the use of this option:

                $ abipkgdiff --self-check --d1 mesa-libGLU-debuginfo-9.0.1-3.fc33.x86_64.rpm  mesa-libGLU-9.0.1-3.fc33.x86_64.rpm
                 ==== SELF CHECK SUCCEEDED for 'libGLU.so.1.3.1' ====
                $

          • --no-assume-odr-for-cplusplus

            When analysing a binary originating from C++ code using DWARF debug information, libabigail  assumes
            the  One  Definition  Rule to speed-up the analysis.  In that case, when several types have the same
            name in the binary, they are assumed to all be equal.

            This option disables that assumption and instructs libabigail to actually actually compare the types
            to determine if they are equal.

          • --no-leverage-dwarf-factorization

            When  analysing  a  binary  which  DWARF debug information was processed with the DWZ tool, the type
            information is supposed to be already factorized.  That context is used  by  libabigail  to  perform
            some speed optimizations.

            This option disables those optimizations.

          • --ctf
                This is used to compare packages with CTF debug information, if present.

          • --btf
                This is used to compare packages with BTF debug information, if present.

   Return value
       The  exit  code  of  the abipkgdiff command is either 0 if the ABI of the binaries compared are equal, or
       non-zero if they differ or if the tool encountered an error.

       In the later case, the value of the exit code is the same as for the abidiff tool.

   kmidiff
       kmidiff compares the binary Kernel Module Interfaces of two Linux Kernel trees.  The binary  KMI  is  the
       interface  that  the  Linux  Kernel  exposes to its modules.  The trees we are interested in here are the
       result of the build of the Linux Kernel source tree.

   General approach
       And example of how to build your kernel if you want to compare it to another one using kmidiff is:

          git clone -b v4.5 git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git linux/v4.5
          cd linux/v4.5
          make allyesconfig all

       Then install the modules into a directory, for instance, the  build/modules  sub-directory  of  the  your
       kernel source tree:

          mkdir build/modules
          make modules_install INSTALL_MOD_DIR=build/modules

       Then construct a list of interfaces exported by the kernel, that you want to compare:

          cat > kmi-whitelist << EOF
          [kernel_4.5_kmi_whitelist]
           init_task
           schedule
           dev_queue_xmit
           __kmalloc
           printk
          EOF

       Suppose  you’ve  done  something  similar for the v4.6 branch of the Linux kernel, you now have these two
       directories:  linux/v4.5  and  linux/v4.6.    Their   modules   are   present   under   the   directories
       linux/v4.5/build/modules and linux/v4.6/build/modules.

       To  Comparing  their  KMI  kmidiff  needs to know where to find the vmlinux binaries and their associated
       modules.  Here would be what the command line looks like:

          kmidiff                                     \
            --kmi-whitelist  linux/v4.6/kmi-whitelist \
            --vmlinux1       linux/v4.5/vmlinux       \
            --vmlinux2       linux/v4.6/vmlinux       \
                             linux/v4.5/build/modules \
                             linux/v4.6/build/modules

       This tool uses the libabigail library to analyze the binary as well as its associated debug  information.
       Here is its general mode of operation.

       When  instructed  to  do so, a binary and its associated debug information is read and analyzed.  To that
       effect, libabigail analyzes by default  the  descriptions  of  the  types  reachable  by  the  interfaces
       (functions  and  variables)  that  are  visible outside of their translation unit.  Once that analysis is
       done, an Application Binary Interface Corpus is constructed by  only  considering  the  subset  of  types
       reachable  from  interfaces  associated to ELF symbols that are defined and exported by the binary.  It’s
       that final ABI corpus which libabigail considers as representing the ABI of the analyzed binary.

       Libabigail then has capabilities to generate  textual  representations  of  ABI  Corpora,  compare  them,
       analyze their changes and report about them.

   Invocation
       More generally, kmidiff is invoked under the form:

          kmidiff [options] <first-modules-dir> <second-modules-dir>

   Environment
       By default, kmidiff compares all the interfaces (exported functions and variables) between the Kernel and
       its modules.  In practice, though, some users might want to compare a subset of the those interfaces.

       By default, kmidiff uses debug information in the DWARF debug  info  format,  if  present,  otherwise  it
       compares  interfaces using CTF or BTF debug info formats, if present.  Finally, if no debug info in these
       formats is found, it only considers ELF symbols and report about their addition or removal.

       Users can then define a “white list” of the interfaces to compare.  Such a white list is a just a file in
       the “INI” format that looks like:

          [kernel_version_x86_64_whitelist]
            function1_name
            function2_name
            global_variable1_name
            ....

       Note  that  the name of the section (the name that is between the two brackets) of that INI file just has
       to  end  with  the  string  “whitelist”.   So  you  can  define  the  name   you   want,   for   instance
       [kernel_46_x86_64_whitelist].

       Then  each  line  of  that  whitelist  file  is the name of an exported function or variable.  Only those
       interfaces along with the types reachable from their signatures are  going  to  be  compared  by  kmidiff
       recursively.

       Note that by default kmidiff analyzes the types reachable from the interfaces associated with ELF symbols
       that are defined and exported by the Linux Kernel as being the union of the vmlinux binary  and  all  its
       compiled modules.  It then compares those interfaces (along with their types).

   Options--help | -h

            Display a short help about the command and exit.

          • --version | -v

            Display the version of the program and exit.

          • --verbose

            Display some verbose messages while executing.

          • --debug-info-dir1 | --d1 <di-path1>

            For  cases  where the debug information for the binaries of the first Linux kernel is split out into
            separate files, tells kmidiff where to find those separate debug information files.

            Note that di-path must point to the root directory under which the debug information is arranged  in
            a tree-like manner.  Under Red Hat based systems, that directory is usually <root>/usr/lib/debug.

          • --debug-info-dir2 | --d2 <di-path2>

            Like --debug-info-dir1, this options tells kmidiff where to find the split debug information for the
            binaries of the second Linux kernel.

          • --vmlinux1 | --l1 <path-to-first-vmlinux>

            Sets the path to the first vmlinux binary to consider.  This has  to  be  the  uncompressed  vmlinux
            binary compiled with debug info.

          • --vmlinux2 | --l2 <path-to-first-vmlinux>

            Sets  the  path  to  the second vmlinux binary to consider.  This has to be the uncompressed vmlinux
            binary compiled with debug info.

          • --kmi-whitelist | -w <path-to-interface-whitelist>

            Set the path to the white list of interfaces to compare while comparing the Kernel Module  Interface
            of the first kernel against the one of the second kernel.

            If  this  option is not provided, all the exported interfaces of the two kernels are compared.  That
            takes a lot of times and is not necessarily meaningful because many interface are probably meant  to
            see their reachable types change.

            So please, make sure you always use this option unless you really know what you  are doing.

          • --suppressions | --suppr <path-to-suppressions>

            Use  a  suppression  specification  file located at path-to-suppressions.  Note that this option can
            appear multiple times on  the  command  line.   In  that  case,  all  of  the  provided  suppression
            specification files are taken into account.

            Please  note  that,  by  default,  if  this  option  is  not  provided, then the default suppression
            specification files are loaded .

          • --no-change-categorization | -x

            This option disables the categorization of changes into harmless and  harmful  changes.   Note  that
            this  categorization  is  a  pre-requisite for the filtering of changes so this option disables that
            filtering.  The goal of this option is to speed-up the execution of the program for cases where  the
            graph  of  changes  is  huge and where the user is just interested in looking at, for instance, leaf
            node changes without caring about their possible impact on interfaces.

          • --ctf

            Extract ABI information from CTF debug information, if present, in the Kernel and Modules.

          • --btf

            Extract ABI information from BTF debug information, if present, in the Kernel and Modules.

          • --impacted-interfaces | -i

            Tell what interfaces got impacted by each individual ABI change.

          • --full-impact | -f

            Emit a change report that shows the full impact of each change on exported interfaces.  This is  the
            default kind of report emitted by tools like abidiff or abipkgdiff.

          • --exported-interfaces-only

            When using this option, this tool analyzes the descriptions of the types reachable by the interfaces
            (functions and variables) associated with ELF symbols that are defined and  exported  by  the  Linux
            Kernel.

            Otherwise,  the  tool also has the ability to analyze the descriptions of the types reachable by the
            interfaces associated with ELF symbols that are visible outside their translation unit.  This  later
            possibility is however much more resource intensive and results in much slower operations.

            That is why this option is enabled by default.

          • --allow-non-exported-interfaces

            When using this option, this tool analyzes the descriptions of the types reachable by the interfaces
            (functions and variables) that are visible outside of their translation unit.  Once that analysis is
            done, an ABI Corpus is constructed by only considering the subset of types reachable from interfaces
            associated to ELF symbols that are defined and exported by the binary.  It’s that final  ABI  corpus
            which is compared against another one.

            The  problem  with  that approach however is that analyzing all the interfaces that are visible from
            outside their translation unit can amount to a lot of data, leading to very slow operations.

            Note that this option is turned off by default.

          • --show-bytes

            Show sizes and offsets in bytes, not bits.  This option is activated by default.

          • --show-bits

            Show sizes and offsets in bits, not bytes.  By default, sizes and offsets are shown in bytes.

          • --show-hex

            Show sizes and offsets in hexadecimal base.  This option is activated by default.

          • --show-dec

            Show sizes and offsets in decimal base.

   abidw
       abidw reads a shared library in ELF format and emits an XML representation of its ABI to standard output.
       The  emitted  representation  format,  named  ABIXML,  includes  all  the  globally defined functions and
       variables, along with a complete representation of their types.  It also includes a representation of the
       globally defined ELF symbols of the file.

       When  given  the  --linux-tree  option,  this  program  can  also handle a Linux kernel tree.  That is, a
       directory tree that contains both the vmlinux binary and Linux Kernel modules.  It analyses  those  Linux
       Kernel  binaries  and  emits an XML representation of the interface between the kernel and its module, to
       standard output.  In this case, we don’t call it an ABI,  but  a  KMI  (Kernel  Module  Interface).   The
       emitted  KMI  includes  all  the  globally  defined  functions  and  variables,  along  with  a  complete
       representation of their types.

       To generate either ABI or KMI representation, by default  abidw  uses  debug  information  in  the  DWARF
       format, if present, otherwise it looks for debug information in CTF or BTF formats, if present.  Finally,
       if no debug info in these formats is found, it only considers ELF symbols and report about their addition
       or removal.

       This  tool uses the libabigail library to analyze the binary as well as its associated debug information.
       Here is its general mode of operation.

       When instructed to do so, a binary and its associated debug information is read and  analyzed.   To  that
       effect,  libabigail  analyzes  by  default  the  descriptions  of  the  types reachable by the interfaces
       (functions and variables) that are visible outside of their translation  unit.   Once  that  analysis  is
       done,  an  Application  Binary  Interface  Corpus  is constructed by only considering the subset of types
       reachable from interfaces associated to ELF symbols that are defined and exported by  the  binary.   It’s
       that final ABI corpus which libabigail considers as representing the ABI of the analyzed binary.

       Libabigail  then  has  capabilities  to  generate  textual  representations of ABI Corpora, compare them,
       analyze their changes and report about them.

   Invocation
          abidw [options] [<path-to-elf-file>]

   Options--help | -h

            Display a short help about the command and exit.

          • --version | -v

            Display the version of the program and exit.

          • --abixml-version

            Display the version of the ABIXML format emitted by this program and exit.

          • --add-binaries <bin1,bin2,…>

            For each of the comma-separated binaries given in argument to this option, if the binary is found in
            the  directory  specified  by the –added-binaries-dir option, then load the ABI corpus of the binary
            and add it to a set of ABI corpora (called a ABI Corpus Group) made of the  binary  denoted  by  the
            Argument of abidw.  That corpus group is then serialized out.

          • --follow-dependencies

            For  each  dependency of the input binary of abidw, if it is found in the directory specified by the
            --added-binaries-dir option, then construct an ABI corpus out of the dependency and add it to a  set
            of  ABI  corpora  (called  an ABI Corpus Group) along with the ABI corpus of the input binary of the
            program.  The ABI Corpus Group is then serialized out.

          • --list-dependencies

            For each dependency of the input binary of``abidw``, if it’s found in the directory specified by the
            --added-binaries-dir option, then the name of the dependency is printed out.

          • --added-binaries-dir | --abd <dir-path>

            This  option  is to be used in conjunction with the --add-binaries, the --follow-dependencies or the
            --list-dependencies option.  Binaries listed as arguments of  the  --add-binaries  option  or  being
            dependencies  of  the  input binary in the case of the --follow-dependencies option and found in the
            directory <dir-path> are going to be loaded as ABI corpus and  added  to  the  set  of  ABI  corpora
            (called an ABI corpus group) built and serialized.

          • --debug-info-dir | -d <dir-path>

            In  cases  where  the  debug  info  for  path-to-elf-file is in a separate file that is located in a
            non-standard place, this tells abidw where to look for that debug info file.

            Note that dir-path must point to the root directory under which the debug information is arranged in
            a tree-like manner.  Under Red Hat based systems, that directory is usually <root>/usr/lib/debug.

            This option can be provided several times with different root directories.  In that case, abidw will
            potentially look into all those root directories to find the split debug info for the elf file.

            Note that this option is not mandatory for  split  debug  information  installed  by  your  system’s
            package manager because then abidw knows where to find it.

          • --out-file <file-path>

            This  option  instructs  abidw  to  emit  the  XML  representation of path-to-elf-file into the file
            file-path, rather than emitting it to its standard output.

          • --noout

            This option instructs abidw to not emit the XML representation of the ABI.  So it only reads the ELF
            and  debug  information,  builds  the  internal representation of the ABI and exits.  This option is
            usually useful for debugging purposes.

          • --no-corpus-path

            Do not emit the path attribute for the ABI corpus.

          • --suppressions | suppr <path-to-suppression-specifications-file>

            Use a suppression specification file located at path-to-suppression-specifications-file.  Note  that
            this  option  can  appear  multiple  times  on  the command line.  In that case, all of the provided
            suppression specification files are taken into account.  ABI artifacts matched  by  the  suppression
            specifications are suppressed from the output of this tool.

          • --kmi-whitelist | -kaw <path-to-whitelist>

            When  analyzing  a Linux Kernel binary, this option points to the white list of names of ELF symbols
            of functions and variables which ABI must be written out.  That white list  is  called  a  ”  Kernel
            Module  Interface  white  list”.   This  is  because for the Kernel, we don’t talk about the ABI; we
            rather talk about the interface between the Kernel and its module. Hence the term  KMI  rather  than
            ABI

            Any  other  function  or  variable  which  ELF symbol are not present in that white list will not be
            considered by the KMI writing process.

            If this option is not provided – thus if no white list is provided – then the entire KMI,  that  is,
            all  publicly  defined  and  exported functions and global variables by the Linux Kernel binaries is
            emitted.

          • --linux-tree | --lt

            Make abidw to consider the input path as a path to a directory  containing  the  vmlinux  binary  as
            several  kernel modules binaries.  In that case, this program emits the representation of the Kernel
            Module Interface (KMI) on the standard output.

            Below is an example of usage of abidw on a Linux Kernel tree.

            First, checkout a Linux Kernel source tree and build it.  Then  install  the  kernel  modules  in  a
            directory  somewhere.   Copy the vmlinux binary into that directory too.  And then serialize the KMI
            of that kernel to disk, using abidw:

                $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
                $ cd linux && git checkout v4.5
                $ make allyesconfig all
                $ mkdir build-output
                $ make INSTALL_MOD_PATH=./build-output modules_install
                $ cp vmlinux build-output/modules/4.5.0
                $ abidw --linux-tree build-output/modules/4.5.0 > build-output/linux-4.5.0.kmi

          • --headers-dir | --hd <headers-directory-path-1>

            Specifies where to find the public headers of the binary that the tool has to  consider.   The  tool
            will thus filter out types that are not defined in public headers.

            Note  that  several  public header directories can be specified for the binary to consider.  In that
            case the --header-dir option should be present several times  on  the  command  line,  like  in  the
            following example:

                $ abidw --header-dir /some/path       \
                        --header-dir /some/other/path \
                        binary > binary.abi

          • --header-file | --hf <header-file-path>

            Specifies  where  to  find  one of the public headers of the abi file that the tool has to consider.
            The tool will thus filter out types that are not defined in public headers.

          • --drop-private-types

            This option is to be used with the --headers-dir and/or  header-file  options.   With  this  option,
            types  that  are  NOT  defined  in the headers are entirely dropped from the internal representation
            build by Libabigail to represent the ABI and will not end up in the abi XML file.

          • --no-elf-needed

            Do not include the list of DT_NEEDED dependency names in the corpus.

          • --drop-undefined-syms

            With this option functions or variables for which the (exported) ELF symbol is undefined are dropped
            from the internal representation build by Libabigail to represent the ABI and will not end up in the
            abi XML file.

          • --exported-interfaces-only

            By default, when looking at the debug information accompanying a  binary,  this  tool  analyzes  the
            descriptions  of  the  types  reachable by the interfaces (functions and variables) that are visible
            outside of their translation unit.  Once that analysis is done, an ABI corpus is constructed by only
            considering the subset of types reachable from interfaces associated to ELF symbols that are defined
            and exported by the binary.  It’s that final ABI corpus which textual  representation  is  saved  as
            ABIXML.

            The  problem  with  that approach however is that analyzing all the interfaces that are visible from
            outside their translation unit can amount to a lot of  data,  especially  when  those  binaries  are
            applications, as opposed to shared libraries.  One example of such applications is the Linux Kernel.
            Analyzing massive ABI corpora like these can be extremely slow.

            To mitigate that performance issue, this option allows libabigail to only  analyze  types  that  are
            reachable from interfaces associated with defined and exported ELF symbols.

            Note  that  this  option  is  turned on by default when analyzing the Linux Kernel.  Otherwise, it’s
            turned off by default.

          • --allow-non-exported-interfaces

            When looking at the debug information accompanying a binary, this tool analyzes the descriptions  of
            the  types  reachable  by the interfaces (functions and variables) that are visible outside of their
            translation unit.  Once that analysis is done, an ABI corpus is constructed by only considering  the
            subset of types reachable from interfaces associated to ELF symbols that are defined and exported by
            the binary.  It’s that final ABI corpus which textual representation is saved as ABIXML.

            The problem with that approach however is that analyzing all the interfaces that  are  visible  from
            outside  their  translation  unit  can  amount  to a lot of data, especially when those binaries are
            applications, as opposed to shared libraries.  One example of such applications is the Linux Kernel.
            Analyzing massive ABI corpora like these can be extremely slow.

            In  the  presence  of an “average sized” binary however one can afford having libabigail analyze all
            interfaces that are visible outside of their translation unit, using this option.

            Note that this option is turned on by default, unless we are in the presence of the Linux Kernel.

          • --no-linux-kernel-mode

            Without this option, if abipkgiff detects that the binaries  it  is  looking  at  are  Linux  Kernel
            binaries  (either  vmlinux  or  modules)  then  it  only considers functions and variables which ELF
            symbols are listed in the __ksymtab and __ksymtab_gpl sections.

            With this option, abipkgdiff considers the binary as a non-special ELF binary.   It  thus  considers
            functions and variables which are defined and exported in the ELF sense.

          • --check-alternate-debug-info <elf-path>

            If  the debug info for the file elf-path contains a reference to an alternate debug info file, abidw
            checks that it can find that alternate debug info file.  In that case, it emits a meaningful success
            message  mentioning  the  full  path to the alternate debug info file found.  Otherwise, it emits an
            error code.

          • --no-show-locs
              In the emitted ABI representation, do not show file,  line  or  column  where  ABI  artifacts  are
              defined.

          • --no-parameter-names

            In the emitted ABI representation, do not show names of function parameters, just the types.

          • --no-write-default-sizes

            In the XML ABI representation, do not write the size-in-bits for pointer type definitions, reference
            type definitions, function declarations and function types  when  they  are  equal  to  the  default
            address size of the translation unit.  Note that libabigail before 1.8 will not set the default size
            and will interpret types without a size-in-bits attribute as zero sized.

          • --type-id-style <sequence``|``hash>

            This option controls how types are idenfied in the generated XML files.  The default sequence  style
            just  numbers (with type-id- as prefix) the types in the order they are encountered.  The hash style
            uses a (stable, portable) hash of libabigail’s internal type names and is intended to make  the  XML
            files easier to diff.

          • --check-alternate-debug-info-base-name <elf-path>

            Like  --check-alternate-debug-info,  but  in  the success message, only mention the base name of the
            debug info file; not its full path.

          • --load-all-types

            By default, libabigail (and thus abidw) only loads types  that  are  reachable  from  functions  and
            variables  declarations  that  are publicly defined and exported by the binary.  So only those types
            are present in the output of abidw.  This option however makes abidw load all the types  defined  in
            the binaries, even those that are not reachable from public declarations.

          • --abidiff
              Load  the  ABI  of  the  ELF  binary  given  in  argument, save it in libabigail’s XML format in a
              temporary file; read the ABI from the temporary XML file and compare the ABI that  has  been  read
              back against the ABI of the ELF binary given in argument.  The ABIs should compare equal.  If they
              don’t, the program emits a diagnostic and exits with a non-zero code.

              This is a debugging and sanity check option.

              • --debug-abidiff

              Same as --abidiff but in debug mode.  In this mode, error messages are  emitted  for  types  which
              fail type canonicalization.

              This  is an optional debugging and sanity check option.  To enable it the libabigail package needs
              to be configured with the –enable-debug-self-comparison option.

              • --debug-type-canonicalization | --debug-tc

              Debug the type canonicalization process.  This is done by using structural and canonical  equality
              when  canonicalizing  every  single type.  Structural and canonical equality should yield the same
              result.  If they don’t  yield  the  same  result  for  a  given  type,  then  it  means  that  the
              canonicalization  of  that  type  went  wrong.   In that case, an error message is emitted and the
              execution of the program is aborted.

              This   option   is   available    only    if    the    package    was    configured    with    the
              –enable-debug-type-canonicalization option.

          • --no-assume-odr-for-cplusplus

            When  analysing a binary originating from C++ code using DWARF debug information, libabigail assumes
            the One Definition Rule to speed-up the analysis.  In that case, when several types  have  the  same
            name in the binary, they are assumed to all be equal.

            This option disables that assumption and instructs libabigail to actually actually compare the types
            to determine if they are equal.

          • --no-leverage-dwarf-factorization

            When analysing a binary which DWARF debug information was processed with  the  DWZ  tool,  the  type
            information  is  supposed  to  be already factorized.  That context is used by libabigail to perform
            some speed optimizations.

            This option disables those optimizations.

          • --ctf

            Extract ABI information from CTF debug information, if present in the given object.

          • --annotate
              Annotate the ABIXML output with comments above most  elements.   The  comments  are  made  of  the
              pretty-printed  form  types,  declaration  or even ELF symbols.  The purpose is to make the ABIXML
              output more human-readable for debugging or documenting purposes.

          • --stats

            Emit statistics about various internal things.

          • --verbose

            Emit verbose logs about the progress of miscellaneous internal things.

   Usage examples
          1. Emitting an ABIXML representation of a binary:

                 $ abidw binary > binary.abi

          2. Emitting an ABIXML representation of a set of binaries specified on the command line:

                 $ abidw --added-binaries=bin1,bin2,bin3  \
                         --added-binaries-dir /some/where \
                         binary > binaries.abi

             Note that the binaries bin1, bin2 and bin3 are  to  be  found  in  the  directory  /some/where.   A
             representation  of  the ABI of the set of binaries binary, bin1, bin2 and bin3 called an ABI corpus
             group is serialized in the file binaries.abi.

          3. Emitting an ABIXML representation of a binary and its dependencies:

                 $ abidw --follow-dependencies              \
                         --added-binaries-dir /some/where   \
                         binary > binary.abi

             Note that only the dependencies that are found in the directory /some/where  are  analysed.   Their
             ABIs,  along  with  the  ABI  the  binary  named  binary are represented as an ABI corpus group and
             serialized in the file binary.abi, in the ABIXML format.

   Notes
   Alternate debug info files
       As of the version 4 of the DWARF specification, Alternate debug information is a  GNU  extension  to  the
       DWARF specification.  It has however been proposed for inclusion into the upcoming version 5 of the DWARF
       standard.  You can read more about the GNU extensions to the DWARF standard here.

   abicompat
       abicompat checks that an application that links against a given shared library is  still  ABI  compatible
       with  a  subsequent  version  of  that  library.   If  the  new  version of the library introduces an ABI
       incompatibility, then abicompat hints the user at what exactly that incompatibility is.

   Invocation
          abicompat [options] [<application> <shared-library-first-version> <shared-library-second-version>]

   Options--help

            Display a short help about the command and exit.

          • –version | -v

            Display the version of the program and exit.

          • --list-undefined-symbols | -u

            Display the list of undefined symbols of the application and exit.

          • --show-base-names | -b

            In the resulting report emitted by the tool, this option makes  the  application  and  libraries  be
            referred  to  by  their base names only; not by a full absolute name.  This can be useful for use in
            scripts that wants to compare names of the application and libraries  independently  of  what  their
            directory names are.

          • --app-debug-info-dir | --appd <path-to-app-debug-info-directory>

            Set the path to the directory under which the debug information of the application is supposed to be
            laid out.  This is useful for application binaries for which the debug info is in a separate set  of
            files.

          • --lib-debug-info-dir1 | --libd1 <path-to-lib1-debug-info>

            Set  the  path to the directory under which the debug information of the first version of the shared
            library is supposed to be laid out.  This is useful for shared library binaries for which the  debug
            info is in a separate set of files.

          • --lib-debug-info-dir2 | --libd2 <path-to-lib1-debug-info>

            Set  the path to the directory under which the debug information of the second version of the shared
            library is supposed to be laid out.  This is useful for shared library binaries for which the  debug
            info is in a separate set of files.

          • --suppressions | --suppr <path-to-suppressions>

            Use  a  suppression  specification  file located at path-to-suppressions.  Note that this option can
            appear multiple times on the command line; all the suppression specification files  are  then  taken
            into account.

          • --no-show-locs
              Do not show information about where in the second shared library the respective type was changed.

          • --ctf

            When comparing binaries, extract ABI information from CTF debug information, if present.

          • --fail-no-debug-info

            If  no  debug  info  was found, then this option makes the program to fail.  Otherwise, without this
            option, the program will attempt to compare properties of the binaries that are not related to debug
            info, like pure ELF properties.

          • --ignore-soname

            Ignore differences in the SONAME when doing a comparison

          • --weak-mode

            This  triggers  the  weak  mode  of  abicompat.   In  this  mode, only one version of the library is
            required.  That is, abicompat is invoked like this:

                abicompat --weak-mode <the-application> <the-library>

            Note that the --weak-mode option can even be omitted if only one version of the  library  is  given,
            along with the application; in that case, abicompat automatically switches to operate in weak mode:

                abicompat <the-application> <the-library>

            In  this weak mode, the types of functions and variables exported by the library and consumed by the
            application (as in, the  symbols  of  the  these  functions  and  variables  are  undefined  in  the
            application  and are defined and exported by the library) are compared to the version of these types
            as expected by the application.  And if these two versions of types are different,  abicompat  tells
            the user what the differences are.

            In  other  words,  in  this  mode,  abicompat  checks  that the types of the functions and variables
            exported by the library mean the same thing as what the application expects, as far as  the  ABI  is
            concerned.

            Note  that in this mode, abicompat doesn’t detect exported functions or variables (symbols) that are
            expected by the application but that are removed from the library.  That is why it  is  called  weak
            mode.

   Return values
       The  exit  code of the abicompat command is either 0 if the ABI of the binaries being compared are equal,
       or non-zero if they differ or if the tool encountered an error.

       In the later case, the exit code is a 8-bits-wide bit field in which each bit has a specific meaning.

       The first bit, of value 1, named ABIDIFF_ERROR means there was an error.

       The second bit, of value 2, named ABIDIFF_USAGE_ERROR means there was  an  error  in  the  way  the  user
       invoked  the  tool.   It might be set, for instance, if the user invoked the tool with an unknown command
       line switch, with a wrong number or argument, etc.  If this bit is set, then the ABIDIFF_ERROR  bit  must
       be set as well.

       The  third  bit,  of  value  4, named ABIDIFF_ABI_CHANGE means the ABI of the binaries being compared are
       different.

       The fourth bit, of value 8, named ABIDIFF_ABI_INCOMPATIBLE_CHANGE means the ABI of the binaries  compared
       are different in an incompatible way.  If this bit is set, then the ABIDIFF_ABI_CHANGE bit must be set as
       well.  If the ABIDIFF_ABI_CHANGE is set and the ABIDIFF_INCOMPATIBLE_CHANGE is NOT  set,  then  it  means
       that  the  ABIs  being  compared  might or might not be compatible.  In that case, a human being needs to
       review the ABI changes to decide if they are compatible or not.

       The remaining bits are not used for the moment.

   Usage examples
          • Detecting a possible ABI incompatibility in a new shared library version:

                $ cat -n test0.h
                     1  struct foo
                     2  {
                     3    int m0;
                     4
                     5    foo()
                     6      : m0()
                     7    {}
                     8  };
                     9
                    10  foo*
                    11  first_func();
                    12
                    13  void
                    14  second_func(foo&);
                    15
                    16  void
                    17  third_func();
                $

                $ cat -n test-app.cc
                     1  // Compile with:
                     2  //  g++ -g -Wall -o test-app -L. -ltest-0 test-app.cc
                     3
                     4  #include "test0.h"
                     5
                     6  int
                     7  main()
                     8  {
                     9    foo* f = first_func();
                    10    second_func(*f);
                    11    return 0;
                    12  }
                $

                $ cat -n test0.cc
                     1  // Compile this with:
                     2  //  g++ -g -Wall -shared -o libtest-0.so test0.cc
                     3
                     4  #include "test0.h"
                     5
                     6  foo*
                     7  first_func()
                     8  {
                     9    foo* f = new foo();
                    10    return f;
                    11  }
                    12
                    13  void
                    14  second_func(foo&)
                    15  {
                    16  }
                    17
                    18  void
                    19  third_func()
                    20  {
                    21  }
                $

                $ cat -n test1.h
                     1  struct foo
                     2  {
                     3    int  m0;
                     4    char m1; /* <-- a new member got added here! */
                     5
                     6    foo()
                     7    : m0(),
                     8      m1()
                     9    {}
                    10  };
                    11
                    12  foo*
                    13  first_func();
                    14
                    15  void
                    16  second_func(foo&);
                    17
                    18  void
                    19  third_func();
                $

                $ cat -n test1.cc
                     1  // Compile this with:
                     2  //  g++ -g -Wall -shared -o libtest-1.so test1.cc
                     3
                     4  #include "test1.h"
                     5
                     6  foo*
                     7  first_func()
                     8  {
                     9    foo* f = new foo();
                    10    return f;
                    11  }
                    12
                    13  void
                    14  second_func(foo&)
                    15  {
                    16  }
                    17
                    18  /* Let's comment out the definition of third_func()
                    19     void
                    20     third_func()
                    21     {
                    22     }
                    23  */
                $

            • Compile the first and second versions of the libraries: libtest-0.so and libtest-1.so:

                  $ g++ -g -Wall -shared -o libtest-0.so test0.cc
                  $ g++ -g -Wall -shared -o libtest-1.so test1.cc

            • Compile the application and link it against  the  first  version  of  the  library,  creating  the
              test-app binary:

                  $ g++ -g -Wall -o test-app -L. -ltest-0.so test-app.cc

            • Now,  use  abicompat to see if libtest-1.so is ABI compatible with app, with respect to the ABI of
              libtest-0.so:

                  $ abicompat test-app libtest-0.so libtest-1.so
                  ELF file 'test-app' might not be ABI compatible with 'libtest-1.so' due to differences with 'libtest-0.so' below:
                  Functions changes summary: 0 Removed, 2 Changed, 0 Added functions
                  Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

                  2 functions with some indirect sub-type change:

                    [C]'function foo* first_func()' has some indirect sub-type changes:
                      return type changed:
                        in pointed to type 'struct foo':
                          size changed from 32 to 64 bits
                          1 data member insertion:
                            'char foo::m1', at offset 32 (in bits)
                    [C]'function void second_func(foo&)' has some indirect sub-type changes:
                      parameter 0 of type 'foo&' has sub-type changes:
                        referenced type 'struct foo' changed, as reported earlier

                  $

            • Now use the weak mode of abicompat, that is, providing just the application and the new version of
              the library:

                  $ abicompat --weak-mode test-app libtest-1.so
                  functions defined in library
                      'libtest-1.so'
                  have sub-types that are different from what application
                      'test-app'
                  expects:

                    function foo* first_func():
                      return type changed:
                        in pointed to type 'struct foo':
                          size changed from 32 to 64 bits
                          1 data member insertion:
                            'char foo::m1', at offset 32 (in bits)

                  $

   abilint
       abilint  parses  the native XML representation of an ABI as emitted by abidw.  Once it has parsed the XML
       representation of the ABI, abilint builds and in-memory model from it.  It then tries to save it back  to
       an  XML  form,  to  standard output.  If that read-write operation succeeds chances are the input XML ABI
       representation is meaningful.

       Note that the main intent of this tool to help debugging issues in the underlying Libabigail library.

       Note also that abilint can also read an ELF input file, build  the  in-memory  model  for  its  ABI,  and
       serialize  that  model  back  into  XML  to  standard  output.   In that case, the ELF input file must be
       accompanied with its debug information in the DWARF format.

   Invocation
          abilint [options] [<abi-file1>]

   Options--help

            Display a short help message and exits.

          • –version | -v

            Display the version of the program and exit.

          • --debug-info-dir <path>

            When reading an ELF input file which debug information is split  out  into  a  separate  file,  this
            options tells abilint where to find that separate debug information file.

            Note  that  path must point to the root directory under which the debug information is arranged in a
            tree-like manner.  Under Red Hat based systems, that directory is usually <root>/usr/lib/debug.

            Note also that this option is not mandatory for split debug information installed by  your  system’s
            package manager because then abidiff knows where to find it.

          • --diff

            For XML inputs, perform a text diff between the input and the memory model saved back to disk.  This
            can help to spot issues in the handling of the XML format by the underlying Libabigail library.

          • --noout

            Do not display anything on standard output.  The return code of the command is the only way to  know
            if the command succeeded.

          • --suppressions | suppr <path-to-suppression-specifications-file>

            Use  a suppression specification file located at path-to-suppression-specifications-file.  Note that
            this option can appear multiple times on the command line.   In  that  case,  all  of  the  provided
            suppression  specification  files  are taken into account.  ABI artifacts matched by the suppression
            specifications are suppressed from the output of this tool.

          • --headers-dir | --hd <headers-directory-path-1>

            Specifies where to find the public headers of  the  first  shared  library  that  the  tool  has  to
            consider.  The tool will thus filter out types that are not defined in public headers.

          • --header-file | --hf <header-file-path>

            Specifies  where  to  find  one of the public headers of the abi file that the tool has to consider.
            The tool will thus filter out types that are not defined in public headers.

          • --stdin | --

            Read the input content from standard input.

          • --tu

            Expect the input XML to represent a single translation unit.

          • --ctf

            Extract ABI information from CTF debug information, if present in the given object.

   fedabipkgdiff
       fedabipkgdiff compares the ABI of shared libraries in Fedora packages.  It’s a convenient way  to  do  so
       without having to manually download packages from the Fedora Build System.

       fedabipkgdiff  knows  how to talk with the Fedora Build System to find the right packages versions, their
       associated debug information and development packages, download them,  compare  their  ABI  locally,  and
       report about the possible ABI changes.

       Note  that  by default, this tool reports ABI changes about types that are defined in public header files
       found in the development packages associated with the packages  being  compared.   It  also  reports  ABI
       changes  about  functions and global variables whose symbols are defined and exported in the ELF binaries
       found in the packages being compared.

   Invocation
          fedabipkgdiff [option] <NVR> ...

   Environment
       fedabipkgdiff loads two default suppression specifications files, merges their  content  and  use  it  to
       filter out ABI change reports that might be considered as false positives to users.

       • Default system-wide suppression specification file

         It’s  located by the optional environment variable LIBABIGAIL_DEFAULT_SYSTEM_SUPPRESSION_FILE.  If that
         environment  variable  is  not  set,  then  fedabipkgdiff  tries   to   load   the   suppression   file
         $libdir/libabigail/libabigail-default.abignore.    If  that  file  is  not  present,  then  no  default
         system-wide suppression specification file is loaded.

       • Default user suppression specification file.

         It’s located by the optional environment LIBABIGAIL_DEFAULT_USER_SUPPRESSION_FILE.  If that environment
         variable  is  not  set, then fedabipkgdiff tries to load the suppression file $HOME/.abignore.  If that
         file is not present, then no default user suppression specification is loaded.

   Options--help | -h

            Display a short help about the command and exit.

          • --dry-run

            Don’t actually perform the ABI comparison.  Details about what is going to be done  are  emitted  on
            standard output.

          • --debug

            Emit  debugging  messages about the execution of the program.  Details about each method invocation,
            including input parameters and returned values, are emitted.

          • --traceback

            Show traceback when an exception raised. This is useful for developers of the tool  itself  to  know
            more exceptional errors.

          • --server <URL>

            Specifies the URL of the Koji XMLRPC service the tool talks to.  The default value of this option is
            http://koji.fedoraproject.org/kojihub.

          • --topurl <URL>

            Specifies the URL of the package store the tool downloads RPMs from.   The  default  value  of  this
            option is https://kojipkgs.fedoraproject.org.

          • --from <distro>

            Specifies the name of the baseline Fedora distribution in which to find the first build that is used
            for comparison. The distro value can be any valid value of the RPM macro %{?dist}  for  Fedora,  for
            example, fc4, fc23, fc25.

          • --to <distro>

            Specifies  the  name  of the Fedora distribution in which to find the build that is compared against
            the baseline specified by option --from.  The distro value could be any valid value of the RPM macro
            %{?dist} for Fedora, for example, fc4, fc23.

          • --all-subpackages

            Instructs  the  tool  to  also  compare  the ABI of the binaries in the sub-packages of the packages
            specified.

          • --dso-only

            Compares the ABI of shared libraries only.  If this option is not provided, the  tool  compares  the
            ABI of all ELF binaries found in the packages.

          • --suppressions <path-to-suppresions>

            Use a suppression specification file located at path-to-suppressions.

          • --no-default-suppression

            Do not load the default suppression specification files.

          • --no-devel-pkg

            Do  not  take associated development packages into account when performing the ABI comparison.  This
            makes the tool report ABI changes about all types that  are  reachable  from  functions  and  global
            variables  which  symbols  are defined and publicly exported in the binaries being compared, even if
            those types are not defined in public header files available from the packages being compared.

          • --show-identical-binaries
              Show the names of the all binaries compared, including the binaries whose ABI compare  equal.   By
              default,  when  this  option is not provided, only binaries with ABI changes are mentionned in the
              output.

          • --abipkgdiff <path/to/abipkgdiff>

            Specify an alternative abipkgdiff instead of the one installed in system.

          • --clean-cache-before

            Clean cache before ABI comparison.

          • --clean-cache-after

            Clean cache after ABI comparison.

          • --clean-cache

            If you want to clean cache both before and after ABI comparison, --clean-cache is the convenient way
            for you to save typing of two options at same time.

       Note that a build is a specific version and release of an RPM package.  It’s specified by its the package
       name, version and release. These are specified by the Fedora Naming Guidelines

   Return value
       The exit code of the abipkgdiff command is either 0 if the ABI of the binaries compared  are  equivalent,
       or non-zero if they differ or if the tool encountered an error.

       In the later case, the value of the exit code is the same as for the abidiff tool.

   Use cases
       Below are some usage examples currently supported by fedabipkgdiff.

          1. Compare  the  ABI  of  binaries  in a local package against the ABI of the latest stable package in
             Fedora 23.

             Suppose you have built just built the httpd package and you want to compare the ABI of the binaries
             in  this locally built package against the ABI of the binaries in the latest http build from Fedora
             23.  The command line invocation would be:

                 $ fedabipkgdiff --from fc23 ./httpd-2.4.18-2.fc24.x86_64.rpm

          2. Compare the ABI of binaries in two local packages.

             Suppose you have built two versions of package httpd, and you want  to  see  what  ABI  differences
             between these two versions of RPM files. The command line invocation would be:

                 $ fedabipkgdiff path/to/httpd-2.4.23-3.fc23.x86_64.rpm another/path/to/httpd-2.4.23-4.fc24.x86_64.rpm

             All  what  fedabipkgdiff  does happens on local machine without the need of querying or downloading
             RPMs from Koji.

          3. Compare the ABI of binaries in the latest build of the httpd package in Fedora 23 against  the  ABI
             of the binaries in the latest build of the same package in 24.

             In  this  case,  note that neither of the two packages are available locally.  The tool is going to
             talk with the Fedora Build System, determine what the versions and releases of the latest  packages
             are, download them and perform the comparison locally.  The command line invocation would be:

                 $ fedabipkgdiff --from fc23 --to fc24 httpd

          4. Compare  the  ABI  of  binaries  of  two builds of the httpd package, designated their versions and
             releases.

             If we want to do perform the ABI comparison for all the processor architectures supported by Fedora
             the command line invocation would be:

                 $ fedabipkgdiff httpd-2.8.14.fc23 httpd-2.8.14.fc24

             But  if  we  want  to perform the ABI comparison for a specific architecture, say, x86_64, then the
             command line invocation would be:

                 $ fedabipkgdiff httpd-2.8.14.fc23.x86_64 httpd-2.8.14.fc24.x86_64

          5. If the use  wants  to  also  compare  the  sub-packages  of  a  given  package,  she  can  use  the
             –all-subpackages option.  The first command of the previous example would thus look like:

                 $ fedabipkgdiff --all-subpackages httpd-2.8.14.fc23 httpd-2.8.14.fc24

CONCEPTS

   ABI artifacts
       An  ABI artifact is a relevant part of the ABI of a shared library or program.  Examples of ABI artifacts
       are exported types, variables, functions, or ELF symbols exported by a shared library.

       The set of ABI artifact for a binary is called an ABI Corpus.

   Harmful changes
       A change in the diff report is considered harmful if it might cause ABI compatibility issues.   That  is,
       it  might  prevent an application dynamically linked against a given version of a library to keep working
       with the changed subsequent versions of the same library.

   Harmless changes
       A change in the diff report is considered harmless if it will not  cause  any  ABI  compatibility  issue.
       That is, it will not prevent an application dynamically linked against given version of a library to keep
       working with the changed subsequent versions of the same library.

       By default, abidiff filters harmless changes from the diff report.

   Suppression specifications
   Definition
       A suppression specification file is a way for a  user  to  instruct  abidiff,  abipkgdiff  or  any  other
       relevant libabigail tool to avoid emitting reports for changes involving certain ABI artifacts.

       It  contains  directives  (or  specifications)  that  describe the set of ABI artifacts to avoid emitting
       change reports about.

   Introductory examples
       Its syntax is based on a simplified and customized form of Ini File Syntax.   For  instance,  to  specify
       that change reports on a type named FooPrivateType should be suppressed, one could write this suppression
       specification:

          [suppress_type]
            name = FooPrivateType

       If we want to ensure that only change reports about structures named FooPrivateType should be suppressed,
       we could write:

          [suppress_type]
            type_kind = struct
            name = FooPrivateType

       But  we  could also want to suppress change reports avoid typedefs named FooPrivateType.  In that case we
       would write:

          [suppress_type]
            type_kind = typedef
            name = FooPrivateType

       Or, we could want to  suppress  change  reports  about  all  struct  which  names  end  with  the  string
       “PrivateType”:

          [suppress_type]
            type_kind = struct
            name_regexp = ^.*PrivateType

       Let’s now look at the generic syntax of suppression specification files.

   Syntax
   Properties
       More  generally,  the  format  of  suppression  lists is organized around the concept of property.  Every
       property has a name and a value, delimited by the = sign.  E.g:

          name = value

       Leading and trailing white spaces are ignored around property names and values.

   Regular expressions
       The value of some properties might be a regular expression.  In that case,  they  must  comply  with  the
       syntax of extended POSIX regular expressions.  Note that Libabigail uses the regular expression engine of
       the GNU C Library.

   Escaping a character in a regular expression
       When trying to match a string that contains a * character, like in the pointer type  int*,  one  must  be
       careful  to  notice  that the character * is a special character in the extended POSIX regular expression
       syntax.  And that character must be  escaped  for  the  regular  expression  engine.   Thus  the  regular
       expression that would match the string int* in a suppression file should be

          int\\*

       Wait; but then why the two \ characters?  Well, because the \ character is a special character in the Ini
       File Syntax used for specifying suppressions.  So it must be escaped as well, so that the Ini File parser
       leaves  a  \  character intact in the data stream that is handed to the regular expression engine.  Hence
       the \\ targeted at the Ini File parser.

       So, in short, to escape a character in a regular expression, always prefix  the  character  with  the  \\
       sequence.

   Modus operandi
       Suppression  specifications  can  be  applied  at  two  different  points  of  the processing pipeline of
       libabigail.

       In the default operating mode called “late suppression mode”, suppression specifications are  applied  to
       the  result  of  comparing  the  in-memory internal representations of two ABIs.  In this mode, if an ABI
       artifact matches a suppression specification, its changes are not mentioned in  the  ABI  change  report.
       The  internal  representation  of the “suppressed” changed ABI artifact is still present in memory; it is
       just not mentioned in the ABI change report.  The change report can still mention  statistics  about  the
       number of changed ABI artifacts that were suppressed.

       There  is another operating mode called the “early suppression mode” where suppression specifications are
       applied during the construction of the in-memory internal representation of a given ABI.  In  that  mode,
       if an ABI artifact matches a suppression specification, no in-memory internal representation is built for
       it.  As a result, no change about the matched ABI artifact is going to be mentioned  in  the  ABI  change
       report  and no statistic about the number of suppressed ABI changes is available.  Also, please note that
       because suppressed ABI artifacts are removed from the in-memory internal representation in this mode, the
       amount  memory  used by the internal representation is potentially smaller than the memory consumption in
       the late suppression mode.

   Sections
       Properties are then grouped into arbitrarily named sections that shall not be nested.  The  name  of  the
       section is on a line by itself and is surrounded by square brackets, i.e:

          [section_name]
          property1_name = property1_value
          property2_name = property2_value

       A  section  might  or  might  not have properties.  Sections that expect to have properties and which are
       found nonetheless empty are just ignored.  Properties that are not recognized by the reader  are  ignored
       as well.

   Section names
       Each  different  section  can  be  thought  of  as being a directive to suppress ABI change reports for a
       particular kind of ABI artifact.

   [suppress_file]
       This directive prevents a given tool from loading a file (binary or abixml file)  if  its  file  name  or
       other  properties match certain properties.  Thus, if the tool is meant to compare the ABIs of two files,
       and if the directive prevents it from loading either one of the files, then no comparison is performed.

       Note that for the [suppress_file] directive to work, at least one of the  following  properties  must  be
       provided:
          file_name_regexp, file_name_not_regexp, soname_regexp, soname_not_regexp.

       If none of the above properties are provided, then the [suppress_file] directive is simply ignored.

       The potential properties of this sections are listed below:

       • file_name_not_regexp

         Usage:
            file_name_not_regexp = <regular-expression>

         Prevents the system from loading the file which name does not match the regular expression specified as
         value of this property.

       • file_name_regexp

         Usage:
            file_name_regexp = <regular-expression>

         Prevents the system from loading the file which name matches the regular expression specified as  value
         of this property.

       • label
          Usage:
              label = <some-value>

          Define  a label for the section.  A label is just an informative string that might be used by the tool
          to refer to a type suppression in error messages.

       • soname_regexp

         Usage:
            soname_regexp = <regular-expression>

         Prevents the system from loading the file which contains a SONAME property  that  matches  the  regular
         expression  of  this  property.   Note that this property also works on an abixml file if it contains a
         SONAME property.

       • soname_not_regexp

         Usage:
            soname_not_regexp = <regular-expression>

         Prevents the system from loading the file which contains a SONAME property  that  does  NOT  match  the
         regular  expression  of  this  property.   Note  that  this property also works on an abixml file if it
         contains a SONAME property.

   [suppress_type]
       This directive suppresses report messages about a type change.

       Note that for the [suppress_type] directive to work, at least one of the  following  properties  must  be
       provided:
          file_name_regexp,   file_name_not_regexp,   soname_regexp,   soname_not_regexp,   name,   name_regexp,
          name_not_regexp, source_location_not_in, source_location_not_regexp, type_kind.

       If none of the above properties are provided, then the [suppress_type] directive is simply ignored.

       The potential properties of this sections are listed below:

       • accessed_through
          Usage:
              accessed_through = <some-predefined-values>

          Suppress change reports involving a type which is referred to either directly or through a pointer  or
          a reference.  The potential values of this property are the predefined keywords below:

              • direct

                So if the [suppress_type] contains the property description:

                   accessed_through = direct

                then  changes  about  a  type  that  is  referred-to  directly  (i.e, not through a pointer or a
                reference) are going to be suppressed.

              • pointer

                If the accessed_through property is set to the value pointer then changes about a type  that  is
                referred-to through a pointer are going to be suppressed.

              • reference

                If the accessed_through property is set to the value reference then changes about a type that is
                referred-to through a reference are going to be suppressed.

              • reference-or-pointer

                If the accessed_through property is set to the value reference-or-pointer then changes  about  a
                type that is referred-to through either a reference or a pointer are going to be suppressed.

          For  an  extensive  example  of  how  to  use  this property, please check out the example below about
          suppressing change reports about types accessed either directly or through pointers.

       • changed_enumerators

         Usage:
            changed_enumerators = <list-of-enumerators>

         Suppresses change reports involving changes in the value of enumerators of a  given  enum  type.   This
         property  is  applied  if  the type_kind property is set to the value enum, at least.  The value of the
         changed_enumerators is a comma-separated list of the enumerators that the user expects to change.   For
         instance:

            changed_enumerators = LAST_ENUMERATORS0, LAST_ENUMERATOR1

       • changed_enumerators_regexp

         Usage:
            changed_enumerators_regexp = <list-of-enumerator-regular-expressions>

         Suppresses  change  reports  involving  changes in the value of enumerators of a given enum type.  This
         property is applied if the type_kind property is set to the value enum, at least.   The  value  of  the
         changed_enumerators_regexp  property is a comma-separated list of regular expressions that should match
         the names of the enumerators that the user expects to change.  For instance:

            changed_enumerators_regexp = .*_MAX$, .*_LAST$, .*_NUM$, .*_NBITS$

         In the example above, change reports to any enumerator which name ends with _MAX, _LAST, _NUM or _NBITS
         will be suppressed.

         Note  that  for  this property to be applied to changes to an enum type, the size of the enum type must
         NOT have changed.

       • drop
          Usage:
              drop = yes | no

          If a type is matched by a suppression specification which contains the “drop” property  set  to  “yes”
          (or to “true”) then the type is not even going to be represented in the internal representation of the
          ABI being analyzed.  This property makes its enclosing suppression specification to be applied in  the
          early  suppression  specification mode.  The net effect is that it potentially reduces the memory used
          to represent the ABI being analyzed.

          Please note that for this property to be effective, the enclosing suppression specification must  have
          at   least   one   of   the   following   properties   specified:   name_regexp,   name,  name_regexp,
          source_location_not_in or source_location_not_regexp.

       • file_name_not_regexp

         Usage:
            file_name_not_regexp = <regular-expression>

         Suppresses change reports about ABI artifacts that are defined in a binary file  which  name  does  not
         match the regular expression specified as value of this property.

       • file_name_regexp

         Usage:
            file_name_regexp = <regular-expression>

         Suppresses  change reports about ABI artifacts that are defined in a binary file which name matches the
         regular expression specified as value of this property.

       • has_data_member

         Usage:
            has_data_member = <list-of-data-member-names>

       Suppresses change reports involving a type which contains data members whose names are  provided  in  the
       list value of this property.

       A usage examples of this property would be:

          has_data_member = {private_data_member0, private_data_member1}

       The  property  above  would  match  any  type  which  contains  at least two data members whose names are
       private_data_member0 and private_data_member1.

       Another usage examples of this property would be:

          has_data_member = another_private_data_member

       The  property  above  would  match  any   type   which   contains   a   data   member   which   name   is
       another_private_data_member0.

       • has_data_member_regexp

         Usage:
            has_data_member_regexp = <a-regular-expression>

       Suppresses  change  reports  involving  a  type which contains data members whose names match the regular
       expression provided as the value of this property.

       A usage examples of this property would be:

          has_data_member_regexp = ^private_data_member

       The property above would match any type which  contains  data  members  whose  names  match  the  regular
       expression  ^private_data_member.   In  other  words, it would match any type which contains data members
       whose names start with the string “private_data_member”.

       • has_data_member_inserted_at
          Usage:
              has_data_member_inserted_at = <offset-in-bit>

          Suppresses change reports involving a type which has at least one data member inserted  at  an  offset
          specified by the property value offset-in-bit.  Please note that if the size of the type changed, then
          the type change will NOT be suppressed by the evaluation of this property, unless the  has_size_change
          property is present and set to yes.

          The value offset-in-bit is either:

              • an integer value, expressed in bits, which denotes the offset of the insertion point of the data
                member, starting from the beginning of the relevant structure or class.

              • data member offset selector expressions, such as:

                   • the keyword end which is a named constant which value equals the offset of the end  of  the
                     structure or class.

                   • the  keyword  offset_of_flexible_array_data_member which is a named constant that evaluates
                     to the offset of the flexible array data member contained in the relevant structure.

                   • the function call expression offset_of(data-member-name) where data-member-name is the name
                     of a given data member of the relevant structure or class.  The value of this function call
                     expression is an integer  that  represents  the  offset  of  the  data  member  denoted  by
                     data-member-name.

                   • the  function  call expression offset_after(data-member-name) where data-member-name is the
                     name of a given data member of the relevant structure or class.  The value of this function
                     call  expression  is  an  integer  that represents the offset of the point that comes right
                     after the region occupied by the data member denoted by data-member-name.

                   • the function  call  expression  offset_of_first_data_member_regexp(data-member-name-regexp)
                     where data-member-name-regexp is a regular expression matching a data member.  The value of
                     this function call expression is an integer that represents the offset of  the  first  data
                     member  which  name  matches the regular expression argument.  If no data member of a given
                     class type matches the regular expression, then the class  type  won’t  match  the  current
                     directive.

                   • the  function  call  expression  offset_of_last_data_member_regexp(data-member-name-regexp)
                     where data-member-name-regexp is a regular expression matching a data member.  The value of
                     this  function  call  expression  is an integer that represents the offset of the last data
                     member which name matches the regular expression argument.  If no data member  of  a  given
                     class  type  matches  the  regular  expression, then the class type won’t match the current
                     directive.

       • has_data_member_inserted_between
          Usage:
              has_data_member_inserted_between = {<range-begin>, <range-end>}

          Suppresses change reports involving a type which has at least one data member inserted  at  an  offset
          that is comprised in the range between range-begin and range-end.  Please note that each of the values
          range-begin and range-end can be of the same form as the has_data_member_inserted_at  property  above.
          Please  also note that if the size of the type changed, then the type change will NOT be suppressed by
          the evaluation of this property, unless the has_size_change property is present and set to yes.   Note
          that  data member deletions happening in the range between range-begin and range-end won’t prevent the
          type change from being suppressed by the evaluation of this property if the size of the  type  doesn’t
          change or if the has_size_change property is present and set to yes.

          Usage examples of this properties are:

              has_data_member_inserted_between = {8, 64}

          or:

              has_data_member_inserted_between = {16, end}

          or:

              has_data_member_inserted_between = {offset_after(member1), end}

       • has_data_members_inserted_between
          Usage:
              has_data_members_inserted_between = {<sequence-of-ranges>}

          Suppresses  change  reports involving a type which has multiple data member inserted in various offset
          ranges.  A usage example of this property is, for instance:

              has_data_members_inserted_between = {{8, 31}, {72, 95}}

          This usage example suppresses change reports involving a type which has data members inserted  in  bit
          offset   ranges   [8   31]   and   [72   95].    The   length  of  the  sequence  of  ranges  or  this
          has_data_members_inserted_between is not bounded; it can be as long as the system can cope with.   The
          values  of  the  boundaries  of the ranges are of the same kind as for the has_data_member_inserted_at
          property above.  Please also note that if the size of the type changed, then  the  type  will  NOT  be
          suppressed  by the evaluation of this property, unless the has_size_change property is present and set
          to yes.  Note that data member deletions happening in the defined ranges won’t prevent the type change
          from  being suppressed by the evaluation of this property if the size of the type doesn’t change or if
          the has_size_change property is present and set to yes.

          Another usage example of this property is thus:

              has_data_members_inserted_between =
                {
                     {offset_after(member0), offset_of(member1)},
                     {72, end}
                }

       • has_strict_flexible_array_data_member_conversion
          Usage:
              has_strict_flexible_array_data_member_conversion = yes | no

          Suppresses change reports involving a type which has a “fake” flexible array member at the end of  the
          struct  which  is converted to a real flexible array member. This would be a member like data[1] being
          converted to data[].

          Please note that if the size of the type changed, then the type change will NOT be suppressed  by  the
          evaluation of this property, unless the has_size_change property is present and set to yes.

       • has_size_change
          Usage:
              has_size_change = yes | no

       This  property  is  to  be  used  in  conjunction  with  the properties has_data_member_inserted_between,
       has_data_members_inserted_between, and has_strict_flexible_array_data_member_conversion Those  properties
       will not match a type change if the size of the type changes, unless the has_size_changes property is set
       to yes.

       • label
          Usage:
              label = <some-value>

          Define a label for the section.  A label is just an informative string that might be used by a tool to
          refer to a type suppression in error messages.

       • name
          Usage:
              name = <a-value>

          Suppresses change reports involving types whose name equals the value of this property.

       • name_not_regexp
          Usage:
              name_not_regexp = <regular-expression>

          Suppresses  change  reports involving types whose name does NOT match the regular expression specified
          as value of this property.  Said otherwise, this property specifies which types to keep,  rather  than
          types to suppress from reports.

       • name_regexp
          Usage:
              name_regexp = <regular-expression>

          Suppresses change reports involving types whose name matches the regular expression specified as value
          of this property.

       • soname_not_regexp

         Usage:
            soname_not_regexp = <regular-expression>

         Suppresses change reports about ABI artifacts that  are  defined  in  a  shared  library  which  SONAME
         property does not match the regular expression specified as value of this property.

       • soname_regexp

         Usage:
            soname_regexp = <regular-expression>

         Suppresses  change  reports  about  ABI  artifacts  that  are  defined in a shared library which SONAME
         property matches the regular expression specified as value of this property.

       • source_location_not_in
          Usage:
              source_location_not_in = <list-of-file-paths>

          Suppresses change reports involving a type which is defined in a file which path is NOT listed in  the
          value  list-of-file-paths.   Note  that  the  value  is a comma-separated list of file paths e.g, this
          property

              source_location_not_in = libabigail/abg-ir.h, libabigail/abg-dwarf-reader.h

          suppresses change reports about all the types that are NOT defined in header files whose path  end  up
          with the strings libabigail/abg-ir.h or libabigail/abg-dwarf-reader.h.

       • source_location_not_regexp
          Usage:
              source_location_not_regexp = <regular-expression>

          Suppresses  change  reports  involving a type which is defined in a file which path does NOT match the
          regular expression provided as value of the property. E.g, this property

              source_location_not_regexp = libabigail/abg-.*\\.h

          suppresses change reports involving all the types that are NOT defined  in  header  files  whose  path
          match the regular expression provided a value of the property.

       • type_kind
          Usage:

              type_kind = class | struct | union | enum |
                     array | typedef | builtin

          Suppresses  change  reports  involving  a  certain  kind of type.  The kind of type to suppress change
          reports for is specified by the possible values listed above:

              •

                class: suppress change reports for class types. Note that
                       even if class types don’t exist for C, this  value  still  triggers  the  suppression  of
                       change reports for struct types, in C.  In C++ however, it should do what it suggests.

              •

                struct: suppress change reports for struct types in C or C++.
                       Note that the value class above is a super-set of this one.

              • union: suppress change reports for union types.

              • enum: suppress change reports for enum types.

              • array: suppress change reports for array types.

              • typedef: suppress change reports for typedef types.

              • builtin:  suppress change reports for built-in (or native) types.  Example of built-in types are
                char, int, unsigned int, etc.

   [suppress_function]
       This directive suppresses report messages about changes on a set of functions.

       Note that for the [suppress_function] directive to work, at least one of the following properties must be
       provided:
          label,  file_name_regexp,  file_name_not_regexp,  soname_regexp, soname_not_regexp, name, name_regexp,
          name_not_regexp, parameter,  return_type_name,  return_type_regexp,  symbol_name,  symbol_name_regexp,
          symbol_name_not_regexp, symbol_version, symbol_version_regexp.

       If none of the above properties are provided, then the [suppress_function] directive is simply ignored.

       The potential properties of this sections are:

       • change_kind
          Usage:
              change_kind = <predefined-possible-values>

          Specifies  the kind of changes this suppression specification should apply to.  The possible values of
          this property as well as their meaning are listed below:

              • function-subtype-change

                This suppression specification applies to functions that which have at least one  sub-type  that
                has changed.

              • added-function

                This suppression specification applies to functions that have been added to the binary.

              • deleted-function

                This suppression specification applies to functions that have been removed from the binary.

              • all

                This  suppression  specification  applies to functions that have all of the changes above.  Note
                that not providing the change_kind property at all is equivalent to setting it to the value all.

       • drop
          Usage:
              drop = yes | no

          If a function is matched by a suppression specification which contains  the  “drop”  property  set  to
          “yes”  (or  to  “true”)  then  the  function  is  not  even  going  to  be represented in the internal
          representation of the ABI being analyzed.  This property makes its enclosing suppression specification
          to  be  applied  in  the  early suppression specification mode.  The net effect is that it potentially
          reduces the memory used to represent the ABI being analyzed.

          Please note that for this property to be effective, the enclosing suppression specification must  have
          at   least   one   of   the   following   properties   specified:   name_regexp,   name,  name_regexp,
          source_location_not_in or source_location_not_regexp.

       • file_name_not_regexp

         Usage:
            file_name_not_regexp = <regular-expression>

         Suppresses change reports about ABI artifacts that are defined in a binary file  which  name  does  not
         match the regular expression specified as value of this property.

       • file_name_regexp

         Usage:

         file_name_regexp = <regular-expression>

         Suppresses  change reports about ABI artifacts that are defined in a binary file which name matches the
         regular expression specified as value of this property.

       • label
          Usage:
              label = <some-value>

          This property is the same as the label property defined above.

       • name
          Usage:
              name = <some-value>

          Suppresses change reports involving functions whose name equals the value of this property.

       • name_not_regexp
          Usage:
              name_not_regexp = <regular-expression>

          Suppresses change reports involving functions whose names don’t match the regular expression specified
          as value of this property.

          The  rules  for  functions  that  have  several symbol names are the same rules as for the name_regexp
          property above.

       • name_regexp
          Usage:
              name_regexp = <regular-expression>

          Suppresses change reports involving functions whose name matches the regular expression  specified  as
          value of this property.

          Let’s consider the case of functions that have several symbol names.  This happens when the underlying
          symbol for the function has aliases.  Each symbol name is actually one alias name.

          In this case, if the regular expression matches the name of at least one of the aliases names, then it
          must  match the names of all of the aliases of the function for the directive to actually suppress the
          diff reports for said function.

       • parameter
          Usage:
              parameter = <function-parameter-specification>

          Suppresses change reports involving functions  whose  parameters  match  the  parameter  specification
          indicated as value of this property.

          The format of the function parameter specification is:

          ' <parameter-index> <space> <type-name-or-regular-expression>

          That  is,  an  apostrophe  followed by a number that is the index of the parameter, followed by one of
          several spaces, followed by either the name of the type of the  parameter,  or  a  regular  expression
          describing a family of parameter type names.

          If the parameter type name is designated by a regular expression, then said regular expression must be
          enclosed between two slashes; like /some-regular-expression/.

          The index of the first parameter of the function is zero.  Note that for member functions (methods  of
          classes), the this is the first parameter that comes after the implicit “this” pointer parameter.

          Examples of function parameter specifications are:

              '0 int

          Which means, the parameter at index 0, whose type name is int.

              '4 unsigned char*

          Which means, the parameter at index 4, whose type name is unsigned char*.

              '2 /^foo.*&/

          Which  means,  the parameter at index 2, whose type name starts with the string “foo” and ends with an
          ‘&’.  In other words, this is the third parameter and it’s a reference on a type that starts with  the
          string “foo”.

       • return_type_name
          Usage:
              return_type_name = <some-value>

          Suppresses  change  reports  involving  functions  whose  return  type  name  equals the value of this
          property.

       • return_type_regexp
          Usage:
              return_type_regexp = <regular-expression>

          Suppresses change reports involving functions whose return type name matches  the  regular  expression
          specified as value of this property.

       • soname_regexp

         Usage:
            soname_regexp = <regular-expression>

         Suppresses  change  reports  about  ABI  artifacts  that  are  defined in a shared library which SONAME
         property matches the regular expression specified as value of this property.

       • soname_not_regexp

         Usage:
            soname_not_regexp = <regular-expression>

         Suppresses change reports about ABI artifacts that  are  defined  in  a  shared  library  which  SONAME
         property does not match the regular expression specified as value of this property.

       • symbol_name
          Usage:
              symbol_name = <some-value>

          Suppresses change reports involving functions whose symbol name equals the value of this property.

       • symbol_name_regexp
          Usage:
              symbol_name_regexp = <regular-expression>

          Suppresses  change  reports  involving  functions  whose  symbol  name  matches the regular expression
          specified as value of this property.

          Let’s consider the case of functions that have several symbol names.  This happens when the underlying
          symbol for the function has aliases.  Each symbol name is actually one alias name.

          In  this  case,  the regular expression must match the names of all of the aliases of the function for
          the directive to actually suppress the diff reports for said function.

       • symbol_name_not_regexp
          Usage:
              symbol_name_not_regexp = <regular-expression>

          Suppresses change reports involving functions whose symbol name does not match the regular  expression
          specified as value of this property.

       • symbol_version
          Usage:
              symbol_version = <some-value>

          Suppresses change reports involving functions whose symbol version equals the value of this property.

       • symbol_version_regexp
          Usage:
              symbol_version_regexp = <regular-expression>

          Suppresses  change  reports  involving  functions  whose symbol version matches the regular expression
          specified as value of this property.

   [suppress_variable]
       This directive suppresses report messages about changes on a set of variables.

       Note that for the [suppress_variable] directive to work, at least one of the following properties must be
       provided:
          label,  file_name_regexp,  file_name_not_regexp,  soname_regexp, soname_not_regexp, name, name_regexp,
          name_not_regexp,    symbol_name,    symbol_name_regexp,    symbol_name_not_regexp,     symbol_version,
          symbol_version_regexp, type_name, type_name_regexp.

       If none of the above properties are provided, then the [suppress_variable] directive is simply ignored.

       The potential properties of this sections are:

       • label
          Usage:
              label = <some-value>

          This property is the same as the label property defined above.

       • file_name_regexp

         Usage:

         file_name_regexp = <regular-expression>

         Suppresses  change reports about ABI artifacts that are defined in a binary file which name matches the
         regular expression specified as value of this property.

       • file_name_not_regexp

         Usage:
            file_name_not_regexp = <regular-expression>

         Suppresses change reports about ABI artifacts that are defined in a binary file  which  name  does  not
         match the regular expression specified as value of this property.

       • soname_regexp

         Usage:
            soname_regexp = <regular-expression>

         Suppresses  change  reports  about  ABI  artifacts  that  are  defined in a shared library which SONAME
         property matches the regular expression specified as value of this property.

       • soname_not_regexp

         Usage:
            soname_not_regexp = <regular-expression>

         Suppresses change reports about ABI artifacts that  are  defined  in  a  shared  library  which  SONAME
         property does not match the regular expression specified as value of this property.

       • name
          Usage:
              name = <some-value>

          Suppresses change reports involving variables whose name equals the value of this property.

       • name_regexp
          Usage:
              name_regexp = <regular-expression>

          Suppresses  change  reports involving variables whose name matches the regular expression specified as
          value of this property.

       • change_kind
          Usage:
              change_kind = <predefined-possible-values>

          Specifies the kind of changes this suppression specification should apply to.  The possible values  of
          this  property  as  well  as  their  meaning are the same as when it’s used in the [suppress_function]
          section.

       • symbol_name
          Usage:
              symbol_name = <some-value>

          Suppresses change reports involving variables whose symbol name equals the value of this property.

       • symbol_name_regexp
          Usage:
              symbol_name_regexp = <regular-expression>

          Suppresses change reports involving  variables  whose  symbol  name  matches  the  regular  expression
          specified as value of this property.

       • symbol_name_not_regexp
          Usage:
              symbol_name_not_regexp = <regular-expression>

          Suppresses  change reports involving variables whose symbol name does not match the regular expression
          specified as value of this property.

       • symbol_version
          Usage:
              symbol_version = <some-value>

          Suppresses change reports involving variables whose symbol version equals the value of this property.

       • symbol_version_regexp
          Usage:
              symbol_version_regexp = <regular-expression>

          Suppresses change reports involving variables whose symbol  version  matches  the  regular  expression
          specified as value of this property.

       • type_name
          Usage:
              type_name = <some-value>

          Suppresses change reports involving variables whose type name equals the value of this property.

       • type_name_regexp
          Usage:
              type_name_regexp = <regular-expression>

          Suppresses change reports involving variables whose type name matches the regular expression specified
          as value of this property.

   Comments
       ; or # ASCII character at the beginning of a line indicates a comment.  Comment lines are ignored.

   Code examples
       1. Suppressing change reports about types.

          Suppose we have a library named libtest1-v0.so which contains this very useful code:

             $ cat -n test1-v0.cc
                  1  // A forward declaration for a type considered to be opaque to
                  2  // function foo() below.
                  3  struct opaque_type;
                  4
                  5  // This function cannot touch any member of opaque_type.  Hence,
                  6  // changes to members of opaque_type should not impact foo, as far as
                  7  // ABI is concerned.
                  8  void
                  9  foo(opaque_type*)
                 10  {
                 11  }
                 12
                 13  struct opaque_type
                 14  {
                 15    int member0;
                 16    char member1;
                 17  };
             $

       Let’s change the layout of struct opaque_type by inserting a data member around line 15, leading to a new
       version of the library, that we shall name libtest1-v1.so:

          $ cat -n test1-v1.cc
               1  // A forward declaration for a type considered to be opaque to
               2  // function foo() below.
               3  struct opaque_type;
               4
               5  // This function cannot touch any member of opaque_type;  Hence,
               6  // changes to members of opaque_type should not impact foo, as far as
               7  // ABI is concerned.
               8  void
               9  foo(opaque_type*)
              10  {
              11  }
              12
              13  struct opaque_type
              14  {
              15    char added_member; // <-- a new member got added here now.
              16    int member0;
              17    char member1;
              18  };
          $

       Let’s  compile  both  examples.   We  shall  not forget to compile them with debug information generation
       turned on:

          $ g++ -shared -g -Wall -o libtest1-v0.so test1-v0.cc
          $ g++ -shared -g -Wall -o libtest1-v1.so test1-v1.cc

       Let’s ask abidiff which ABI differences it sees between libtest1-v0.so and libtest1-v1.so:

          $ abidiff libtest1-v0.so libtest1-v1.so
          Functions changes summary: 0 Removed, 1 Changed, 0 Added function
          Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

          1 function with some indirect sub-type change:

            [C]'function void foo(opaque_type*)' has some indirect sub-type changes:
              parameter 0 of type 'opaque_type*' has sub-type changes:
                in pointed to type 'struct opaque_type':
                  size changed from 64 to 96 bits
                  1 data member insertion:
                    'char opaque_type::added_member', at offset 0 (in bits)
                  2 data member changes:
                   'int opaque_type::member0' offset changed from 0 to 32
                   'char opaque_type::member1' offset changed from 32 to 64

       So abidiff reports that the opaque_type’s layout has  changed  in  a  significant  way,  as  far  as  ABI
       implications  are  concerned,  in  theory.   After  all,  a  sub-type (struct opaque_type) of an exported
       function (foo()) has seen its layout change.  This might have non negligible ABI  implications.   But  in
       practice  here,  the  programmer  of the litest1-v1.so library knows that the “soft” contract between the
       function foo() and the type struct opaque_type is to stay away from the data members  of  the  type.   So
       layout changes of struct opaque_type should not impact foo().

       Now  to teach abidiff about this soft contract and have it avoid emitting what amounts to false positives
       in this case, we write the suppression specification file below:

          $ cat test1.suppr
          [suppress_type]
            type_kind = struct
            name = opaque_type

       Translated in plain English, this suppression specification would read: “Do not emit change reports about
       a struct which name is opaque_type”.

       Let’s  now  invoke  abidiff  on the two versions of the library again, but this time with the suppression
       specification:

          $ abidiff --suppressions test1.suppr libtest1-v0.so libtest1-v1.so
          Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
          Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

       As you can see, abidiff does not report the change anymore; it tells us that it was filtered out instead.

       Suppressing change reports about types with data member insertions

       Suppose the first version of a library named libtest3-v0.so has this source code:

          /* Compile this with:
               gcc -g -Wall -shared -o libtest3-v0.so test3-v0.c
           */

          struct S
          {
            char member0;
            int member1; /*
                            between member1 and member2, there is some padding,
                            at least on some popular platforms.  On
                            these platforms, adding a small enough data
                            member into that padding shouldn't change
                            the offset of member1.  Right?
                          */
          };

          int
          foo(struct S* s)
          {
            return s->member0 + s->member1;
          }

       Now, suppose the second version of the library named libtest3-v1.so has this source code in which a  data
       member has been added in the padding space of struct S and another data member has been added at its end:

          /* Compile this with:
               gcc -g -Wall -shared -o libtest3-v1.so test3-v1.c
           */

          struct S
          {
            char member0;
            char inserted1; /* <---- A data member has been added here...  */
            int member1;
            char inserted2; /* <---- ... and another one has been added here.  */
          };

          int
          foo(struct S* s)
          {
            return s->member0 + s->member1;
          }

       In  libtest3-v1.so,  adding  char  data  members S::inserted1 and S::inserted2 can be considered harmless
       (from an ABI compatibility perspective), at least on the x86 platform, because that  doesn’t  change  the
       offsets of the data members S::member0 and S::member1.  But then running abidiff on these two versions of
       library yields:

          $ abidiff libtest3-v0.so libtest3-v1.so
          Functions changes summary: 0 Removed, 1 Changed, 0 Added function
          Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

          1 function with some indirect sub-type change:

            [C]'function int foo(S*)' has some indirect sub-type changes:
              parameter 0 of type 'S*' has sub-type changes:
                in pointed to type 'struct S':
                  type size changed from 64 to 96 bits
                  2 data member insertions:
                    'char S::inserted1', at offset 8 (in bits)
                    'char S::inserted2', at offset 64 (in bits)
          $

       That is, abidiff shows us the two changes, even though we (the developers of that very involved  library)
       know that these changes are harmless in this particular context.

       Luckily,  we  can  devise a suppression specification that essentially tells abidiff to filter out change
       reports about adding a data member between S::member0 and S::member1, and adding a data member at the end
       of  struct  S.   We  have  written such a suppression specification in a file called test3-1.suppr and it
       unsurprisingly looks like:

          [suppress_type]
            name = S
            has_data_member_inserted_between = {offset_after(member0), offset_of(member1)}
            has_data_member_inserted_at = end

       Now running abidiff with this suppression specification yields:

          $ ../build/tools/abidiff --suppressions test3-1.suppr libtest3-v0.so libtest3-v1.so
          Functions changes summary: 0 Removed, 0 Changed (1 filtered out), 0 Added function
          Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

          $

       Hooora! \o/ (I guess)

       Suppressing change reports about types accessed either directly or through pointers

       Suppose we have a first version of an object file which source code is the file widget-v0.cc below:

          // Compile with: g++ -g -c widget-v0.cc

          struct widget
          {
            int x;
            int y;

            widget()
              :x(), y()
            {}
          };

          void
          fun0(widget*)
          {
            // .. do stuff here.
          }

          void
          fun1(widget&)
          {
            // .. do stuff here ..
          }

          void
          fun2(widget w)
          {
            // ... do other stuff here ...
          }

       Now suppose in the second version of that file, named widget-v1.cc, we have added some  data  members  at
       the end of the type struct widget; here is what the content of that file would look like:

          // Compile with: g++ -g -c widget-v1.cc

          struct widget
          {
            int x;
            int y;
            int w; // We have added these two new data members here ..
            int h; // ... and here.

            widget()
              : x(), y(), w(), h()
            {}
          };

          void
          fun0(widget*)
          {
            // .. do stuff here.
          }

          void
          fun1(widget&)
          {
            // .. do stuff here ..
          }

          void
          fun2(widget w)
          {
            // ... do other stuff here ...
          }

       When  we invoke abidiff on the object files resulting from the compilation of the two file above, here is
       what we get:

           $ abidiff widget-v0.o widget-v1.o
           Functions changes summary: 0 Removed, 2 Changed (1 filtered out), 0 Added functions
           Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

           2 functions with some indirect sub-type change:

             [C]'function void fun0(widget*)' has some indirect sub-type changes:
               parameter 1 of type 'widget*' has sub-type changes:
                 in pointed to type 'struct widget':
                   type size changed from 64 to 128 bits
                   2 data member insertions:
                     'int widget::w', at offset 64 (in bits)
                     'int widget::h', at offset 96 (in bits)

             [C]'function void fun2(widget)' has some indirect sub-type changes:
               parameter 1 of type 'struct widget' has sub-type changes:
                 details were reported earlier
          $

       I guess a little bit of explaining is due here.  abidiff detects that two data member got  added  at  the
       end  of  struct widget.  it also tells us that the type change impacts the exported function fun0() which
       uses the type struct widget through a pointer, in its signature.

       Careful readers will notice that the change to struct widget also impacts the exported  function  fun1(),
       that  uses  type struct widget through a reference.  But then abidiff doesn’t tell us about the impact on
       that function fun1() because it has evaluated that change as being redundant with the change it  reported
       on fun0().  It has thus filtered it out, to avoid cluttering the output with noise.

       Redundancy  detection  and  filtering is fine and helpful to avoid burying the important information in a
       sea of noise.  However, it must be treated with care, by fear of mistakenly filtering  out  relevant  and
       important information.

       That  is  why  abidiff tells us about the impact that the change to struct widget has on function fun2().
       In this case, that function uses the type struct widget directly (in its signature).  It does not use  it
       via a pointer or a reference.  In this case, the direct use of this type causes fun2() to be exposed to a
       potentially harmful ABI change.  Hence, the report about fun2() is not filtered  out,  even  though  it’s
       about that same change on struct widget.

       To  go further in suppressing reports about changes that are harmless and keeping only those that we know
       are harmful, we would like to go tell abidiff to suppress reports about  this  particular  struct  widget
       change  when  it  impacts uses of struct widget through a pointer or reference.  In other words, suppress
       the change reports about fun0() and fun1().  We would then write this suppression specification, in  file
       widget.suppr:

          [suppress_type]
            name = widget
            type_kind = struct
            has_data_member_inserted_at = end
            accessed_through = reference-or-pointer

            # So this suppression specification says to suppress reports about
            # the type 'struct widget', if this type was added some data member
            # at its end, and if the change impacts uses of the type through a
            # reference or a pointer.

       Invoking abidiff on widget-v0.o and widget-v1.o with this suppression specification yields:

          $ abidiff --suppressions widget.suppr widget-v0.o widget-v1.o
          Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
          Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

          1 function with some indirect sub-type change:

            [C]'function void fun2(widget)' has some indirect sub-type changes:
              parameter 1 of type 'struct widget' has sub-type changes:
                type size changed from 64 to 128 bits
                2 data member insertions:
                  'int widget::w', at offset 64 (in bits)
                  'int widget::h', at offset 96 (in bits)
          $

       As expected, I guess.

       Suppressing change reports about functions.

       Suppose we have a first version a library named libtest2-v0.so whose source code is:

           $ cat -n test2-v0.cc

            1     struct S1
            2     {
            3       int m0;
            4
            5       S1()
            6         : m0()
            7       {}
            8     };
            9
           10     struct S2
           11     {
           12       int m0;
           13
           14       S2()
           15         : m0()
           16       {}
           17     };
           18
           19     struct S3
           20     {
           21       int m0;
           22
           23       S3()
           24         : m0()
           25       {}
           26     };
           27
           28     int
           29     func(S1&)
           30     {
           31       // suppose the code does something with the argument.
           32       return 0;
           33
           34     }
           35
           36     char
           37     func(S2*)
           38     {
           39       // suppose the code does something with the argument.
           40       return 0;
           41     }
           42
           43     unsigned
           44     func(S3)
           45     {
           46       // suppose the code does something with the argument.
           47       return 0;
           48     }
          $

       And  then we come up with a second version libtest2-v1.so of that library; the source code is modified by
       making the structures S1, S2, S3 inherit another struct:

          $ cat -n test2-v1.cc
                1 struct base_type
                2 {
                3   int m_inserted;
                4 };
                5
                6 struct S1 : public base_type // <--- S1 now has base_type as its base
                7                              // type.
                8 {
                9   int m0;
               10
               11   S1()
               12     : m0()
               13   {}
               14 };
               15
               16 struct S2 : public base_type // <--- S2 now has base_type as its base
               17                              // type.
               18 {
               19   int m0;
               20
               21   S2()
               22     : m0()
               23   {}
               24 };
               25
               26 struct S3 : public base_type // <--- S3 now has base_type as its base
               27                              // type.
               28 {
               29   int m0;
               30
               31   S3()
               32     : m0()
               33   {}
               34 };
               35
               36 int
               37 func(S1&)
               38 {
               39   // suppose the code does something with the argument.
               40   return 0;
               41
               42 }
               43
               44 char
               45 func(S2*)
               46 {
               47   // suppose the code does something with the argument.
               48   return 0;
               49 }
               50
               51 unsigned
               52 func(S3)
               53 {
               54   // suppose the code does something with the argument.
               55   return 0;
               56 }
           $

       Now let’s build the two libraries:

          g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc
          g++ -Wall -g -shared -o libtest2-v0.so test2-v0.cc

       Let’s look at the output of abidiff:

          $ abidiff libtest2-v0.so libtest2-v1.so
          Functions changes summary: 0 Removed, 3 Changed, 0 Added functions
          Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

          3 functions with some indirect sub-type change:

            [C]'function unsigned int func(S3)' has some indirect sub-type changes:
              parameter 0 of type 'struct S3' has sub-type changes:
                size changed from 32 to 64 bits
                1 base class insertion:
                  struct base_type
                1 data member change:
                 'int S3::m0' offset changed from 0 to 32

            [C]'function char func(S2*)' has some indirect sub-type changes:
              parameter 0 of type 'S2*' has sub-type changes:
                in pointed to type 'struct S2':
                  size changed from 32 to 64 bits
                  1 base class insertion:
                    struct base_type
                  1 data member change:
                   'int S2::m0' offset changed from 0 to 32

            [C]'function int func(S1&)' has some indirect sub-type changes:
              parameter 0 of type 'S1&' has sub-type changes:
                in referenced type 'struct S1':
                  size changed from 32 to 64 bits
                  1 base class insertion:
                    struct base_type
                  1 data member change:
                   'int S1::m0' offset changed from 0 to 32
          $

       Let’s tell abidiff to avoid showing us the differences on the overloads  of  func  that  takes  either  a
       pointer or a reference.  For that, we author this simple suppression specification:

          $ cat -n libtest2.suppr
               1 [suppress_function]
               2   name = func
               3   parameter = '0 S1&
               4
               5 [suppress_function]
               6   name = func
               7   parameter = '0 S2*
          $

       And then let’s invoke abidiff with the suppression specification:

          $ ../build/tools/abidiff --suppressions libtest2.suppr libtest2-v0.so libtest2-v1.so
          Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
          Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

          1 function with some indirect sub-type change:

                 [C]'function unsigned int func(S3)' has some indirect sub-type changes:
                   parameter 0 of type 'struct S3' has sub-type changes:
                     size changed from 32 to 64 bits
                     1 base class insertion:
                       struct base_type
                     1 data member change:
                      'int S3::m0' offset changed from 0 to 32

       The suppression specification could be reduced using regular expressions:

          $ cat -n libtest2-1.suppr
                    1   [suppress_function]
                    2     name = func
                    3     parameter = '0 /^S.(&|\\*)/
          $

          $ ../build/tools/abidiff --suppressions libtest2-1.suppr libtest2-v0.so libtest2-v1.so
          Functions changes summary: 0 Removed, 1 Changed (2 filtered out), 0 Added function
          Variables changes summary: 0 Removed, 0 Changed, 0 Added variable

          1 function with some indirect sub-type change:

                 [C]'function unsigned int func(S3)' has some indirect sub-type changes:
                   parameter 0 of type 'struct S3' has sub-type changes:
                     size changed from 32 to 64 bits
                     1 base class insertion:
                       struct base_type
                     1 data member change:
                      'int S3::m0' offset changed from 0 to 32

          $

AUTHOR

       Dodji Seketeli

COPYRIGHT

       2014-2024, Red Hat, Inc.

                                                  Mar 31, 2024                                     LIBABIGAIL(7)