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)