.\" Man page generated from reStructuredText. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "LIBABIGAIL" "7" "Mar 13, 2024" "" "Libabigail" .SH NAME libabigail \- Library to analyze and compare ELF ABIs .SH OVERVIEW OF THE ABIGAIL FRAMEWORK .sp \fBABIGAIL\fP stands for the Application Binary Interface Generic Analysis and Instrumentation Library. .sp It’s a framework which aims at helping developers and software distributors to spot some ABI\-related issues like interface incompatibility in \fI\%ELF\fP shared libraries by performing a static analysis of the \fI\%ELF\fP binaries at hand. .sp The type of interface incompatibilities that \fBAbigail\fP 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. .sp 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 \fBAbigail\fP to help people catch that. .sp In more concrete terms, the Abigail framwork provides a shared library named \fBlibabigail\fP which exposes an API to parse a shared library in \fI\%ELF\fP format (accompanied with its associated debug information in \fI\%DWARF\fP format) build an internal representation of all the functions and variables it exports, along with their types. \fBLibabigail\fP also builds an internal representation of the \fI\%ELF symbols\fP 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 \fBLibabigail\fP\&. .sp Aside of this internal representation, \fBlibabigail\fP 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. .sp This allows us to write tools like \fI\%abidiff\fP 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 \fI\%other tools\fP that are built using the \fBAbigail\fP framwork. .SH TOOLS .SS Overview .sp 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. .SS Tools manuals .SS abidiff .sp abidiff compares the Application Binary Interfaces (ABI) of two shared libraries in \fI\%ELF\fP format. It emits a meaningful report describing the differences between the two ABIs. .sp This tool can also compare the textual representations of the ABI of two ELF binaries (as emitted by \fBabidw\fP) or an ELF binary against a textual representation of another ELF binary. .sp For a comprehensive ABI change report between two input shared libraries that includes changes about function and variable sub\-types, \fBabidiff\fP uses by default, debug information in \fI\%DWARF\fP format, if present, otherwise it compares interfaces using debug information in \fI\%CTF\fP or \fI\%BTF\fP formats, if present. Finally, if no debug info in these formats is found, it only considers \fI\%ELF\fP symbols and report about their addition or removal. .sp This tool uses the libabigail library to analyze the binary as well as its associated debug information. Here is its general mode of operation. .sp 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 \fI\%ELF\fP 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. .sp Libabigail then has capabilities to generate textual representations of ABI Corpora, compare them, analyze their changes and report about them. .SS Invocation .INDENT 0.0 .INDENT 3.5 .sp .EX abidiff [options] .EE .UNINDENT .UNINDENT .SS Environment .sp abidiff loads two default \fI\%suppression specifications files\fP, merges their content and use it to filter out ABI change reports that might be considered as false positives to users. .INDENT 0.0 .IP \(bu 2 Default system\-wide suppression specification file .sp 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. .IP \(bu 2 Default user suppression specification file. .sp 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. .UNINDENT .SS Options .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fB\-\-help | \-h\fP .sp Display a short help about the command and exit. .IP \(bu 2 \fB\-\-debug\-self\-comparison\fP .sp In this mode, error messages are emitted for types which fail type canonicalization, in some circumstances, when comparing a binary against itself. .sp 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. .sp 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. .IP \(bu 2 \fB\-\-debug\-tc\fP .sp 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. .sp 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. .IP \(bu 2 \fB\-\-version | \-v\fP .sp Display the version of the program and exit. .IP \(bu 2 \fB\-\-debug\-info\-dir1 | \-\-d1\fP <\fIdi\-path1\fP> .sp For cases where the debug information for \fIfirst\-shared\-library\fP is split out into a separate file, tells \fBabidiff\fP where to find that separate debug information file. .sp Note that \fIdi\-path\fP 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 \fB/usr/lib/debug\fP\&. .sp This option can be provided several times with different root directories. In that case, \fBabidiff\fP will potentially look into all those root directories to find the split debug info for \fIfirst\-shared\-library\fP\&. .sp Note also that this option is not mandatory for split debug information installed by your system’s package manager because then \fBabidiff\fP knows where to find it. .IP \(bu 2 \fB\-\-debug\-info\-dir2 | \-\-d2\fP <\fIdi\-path2\fP> .sp Like \fB\-\-debug\-info\-dir1\fP, this options tells \fBabidiff\fP where to find the split debug information for the \fIsecond\-shared\-library\fP file. .sp This option can be provided several times with different root directories. In that case, \fBabidiff\fP will potentially look into all those root directories to find the split debug info for \fIsecond\-shared\-library\fP\&. .IP \(bu 2 \fB\-\-headers\-dir1 | \-\-hd1\fP .sp 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. .sp Note that several public header directories can be specified for the first shared library. In that case the \fB\-\-headers\-dir1\fP option should be present several times on the command line, like in the following example: .INDENT 2.0 .INDENT 3.5 .sp .EX $ abidiff \-\-headers\-dir1 /some/path \e \-\-headers\-dir1 /some/other/path \e binary\-version\-1 binary\-version\-2 .EE .UNINDENT .UNINDENT .IP \(bu 2 \fB\-\-header\-file1 | \-\-hf1\fP .sp 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. .IP \(bu 2 \fB\-\-headers\-dir2 | \-\-hd2\fP .sp 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. .sp Note that several public header directories can be specified for the second shared library. In that case the \fB\-\-headers\-dir2\fP option should be present several times like in the following example: .INDENT 2.0 .INDENT 3.5 .sp .EX $ abidiff \-\-headers\-dir2 /some/path \e \-\-headers\-dir2 /some/other/path \e binary\-version\-1 binary\-version\-2 .EE .UNINDENT .UNINDENT .IP \(bu 2 \fB\-\-header\-file2 | \-\-hf2\fP .sp 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. .IP \(bu 2 \fB\-\-add\-binaries1\fP <\fIbin1,bin2,bin3,..\fP> .sp For each of the comma\-separated binaries given in argument to this option, if the binary is found in the directory specified by the \fB\-\-added\-binaries\-dir1\fP option, then \fBabidiff\fP 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 \fBabidiff\fP\&. .sp That ABI corpus group is then compared against the second corpus group given in argument to \fBabidiff\fP\&. .IP \(bu 2 \fB\-\-add\-binaries2\fP <\fIbin1,bin2,bin3,..\fP> .sp For each of the comma\-separated binaries given in argument to this option, if the binary is found in the directory specified by the \fB\-\-added\-binaries\-dir2\fP option, then \fBabidiff\fP 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 \fBabidiff\fP\&. .sp That ABI corpus group is then compared against the first corpus group given in argument to \fBabidiff\fP\&. .IP \(bu 2 \fB\-\-follow\-dependencies | \-\-fdeps\fP .sp For each dependency of the first argument of \fBabidiff\fP, if it’s found in the directory specified by the \fB\-\-added\-binaries\-dir1\fP 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 \fBabidiff\fP\&. .sp Similarly, for each dependency of the second argument of \fBabidiff\fP, if it’s found in the directory specified by the \fB\-\-added\-binaries\-dir2\fP option, then construct an ABI corpus out of the dependency, add it to an ABI corpus group that includes the second argument of \fBabidiff\fP\&. .sp These two ABI corpus groups are then compared against each other. .sp Said otherwise, this makes \fBabidiff\fP compare the set of its first input and its dependencies against the set of its second input and its dependencies. .IP \(bu 2 \fBlist\-dependencies | \-\-ldeps\fP .sp This option lists all the dependencies of the input arguments of \fBabidiff\fP that are found in the directories specified by the options \fB\-\-added\-binaries\-dir1\fP and \fB\-\-added\-binaries\-dir2\fP .IP \(bu 2 \fB\-\-added\-binaries\-dir1 | \-\-abd1\fP .sp This option is to be used in conjunction with the \fB\-\-add\-binaries1\fP, \fB\-\-follow\-dependencies\fP and \fB\-\-list\-dependencies\fP options. Binaries referred to by these options, if found in the directory \fIadded\-binaries\-directory\-1\fP, are loaded as ABI corpus and are added to the first ABI corpus group that is to be used in the comparison. .IP \(bu 2 \fB\-\-added\-binaries\-dir2 | \-\-abd2\fP .sp This option is to be used in conjunction with the \fB\-\-add\-binaries2\fP, \fB\-\-follow\-dependencies\fP and \fB\-\-list\-dependencies\fP options. Binaries referred to by these options, if found in the directory \fIadded\-binaries\-directory\-2\fP, are loaded as ABI corpus and are added to the second ABI corpus group to be used in the comparison. .IP \(bu 2 \fB\-\-no\-linux\-kernel\-mode\fP .sp 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. .sp 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. .IP \(bu 2 \fB\-\-kmi\-whitelist | \-kaw\fP <\fIpath\-to\-whitelist\fP> .sp 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 \fBABI\fP; we rather talk about the interface between the Kernel and its module. Hence the term \fBKMI\fP rather than \fBABI\fP\&. .sp Any other function or variable which ELF symbol are not present in that white list will not be considered by this tool. .sp 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. .IP \(bu 2 \fB\-\-drop\-private\-types\fP .sp This option is to be used with the \fB\-\-headers\-dir1\fP, \fBheader\-file1\fP, \fBheader\-file2\fP and \fB\-\-headers\-dir2\fP options. With this option, types that are \fINOT\fP 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. .sp Without this option however, those private types are kept in the internal representation and later filtered out from the report. .sp 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. .IP \(bu 2 \fB\-\-exported\-interfaces\-only\fP .sp 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 \fI\%ELF\fP symbols that are defined and exported by the binary. It’s those final ABI Corpora that are compared by this tool. .sp 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 \fI\%Linux Kernel\fP\&. Analyzing massive ABI corpora like these can be extremely slow. .sp To mitigate that performance issue, this option allows libabigail to only analyze types that are reachable from interfaces associated with defined and exported \fI\%ELF\fP symbols. .sp Note that this option is turned on by default when analyzing the \fI\%Linux Kernel\fP\&. Otherwise, it’s turned off by default. .IP \(bu 2 \fB\-\-allow\-non\-exported\-interfaces\fP .sp 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 \fI\%ELF\fP symbols that are defined and exported by the binary. It’s those final ABI Corpora that are compared by this tool. .sp 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 \fI\%Linux Kernel\fP\&. Analyzing massive ABI Corpora like these can be extremely slow. .sp 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. .sp Note that this option is turned on by default, unless we are in the presence of the \fI\%Linux Kernel\fP\&. .IP \(bu 2 \fB\-\-stat\fP .sp Rather than displaying the detailed ABI differences between \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP, just display some summary statistics about these differences. .IP \(bu 2 \fB\-\-symtabs\fP .sp Only display the symbol tables of the \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP\&. .IP \(bu 2 \fB\-\-deleted\-fns\fP .sp In the resulting report about the differences between \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP, only display the globally defined functions that got deleted from \fIfirst\-shared\-library\fP\&. .IP \(bu 2 \fB\-\-changed\-fns\fP .sp In the resulting report about the differences between \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP, only display the changes in sub\-types of the global functions defined in \fIfirst\-shared\-library\fP\&. .IP \(bu 2 \fB\-\-added\-fns\fP .sp In the resulting report about the differences between \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP, only display the globally defined functions that were added to \fIsecond\-shared\-library\fP\&. .IP \(bu 2 \fB\-\-deleted\-vars\fP .sp In the resulting report about the differences between \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP, only display the globally defined variables that were deleted from \fIfirst\-shared\-library\fP\&. .IP \(bu 2 \fB\-\-changed\-vars\fP .sp In the resulting report about the differences between \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP, only display the changes in the sub\-types of the global variables defined in \fIfirst\-shared\-library\fP .IP \(bu 2 \fB\-\-added\-vars\fP .sp In the resulting report about the differences between \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP, only display the global variables that were added (defined) to \fIsecond\-shared\-library\fP\&. .IP \(bu 2 \fB\-\-non\-reachable\-types|\-t\fP .sp Analyze and emit change reports for all the types of the binary, including those that are not reachable from global functions and variables. .sp This option might incur some serious performance degradation as the number of types analyzed can be huge. However, if paired with the \fB\-\-headers\-dir{1,2}\fP and/or \fBheader\-file{1,2}\fP options, the additional non\-reachable types analyzed are restricted to those defined in public headers files, thus hopefully making the performance hit acceptable. .sp Also, using this option alongside suppression specifications (by also using the \fB\-\-suppressions\fP option) might help keep the number of analyzed types (and the potential performance degradation) in control. .sp 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. .IP \(bu 2 \fB\-\-no\-added\-syms\fP .sp In the resulting report about the differences between \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP, 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. .IP \(bu 2 \fB\-\-no\-linkage\-name\fP .sp In the resulting report, do not display the linkage names of the added, removed, or changed functions or variables. .IP \(bu 2 \fB\-\-no\-show\-locs\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Do not show information about where in the \fIsecond shared library\fP the respective type was changed. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fB\-\-show\-bytes\fP .sp Show sizes and offsets in bytes, not bits. By default, sizes and offsets are shown in bits. .IP \(bu 2 \fB\-\-show\-bits\fP .sp Show sizes and offsets in bits, not bytes. This option is activated by default. .IP \(bu 2 \fB\-\-show\-hex\fP .sp Show sizes and offsets in hexadecimal base. .IP \(bu 2 \fB\-\-show\-dec\fP .sp Show sizes and offsets in decimal base. This option is activated by default. .IP \(bu 2 \fB\-\-ignore\-soname\fP .sp Ignore differences in the SONAME when doing a comparison .IP \(bu 2 \fB\-\-no\-show\-relative\-offset\-changes\fP .sp 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. .IP \(bu 2 \fB\-\-no\-unreferenced\-symbols\fP .sp 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. .IP \(bu 2 \fB\-\-no\-default\-suppression\fP .sp Do not load the \fI\%default suppression specification files\fP\&. .IP \(bu 2 \fB\-\-suppressions | \-\-suppr\fP <\fIpath\-to\-suppressions\fP> .sp Use a \fI\%suppression specification\fP file located at \fIpath\-to\-suppressions\fP\&. 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. .sp Please note that, by default, if this option is not provided, then the \fI\%default suppression specification files\fP are loaded . .IP \(bu 2 \fB\-\-drop\fP <\fIregex\fP> .sp When reading the \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP ELF input files, drop the globally defined functions and variables which name match the regular expression \fIregex\fP\&. As a result, no change involving these functions or variables will be emitted in the diff report. .IP \(bu 2 \fB\-\-drop\-fn\fP <\fIregex\fP> .sp When reading the \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP ELF input files, drop the globally defined functions which name match the regular expression \fIregex\fP\&. As a result, no change involving these functions will be emitted in the diff report. .IP \(bu 2 \fB\-\-drop\-var\fP <\fIregex\fP> .sp When reading the \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP ELF input files, drop the globally defined variables matching a the regular expression \fIregex\fP\&. .IP \(bu 2 \fB\-\-keep\fP <\fIregex\fP> .sp When reading the \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP ELF input files, keep the globally defined functions and variables which names match the regular expression \fIregex\fP\&. All other functions and variables are dropped on the floor and will thus not appear in the resulting diff report. .IP \(bu 2 \fB\-\-keep\-fn\fP <\fIregex\fP> .sp When reading the \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP ELF input files, keep the globally defined functions which name match the regular expression \fIregex\fP\&. All other functions are dropped on the floor and will thus not appear in the resulting diff report. .IP \(bu 2 \fB\-\-keep\-var\fP <\fIregex\fP> .sp When reading the \fIfirst\-shared\-library\fP and \fIsecond\-shared\-library\fP ELF input files, keep the globally defined which names match the regular expression \fIregex\fP\&. All other variables are dropped on the floor and will thus not appear in the resulting diff report. .IP \(bu 2 \fB\-\-harmless\fP .sp In the diff report, display only the \fI\%harmless\fP 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. .IP \(bu 2 \fB\-\-no\-harmful\fP .sp In the diff report, do not display the \fI\%harmful\fP changes. By default, only the harmful changes are displayed in diff report. .IP \(bu 2 \fB\-\-redundant\fP .sp In the diff report, do display redundant changes. A redundant change is a change that has been displayed elsewhere in the report. .IP \(bu 2 \fB\-\-no\-redundant\fP .sp In the diff report, do \fINOT\fP display redundant changes. A redundant change is a change that has been displayed elsewhere in the report. This option is switched on by default. .IP \(bu 2 \fB\-\-no\-architecture\fP .sp Do not take architecture in account when comparing ABIs. .IP \(bu 2 \fB\-\-no\-corpus\-path\fP .sp Do not emit the path attribute for the ABI corpus. .IP \(bu 2 \fB\-\-fail\-no\-debug\-info\fP .sp 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. .IP \(bu 2 \fB\-\-leaf\-changes\-only|\-l\fP only show leaf changes, so don’t show impact analysis report. This option implies \fB\-\-redundant\fP\&. .sp The typical output of abidiff when comparing two binaries looks like this .INDENT 2.0 .INDENT 3.5 .sp .EX $ 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]\(aqfunction void fn(C&)\(aq at test\-v1.cc:13:1 has some indirect sub\-type changes: parameter 1 of type \(aqC&\(aq has sub\-type changes: in referenced type \(aqstruct C\(aq at test\-v1.cc:7:1: type size hasn\(aqt changed 1 data member change: type of \(aqleaf* C::m0\(aq changed: in pointed to type \(aqstruct leaf\(aq at test\-v1.cc:1:1: type size changed from 32 to 64 bits 1 data member insertion: \(aqchar leaf::m1\(aq, at offset 32 (in bits) at test\-v1.cc:4:1 $ .EE .UNINDENT .UNINDENT .sp 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&)”. .sp In abidiff parlance, the change on “struct leaf” is called a leaf change. So the \fB\-\-leaf\-changes\-only \-\-impacted\-interfaces\fP options show, well, only the leaf change. And it goes like this: .INDENT 2.0 .INDENT 3.5 .sp .EX $ abidiff \-l libtest\-v0.so libtest\-v1.so \(aqstruct leaf\(aq changed: type size changed from 32 to 64 bits 1 data member insertion: \(aqchar leaf::m1\(aq, at offset 32 (in bits) at test\-v1.cc:4:1 one impacted interface: function void fn(C&) $ .EE .UNINDENT .UNINDENT .sp Note how the report ends by showing the list of interfaces impacted by the leaf change. .sp Now if you don’t want to see that list of impacted interfaces, then you can just avoid using the \fB\-\-impacted\-interface\fP option. You can learn about that option below, in any case. .IP \(bu 2 \fB\-\-impacted\-interfaces\fP .sp 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 \fB\-\-leaf\-changes\-only\fP option, otherwise, it’s ignored. .IP \(bu 2 \fB\-\-dump\-diff\-tree\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 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. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fB\-\-no\-assume\-odr\-for\-cplusplus\fP .sp When analysing a binary originating from C++ code using \fI\%DWARF\fP debug information, libabigail assumes the \fI\%One Definition Rule\fP 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. .sp This option disables that assumption and instructs libabigail to actually actually compare the types to determine if they are equal. .IP \(bu 2 \fB\-\-no\-leverage\-dwarf\-factorization\fP .sp When analysing a binary which \fI\%DWARF\fP debug information was processed with the \fI\%DWZ\fP tool, the type information is supposed to be already factorized. That context is used by libabigail to perform some speed optimizations. .sp This option disables those optimizations. .IP \(bu 2 \fB\-\-no\-change\-categorization | \-x\fP .sp 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 \fB\-\-leaf\-changes\-only\fP one. .IP \(bu 2 \fB\-\-ctf\fP .sp When comparing binaries, extract ABI information from \fI\%CTF\fP debug information, if present. .IP \(bu 2 \fB\-\-btf\fP .sp When comparing binaries, extract ABI information from \fI\%BTF\fP debug information, if present. .IP \(bu 2 \fB\-\-stats\fP .sp Emit statistics about various internal things. .IP \(bu 2 \fB\-\-verbose\fP .sp Emit verbose logs about the progress of miscellaneous internal things. .UNINDENT .UNINDENT .UNINDENT .SS Return values .sp The exit code of the \fBabidiff\fP 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. .sp In the later case, the exit code is a 8\-bits\-wide bit field in which each bit has a specific meaning. .sp The first bit, of value 1, named \fBABIDIFF_ERROR\fP means there was an error. .sp The second bit, of value 2, named \fBABIDIFF_USAGE_ERROR\fP 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 \fBABIDIFF_ERROR\fP bit must be set as well. .sp The third bit, of value 4, named \fBABIDIFF_ABI_CHANGE\fP means the ABI of the binaries being compared are different. .sp The fourth bit, of value 8, named \fBABIDIFF_ABI_INCOMPATIBLE_CHANGE\fP means the ABI of the binaries compared are different in an incompatible way. If this bit is set, then the \fBABIDIFF_ABI_CHANGE\fP bit must be set as well. If the \fBABIDIFF_ABI_CHANGE\fP is set and the \fBABIDIFF_INCOMPATIBLE_CHANGE\fP is \fINOT\fP 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. .sp Note that, at the moment, there are only a few kinds of ABI changes that would result in setting the flag \fBABIDIFF_ABI_INCOMPATIBLE_CHANGE\fP\&. Those ABI changes are either: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 the removal of the symbol of a function or variable that has been defined and exported. .IP \(bu 2 the modification of the index of a member of a virtual function table (for C++ programs and libraries). .UNINDENT .UNINDENT .UNINDENT .sp With time, when more ABI change patterns are found to \fIalways\fP constitute incompatible ABI changes, we will adapt the code to recognize those cases and set the \fBABIDIFF_ABI_INCOMPATIBLE_CHANGE\fP accordingly. So, if you find such patterns, please let us know. .sp The remaining bits are not used for the moment. .SS Usage examples .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP 1. 3 Detecting a change in a sub\-type of a function: .INDENT 3.0 .INDENT 3.5 .sp .EX $ 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]\(aqfunction void foo(S0*)\(aq has some indirect sub\-type changes: parameter 0 of type \(aqS0*\(aq has sub\-type changes: in pointed to type \(aqstruct S0\(aq: size changed from 32 to 64 bits 1 base class insertion: struct type_base 1 data member change: \(aqint S0::m0\(aq offset changed from 0 to 32 $ .EE .UNINDENT .UNINDENT .IP 2. 3 Detecting another change in a sub\-type of a function: .INDENT 3.0 .INDENT 3.5 .sp .EX $ 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]\(aqfunction void foo(S0&)\(aq has some indirect sub\-type changes: parameter 0 of type \(aqS0&\(aq has sub\-type changes: in referenced type \(aqstruct S0\(aq: size changed from 32 to 64 bits 1 data member insertion: \(aqchar S0::inserted_member\(aq, at offset 0 (in bits) 1 data member change: \(aqint S0::m0\(aq offset changed from 0 to 32 $ .EE .UNINDENT .UNINDENT .IP 3. 3 Detecting that functions got removed or added to a library: .INDENT 3.0 .INDENT 3.5 .sp .EX $ 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: \(aqfunction void foo(S0&)\(aq {_Z3fooR2S0} 1 Added function: \(aqfunction void bar(S0&)\(aq {_Z3barR2S0} $ .EE .UNINDENT .UNINDENT .IP 4. 3 Comparing two sets of binaries that are passed on the command line: .INDENT 3.0 .INDENT 3.5 .sp .EX $ abidiff \-\-add\-binaries1=file2\-v1 \e \-\-add\-binaries2=file2\-v2,file2\-v1 \e \-\-added\-binaries\-dir1 dir1 \e \-\-added\-binaries\-dir2 dir2 \e file1\-v1 file1\-v2 .EE .UNINDENT .UNINDENT .sp Note that the files \fBfile2\-v1\fP, and \fBfile2\-v2\fP are to be found in \fBdir1\fP and \fBdir2\fP or in the current directory. .IP 5. 3 Compare two libraries and their dependencies: .INDENT 3.0 .INDENT 3.5 .sp .EX $ abidiff \-\-follow\-dependencies \e \-\-added\-binaries\-dir1 /some/where \e \-\-added\-binaries\-dir2 /some/where/else \e foo bar .EE .UNINDENT .UNINDENT .sp This compares the set of binaries comprised by \fBfoo\fP and its dependencies against the set of binaries comprised by \fBbar\fP and its dependencies. .UNINDENT .UNINDENT .UNINDENT .SS abipkgdiff .sp \fBabipkgdiff\fP compares the Application Binary Interfaces (ABI) of the \fI\%ELF\fP binaries contained in two software packages. The software package formats currently supported are \fI\%Deb\fP, \fI\%RPM\fP, \fI\%tar\fP archives (either compressed or not) and plain directories that contain binaries. .sp 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 \fI\%DWARF\fP, \fI\%CTF\fP or in \fI\%BTF\fP 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. .sp By default, \fBabipkgdiff\fP uses debug information in \fI\%DWARF\fP format, if present, otherwise it compares binaries interfaces using debug information in \fI\%CTF\fP or in \fI\%BTF\fP formats, if present. Finally, if no debug info in these formats is found, it only considers \fI\%ELF\fP symbols and report about their addition or removal. .sp This tool uses the libabigail library to analyze the binary as well as its associated debug information. Here is its general mode of operation. .sp 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 \fI\%ELF\fP 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. .sp Libabigail then has capabilities to generate textual representations of ABI Corpora, compare them, analyze their changes and report about them. .SS Invocation .INDENT 0.0 .INDENT 3.5 .sp .EX abipkgdiff [option] .EE .UNINDENT .UNINDENT .sp \fBpackage1\fP and \fBpackage2\fP are the packages that contain the binaries to be compared. .SS Environment .sp abipkgdiff loads two default \fI\%suppression specifications files\fP, merges their content and use it to filter out ABI change reports that might be considered as false positives to users. .INDENT 0.0 .IP \(bu 2 Default system\-wide suppression specification file .sp 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. .IP \(bu 2 Default user suppression specification file. .sp 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. .UNINDENT .sp 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 \fB\&.abignore\fP, then it will consider it as a suppression specification and it will combine it to the default suppression specification that might be already loaded. .sp The user might as well use the \fB\-\-suppressions\fP option (that is documented further below) to provide a suppression specification. .SS Options .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fB\-\-help | \-h\fP .sp Display a short help about the command and exit. .IP \(bu 2 \fI–version | \-v\fP .sp Display the version of the program and exit. .IP \(bu 2 \fB\-\-debug\-info\-pkg1 | \-\-d1\fP .sp For cases where the debug information for \fIpackage1\fP is split out into a separate file, tells \fBabipkgdiff\fP where to find that separate debug information package. .sp Note that the debug info for \fIpackage1\fP 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. .IP \(bu 2 \fB\-\-debug\-info\-pkg2 | \-\-d2\fP .sp For cases where the debug information for \fIpackage2\fP is split out into a separate file, tells \fBabipkgdiff\fP where to find that separate debug information package. .sp Note that the debug info for \fIpackage2\fP 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. .IP \(bu 2 \fB\-\-devel\-pkg1 | \-\-devel1\fP .sp Specifies where to find the \fI\%Development Package\fP associated with the first package to be compared. That \fI\%Development Package\fP at \fBpath\fP 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 \fINOT\fP defined in these header files. .IP \(bu 2 \fB\-\-devel\-pkg2 | \-\-devel2\fP .sp Specifies where to find the \fI\%Development Package\fP associated with the second package to be compared. That \fI\%Development Package\fP at \fBpath\fP 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 \fINOT\fP defined in these header files. .IP \(bu 2 \fB\-\-drop\-private\-types\fP .sp This option is to be used with the \fB\-\-devel\-pkg1\fP and \fB\-\-devel\-pkg2\fP options. With this option, types that are \fINOT\fP 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. .sp Without this option however, those private types are kept in the internal representation and later filtered out from the report. .sp 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. .IP \(bu 2 \fB\-\-dso\-only\fP .sp Compare ELF files that are shared libraries, only. Do not compare executable files, for instance. .IP \(bu 2 \fB\-\-private\-dso\fP .sp By default, \fBabipkgdiff\fP does not compare DSOs that are private to the RPM package. A private DSO is a DSO which SONAME is \fINOT\fP advertised in the “provides” property of the RPM. .sp This option instructs \fBabipkgdiff\fP to \fIalso\fP compare DSOs that are \fINOT\fP advertised in the “provides” property of the RPM. .sp Please note that the fact that (by default) \fBabipkgdiff\fP 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. .IP \(bu 2 \fB\-\-leaf\-changes\-only|\-l\fP only show leaf changes, so don’t show impact analysis report. This option implies \fB\-\-redundant\fP .sp The typical output of \fBabipkgdiff\fP and \fBabidiff\fP when comparing two binaries, that we shall call \fBfull impact report\fP, looks like this .INDENT 2.0 .INDENT 3.5 .sp .EX $ 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]\(aqfunction void fn(C&)\(aq at test\-v1.cc:13:1 has some indirect sub\-type changes: parameter 1 of type \(aqC&\(aq has sub\-type changes: in referenced type \(aqstruct C\(aq at test\-v1.cc:7:1: type size hasn\(aqt changed 1 data member change: type of \(aqleaf* C::m0\(aq changed: in pointed to type \(aqstruct leaf\(aq at test\-v1.cc:1:1: type size changed from 32 to 64 bits 1 data member insertion: \(aqchar leaf::m1\(aq, at offset 32 (in bits) at test\-v1.cc:4:1 $ .EE .UNINDENT .UNINDENT .sp 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&)”. .sp In abidiff (and abipkgdiff) parlance, the change on “struct leaf” is called a leaf change. So the \fB\-\-leaf\-changes\-only \-\-impacted\-interfaces\fP options show, well, only the leaf change. And it goes like this: .INDENT 2.0 .INDENT 3.5 .sp .EX $ abidiff \-l libtest\-v0.so libtest\-v1.so \(aqstruct leaf\(aq changed: type size changed from 32 to 64 bits 1 data member insertion: \(aqchar leaf::m1\(aq, at offset 32 (in bits) at test\-v1.cc:4:1 one impacted interface: function void fn(C&) $ .EE .UNINDENT .UNINDENT .sp Note how the report ends up by showing the list of interfaces impacted by the leaf change. That’s the effect of the additional \fB\-\-impacted\-interfaces\fP option. .sp Now if you don’t want to see that list of impacted interfaces, then you can just avoid using the \fB\-\-impacted\-interface\fP option. You can learn about that option below, in any case. .sp Please note that when comparing two Linux Kernel packages, it’s this \fBleaf changes report\fP that is emitted, by default. The normal so\-called \fBfull impact report\fP can be emitted with the option \fB\-\-full\-impact\fP which is documented later below. .IP \(bu 2 \fB\-\-impacted\-interfaces\fP .sp 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 \fB\-\-leaf\-changes\-only\fP option, or, when comparing two Linux Kernel packages. Otherwise, it’s simply ignored. .IP \(bu 2 \fB\-\-full\-impact|\-f\fP .sp When comparing two Linux Kernel packages, this function instructs \fBabipkgdiff\fP to emit the so\-called \fBfull impact report\fP, which is the default report kind emitted by the \fBabidiff\fP tool: .INDENT 2.0 .INDENT 3.5 .sp .EX $ 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]\(aqfunction void fn(C&)\(aq at test\-v1.cc:13:1 has some indirect sub\-type changes: parameter 1 of type \(aqC&\(aq has sub\-type changes: in referenced type \(aqstruct C\(aq at test\-v1.cc:7:1: type size hasn\(aqt changed 1 data member change: type of \(aqleaf* C::m0\(aq changed: in pointed to type \(aqstruct leaf\(aq at test\-v1.cc:1:1: type size changed from 32 to 64 bits 1 data member insertion: \(aqchar leaf::m1\(aq, at offset 32 (in bits) at test\-v1.cc:4:1 $ .EE .UNINDENT .UNINDENT .IP \(bu 2 \fB\-\-non\-reachable\-types|\-t\fP .sp Analyze and emit change reports for all the types of the binary, including those that are not reachable from global functions and variables. .sp This option might incur some serious performance degradation as the number of types analyzed can be huge. However, if paired with the \fB\-\-devel\-pkg{1,2}\fP 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. .sp Also, using this option alongside suppression specifications (by also using the \fB\-\-suppressions\fP option) might help keep the number of analyzed types (and the potential performance degradation) in control. .sp 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. .IP \(bu 2 \fB\-\-exported\-interfaces\-only\fP .sp 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 \fI\%ELF\fP symbols that are defined and exported by the binary. It’s those final ABI Corpora that are compared by this tool. .sp 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 \fI\%Linux Kernel\fP\&. Analyzing massive ABI corpora like these can be extremely slow. .sp To mitigate that performance issue, this option allows libabigail to only analyze types that are reachable from interfaces associated with defined and exported \fI\%ELF\fP symbols. .sp Note that this option is turned on by default when analyzing the \fI\%Linux Kernel\fP\&. Otherwise, it’s turned off by default. .IP \(bu 2 \fB\-\-allow\-non\-exported\-interfaces\fP .sp 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 \fI\%ELF\fP symbols that are defined and exported by the binary. It’s those final ABI Corpora that are compared by this tool. .sp 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 \fI\%Linux Kernel\fP\&. Analyzing massive ABI Corpora like these can be extremely slow. .sp 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. .sp Note that this option is turned on by default, unless we are in the presence of the \fI\%Linux Kernel\fP\&. .IP \(bu 2 \fB\-\-redundant\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 In the diff reports, do display redundant changes. A redundant change is a change that has been displayed elsewhere in a given report. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fB\-\-harmless\fP .sp In the diff report, display only the \fI\%harmless\fP 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. .IP \(bu 2 \fB\-\-no\-linkage\-name\fP .sp In the resulting report, do not display the linkage names of the added, removed, or changed functions or variables. .IP \(bu 2 \fB\-\-no\-added\-syms\fP .sp Do not show the list of functions, variables, or any symbol that was added. .IP \(bu 2 \fB\-\-no\-added\-binaries\fP .sp Do not show the list of binaries that got added to the second package. .sp 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. .IP \(bu 2 \fB\-\-no\-abignore\fP .sp Do not search the package for the presence of suppression files. .IP \(bu 2 \fB\-\-no\-parallel\fP .sp By default, \fBabipkgdiff\fP will use all the processors it has available to execute concurrently. This option tells it not to extract packages or run comparisons in parallel. .IP \(bu 2 \fB\-\-no\-default\-suppression\fP .sp Do not load the \fI\%default suppression specification files\fP\&. .IP \(bu 2 \fB\-\-suppressions | \-\-suppr\fP <\fIpath\-to\-suppressions\fP> .sp Use a \fI\%suppression specification\fP file located at \fIpath\-to\-suppressions\fP\&. 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. .sp Please note that, by default, if this option is not provided, then the \fI\%default suppression specification files\fP are loaded . .IP \(bu 2 \fB\-\-linux\-kernel\-abi\-whitelist | \-w\fP <\fIpath\-to\-whitelist\fP> .sp 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”. .sp Any other function or variable which ELF symbol are not present in that white list will not be considered by the ABI comparison process. .sp 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. .sp 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. .IP \(bu 2 \fB\-\-wp\fP <\fIpath\-to\-whitelist\-package\fP> .sp 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”. .sp 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. .sp 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. .sp Any other function or variable which ELF symbol are not present in that white list will not be considered by the ABI comparison process. .sp 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. .sp 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. .IP \(bu 2 \fB\-\-no\-unreferenced\-symbols\fP .sp 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. .IP \(bu 2 \fB\-\-no\-show\-locs\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Do not show information about where in the \fIsecond shared library\fP the respective type was changed. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fB\-\-show\-bytes\fP .sp Show sizes and offsets in bytes, not bits. By default, sizes and offsets are shown in bits. .IP \(bu 2 \fB\-\-show\-bits\fP .sp Show sizes and offsets in bits, not bytes. This option is activated by default. .IP \(bu 2 \fB\-\-show\-hex\fP .sp Show sizes and offsets in hexadecimal base. .IP \(bu 2 \fB\-\-show\-dec\fP .sp Show sizes and offsets in decimal base. This option is activated by default. .IP \(bu 2 \fB\-\-no\-show\-relative\-offset\-changes\fP .sp 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. .IP \(bu 2 \fB\-\-show\-identical\-binaries\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 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. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fB\-\-fail\-no\-dbg\fP .sp 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. .sp Note that the non\-zero exit code returned by the program as a result of this option is the constant \fBABIDIFF_ERROR\fP\&. To know the numerical value of that constant, please refer to the \fI\%exit code documentation\fP\&. .IP \(bu 2 \fB\-\-keep\-tmp\-files\fP .sp Do not erase the temporary directory files that are created during the execution of the tool. .IP \(bu 2 \fB\-\-verbose\fP .sp Emit verbose progress messages. .IP \(bu 2 \fB\-\-self\-check\fP .sp 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: .INDENT 2.0 .INDENT 3.5 .sp .EX $ 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 \(aqlibGLU.so.1.3.1\(aq ==== $ .EE .UNINDENT .UNINDENT .IP \(bu 2 \fB\-\-no\-assume\-odr\-for\-cplusplus\fP .sp When analysing a binary originating from C++ code using \fI\%DWARF\fP debug information, libabigail assumes the \fI\%One Definition Rule\fP 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. .sp This option disables that assumption and instructs libabigail to actually actually compare the types to determine if they are equal. .IP \(bu 2 \fB\-\-no\-leverage\-dwarf\-factorization\fP .sp When analysing a binary which \fI\%DWARF\fP debug information was processed with the \fI\%DWZ\fP tool, the type information is supposed to be already factorized. That context is used by libabigail to perform some speed optimizations. .sp This option disables those optimizations. .IP \(bu 2 \fB\-\-ctf\fP .INDENT 2.0 .INDENT 3.5 This is used to compare packages with \fI\%CTF\fP debug information, if present. .UNINDENT .UNINDENT .IP \(bu 2 \fB\-\-btf\fP .INDENT 2.0 .INDENT 3.5 This is used to compare packages with \fI\%BTF\fP debug information, if present. .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SS Return value .sp The exit code of the \fBabipkgdiff\fP 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. .sp In the later case, the value of the exit code is the same as for the \fI\%abidiff tool\fP\&. .SS kmidiff .sp \fBkmidiff\fP 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. .SS General approach .sp And example of how to build your kernel if you want to compare it to another one using kmidiff is: .INDENT 0.0 .INDENT 3.5 .sp .EX 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 .EE .UNINDENT .UNINDENT .sp Then install the modules into a directory, for instance, the build/modules sub\-directory of the your kernel source tree: .INDENT 0.0 .INDENT 3.5 .sp .EX mkdir build/modules make modules_install INSTALL_MOD_DIR=build/modules .EE .UNINDENT .UNINDENT .sp Then construct a list of interfaces exported by the kernel, that you want to compare: .INDENT 0.0 .INDENT 3.5 .sp .EX cat > kmi\-whitelist << EOF [kernel_4.5_kmi_whitelist] init_task schedule dev_queue_xmit __kmalloc printk EOF .EE .UNINDENT .UNINDENT .sp Suppose you’ve done something similar for the v4.6 branch of the Linux kernel, you now have these two directories: \fBlinux/v4.5\fP and \fBlinux/v4.6\fP\&. Their modules are present under the directories \fBlinux/v4.5/build/modules\fP and \fBlinux/v4.6/build/modules\fP\&. .sp To Comparing their KMI \fBkmidiff\fP needs to know where to find the vmlinux binaries and their associated modules. Here would be what the command line looks like: .INDENT 0.0 .INDENT 3.5 .sp .EX kmidiff \e \-\-kmi\-whitelist linux/v4.6/kmi\-whitelist \e \-\-vmlinux1 linux/v4.5/vmlinux \e \-\-vmlinux2 linux/v4.6/vmlinux \e linux/v4.5/build/modules \e linux/v4.6/build/modules .EE .UNINDENT .UNINDENT .sp This tool uses the libabigail library to analyze the binary as well as its associated debug information. Here is its general mode of operation. .sp 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 \fI\%ELF\fP 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. .sp Libabigail then has capabilities to generate textual representations of ABI Corpora, compare them, analyze their changes and report about them. .SS Invocation .sp More generally, \fBkmidiff\fP is invoked under the form: .INDENT 0.0 .INDENT 3.5 .sp .EX kmidiff [options] .EE .UNINDENT .UNINDENT .SS Environment .sp By default, \fBkmidiff\fP 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. .sp By default, \fBkmidiff\fP uses debug information in the \fI\%DWARF\fP debug info format, if present, otherwise it compares interfaces using \fI\%CTF\fP or \fI\%BTF\fP debug info formats, if present. Finally, if no debug info in these formats is found, it only considers \fI\%ELF\fP symbols and report about their addition or removal. .sp 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: .INDENT 0.0 .INDENT 3.5 .sp .EX [kernel_version_x86_64_whitelist] function1_name function2_name global_variable1_name .... .EE .UNINDENT .UNINDENT .sp 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 \fB[kernel_46_x86_64_whitelist]\fP\&. .sp 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 \fBkmidiff\fP recursively. .sp Note that by default kmidiff analyzes the types reachable from the interfaces associated with \fI\%ELF\fP symbols that are defined and exported by the \fI\%Linux Kernel\fP as being the union of the \fBvmlinux\fP binary and all its compiled modules. It then compares those interfaces (along with their types). .SS Options .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fB\-\-help | \-h\fP .sp Display a short help about the command and exit. .IP \(bu 2 \fB\-\-version | \-v\fP .sp Display the version of the program and exit. .IP \(bu 2 \fB\-\-verbose\fP .sp Display some verbose messages while executing. .IP \(bu 2 \fB\-\-debug\-info\-dir1 | \-\-d1\fP <\fIdi\-path1\fP> .sp For cases where the debug information for the binaries of the first Linux kernel is split out into separate files, tells \fBkmidiff\fP where to find those separate debug information files. .sp Note that \fIdi\-path\fP 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 \fB/usr/lib/debug\fP\&. .IP \(bu 2 \fB\-\-debug\-info\-dir2 | \-\-d2\fP <\fIdi\-path2\fP> .sp Like \fB\-\-debug\-info\-dir1\fP, this options tells \fBkmidiff\fP where to find the split debug information for the binaries of the second Linux kernel. .IP \(bu 2 \fB\-\-vmlinux1 | \-\-l1\fP <\fIpath\-to\-first\-vmlinux\fP> .sp Sets the path to the first \fBvmlinux\fP binary to consider. This has to be the uncompressed vmlinux binary compiled with debug info. .IP \(bu 2 \fB\-\-vmlinux2 | \-\-l2\fP <\fIpath\-to\-first\-vmlinux\fP> .sp Sets the path to the second \fBvmlinux\fP binary to consider. This has to be the uncompressed vmlinux binary compiled with debug info. .IP \(bu 2 \fB\-\-kmi\-whitelist | \-w\fP <\fIpath\-to\-interface\-whitelist\fP> .sp 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. .sp If this option is not provided, \fIall\fP 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. .sp So please, make sure you always use this option unless you really know what you are doing. .IP \(bu 2 \fB\-\-suppressions | \-\-suppr\fP <\fIpath\-to\-suppressions\fP> .sp Use a \fI\%suppression specification\fP file located at \fIpath\-to\-suppressions\fP\&. 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. .sp Please note that, by default, if this option is not provided, then the \fI\%default suppression specification files\fP are loaded . .IP \(bu 2 \fB\-\-no\-change\-categorization | \-x\fP .sp 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. .IP \(bu 2 \fB\-\-ctf\fP .sp Extract ABI information from \fI\%CTF\fP debug information, if present, in the Kernel and Modules. .IP \(bu 2 \fB\-\-btf\fP .sp Extract ABI information from \fI\%BTF\fP debug information, if present, in the Kernel and Modules. .IP \(bu 2 \fB\-\-impacted\-interfaces | \-i\fP .sp Tell what interfaces got impacted by each individual ABI change. .IP \(bu 2 \fB\-\-full\-impact | \-f\fP .sp 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 \fBabidiff\fP or \fBabipkgdiff\fP\&. .IP \(bu 2 \fB\-\-exported\-interfaces\-only\fP .sp When using this option, this tool analyzes the descriptions of the types reachable by the interfaces (functions and variables) associated with \fI\%ELF\fP symbols that are defined and exported by the \fI\%Linux Kernel\fP\&. .sp Otherwise, the tool also has the ability to analyze the descriptions of the types reachable by the interfaces associated with \fI\%ELF\fP symbols that are visible outside their translation unit. This later possibility is however much more resource intensive and results in much slower operations. .sp That is why this option is enabled by default. .IP \(bu 2 \fB\-\-allow\-non\-exported\-interfaces\fP .sp 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 \fI\%ELF\fP symbols that are defined and exported by the binary. It’s that final ABI corpus which is compared against another one. .sp 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. .sp Note that this option is turned off by default. .IP \(bu 2 \fB\-\-show\-bytes\fP .sp Show sizes and offsets in bytes, not bits. This option is activated by default. .IP \(bu 2 \fB\-\-show\-bits\fP .sp Show sizes and offsets in bits, not bytes. By default, sizes and offsets are shown in bytes. .IP \(bu 2 \fB\-\-show\-hex\fP .sp Show sizes and offsets in hexadecimal base. This option is activated by default. .IP \(bu 2 \fB\-\-show\-dec\fP .sp Show sizes and offsets in decimal base. .UNINDENT .UNINDENT .UNINDENT .SS abidw .sp abidw reads a shared library in \fI\%ELF\fP format and emits an XML representation of its ABI to standard output. The emitted representation format, named \fBABIXML\fP, 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. .sp When given the \fB\-\-linux\-tree\fP option, this program can also handle a \fI\%Linux kernel\fP tree. That is, a directory tree that contains both the vmlinux binary and \fI\%Linux Kernel\fP modules. It analyses those \fI\%Linux Kernel\fP 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. .sp To generate either ABI or KMI representation, by default \fBabidw\fP uses debug information in the \fI\%DWARF\fP format, if present, otherwise it looks for debug information in \fI\%CTF\fP or \fI\%BTF\fP formats, if present. Finally, if no debug info in these formats is found, it only considers \fI\%ELF\fP symbols and report about their addition or removal. .sp This tool uses the libabigail library to analyze the binary as well as its associated debug information. Here is its general mode of operation. .sp 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 \fI\%ELF\fP 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. .sp Libabigail then has capabilities to generate textual representations of ABI Corpora, compare them, analyze their changes and report about them. .SS Invocation .INDENT 0.0 .INDENT 3.5 .sp .EX abidw [options] [] .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fB\-\-help | \-h\fP .sp Display a short help about the command and exit. .IP \(bu 2 \fB\-\-version | \-v\fP .sp Display the version of the program and exit. .IP \(bu 2 \fB\-\-abixml\-version\fP .sp Display the version of the ABIXML format emitted by this program and exit. .IP \(bu 2 \fB\-\-add\-binaries\fP <\fIbin1,bin2,…\fP> .sp For each of the comma\-separated binaries given in argument to this option, if the binary is found in the directory specified by the \fI–added\-binaries\-dir\fP 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 \fBabidw\fP\&. That corpus group is then serialized out. .IP \(bu 2 \fB\-\-follow\-dependencies\fP .sp For each dependency of the input binary of \fBabidw\fP, if it is found in the directory specified by the \fB\-\-added\-binaries\-dir\fP 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. .IP \(bu 2 \fB\-\-list\-dependencies\fP .sp For each dependency of the input binary of\(ga\(gaabidw\(ga\(ga, if it’s found in the directory specified by the \fB\-\-added\-binaries\-dir\fP option, then the name of the dependency is printed out. .IP \(bu 2 \fB\-\-added\-binaries\-dir | \-\-abd\fP <\fIdir\-path\fP> .sp This option is to be used in conjunction with the \fB\-\-add\-binaries\fP, the \fB\-\-follow\-dependencies\fP or the \fB\-\-list\-dependencies\fP option. Binaries listed as arguments of the \fB\-\-add\-binaries\fP option or being dependencies of the input binary in the case of the \fB\-\-follow\-dependencies\fP option and found in the directory <\fIdir\-path\fP> are going to be loaded as ABI corpus and added to the set of ABI corpora (called an ABI corpus group) built and serialized. .IP \(bu 2 \fB\-\-debug\-info\-dir | \-d\fP <\fIdir\-path\fP> .sp In cases where the debug info for \fIpath\-to\-elf\-file\fP is in a separate file that is located in a non\-standard place, this tells \fBabidw\fP where to look for that debug info file. .sp Note that \fIdir\-path\fP 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 \fB/usr/lib/debug\fP\&. .sp This option can be provided several times with different root directories. In that case, \fBabidw\fP will potentially look into all those root directories to find the split debug info for the elf file. .sp Note that this option is not mandatory for split debug information installed by your system’s package manager because then \fBabidw\fP knows where to find it. .IP \(bu 2 \fB\-\-out\-file\fP <\fIfile\-path\fP> .sp This option instructs \fBabidw\fP to emit the XML representation of \fIpath\-to\-elf\-file\fP into the file \fIfile\-path\fP, rather than emitting it to its standard output. .IP \(bu 2 \fB\-\-noout\fP .sp This option instructs \fBabidw\fP 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. .IP \(bu 2 \fB\-\-no\-corpus\-path\fP .sp Do not emit the path attribute for the ABI corpus. .IP \(bu 2 \fB\-\-suppressions | suppr\fP <\fIpath\-to\-suppression\-specifications\-file\fP> .sp Use a \fI\%suppression specification\fP file located at \fIpath\-to\-suppression\-specifications\-file\fP\&. 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. .IP \(bu 2 \fB\-\-kmi\-whitelist | \-kaw\fP <\fIpath\-to\-whitelist\fP> .sp When analyzing a \fI\%Linux Kernel\fP 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 \fBKMI\fP rather than \fBABI\fP .sp Any other function or variable which ELF symbol are not present in that white list will not be considered by the KMI writing process. .sp 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 \fI\%Linux Kernel\fP binaries is emitted. .IP \(bu 2 \fB\-\-linux\-tree | \-\-lt\fP .sp Make \fBabidw\fP 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. .sp Below is an example of usage of \fBabidw\fP on a \fI\%Linux Kernel\fP tree. .sp First, checkout a \fI\%Linux Kernel\fP 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 \fBabidw\fP: .INDENT 2.0 .INDENT 3.5 .sp .EX $ 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 .EE .UNINDENT .UNINDENT .IP \(bu 2 \fB\-\-headers\-dir | \-\-hd\fP .sp 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. .sp Note that several public header directories can be specified for the binary to consider. In that case the \fB\-\-header\-dir\fP option should be present several times on the command line, like in the following example: .INDENT 2.0 .INDENT 3.5 .sp .EX $ abidw \-\-header\-dir /some/path \e \-\-header\-dir /some/other/path \e binary > binary.abi .EE .UNINDENT .UNINDENT .IP \(bu 2 \fB\-\-header\-file | \-\-hf\fP .sp 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. .IP \(bu 2 \fB\-\-drop\-private\-types\fP .sp This option is to be used with the \fB\-\-headers\-dir\fP and/or \fBheader\-file\fP options. With this option, types that are \fINOT\fP 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. .IP \(bu 2 \fB\-\-no\-elf\-needed\fP .sp Do not include the list of DT_NEEDED dependency names in the corpus. .IP \(bu 2 \fB\-\-drop\-undefined\-syms\fP .sp 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. .IP \(bu 2 \fB\-\-exported\-interfaces\-only\fP .sp 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 \fI\%ELF\fP symbols that are defined and exported by the binary. It’s that final ABI corpus which textual representation is saved as \fBABIXML\fP\&. .sp 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 \fI\%Linux Kernel\fP\&. Analyzing massive ABI corpora like these can be extremely slow. .sp To mitigate that performance issue, this option allows libabigail to only analyze types that are reachable from interfaces associated with defined and exported \fI\%ELF\fP symbols. .sp Note that this option is turned on by default when analyzing the \fI\%Linux Kernel\fP\&. Otherwise, it’s turned off by default. .IP \(bu 2 \fB\-\-allow\-non\-exported\-interfaces\fP .sp 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 \fI\%ELF\fP symbols that are defined and exported by the binary. It’s that final ABI corpus which textual representation is saved as \fBABIXML\fP\&. .sp 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 \fI\%Linux Kernel\fP\&. Analyzing massive ABI corpora like these can be extremely slow. .sp 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. .sp Note that this option is turned on by default, unless we are in the presence of the \fI\%Linux Kernel\fP\&. .IP \(bu 2 \fB\-\-no\-linux\-kernel\-mode\fP .sp 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. .sp 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. .IP \(bu 2 \fB\-\-check\-alternate\-debug\-info\fP <\fIelf\-path\fP> .sp If the debug info for the file \fIelf\-path\fP contains a reference to an \fI\%alternate debug info\fP file, \fBabidw\fP 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. .IP \(bu 2 \fB\-\-no\-show\-locs\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 In the emitted ABI representation, do not show file, line or column where ABI artifacts are defined. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fB\-\-no\-parameter\-names\fP .sp In the emitted ABI representation, do not show names of function parameters, just the types. .IP \(bu 2 \fB\-\-no\-write\-default\-sizes\fP .sp 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. .IP \(bu 2 \fB\-\-type\-id\-style\fP <\fBsequence\(ga\(ga|\(ga\(gahash\fP> .sp This option controls how types are idenfied in the generated XML files. The default \fBsequence\fP style just numbers (with \fBtype\-id\-\fP as prefix) the types in the order they are encountered. The \fBhash\fP style uses a (stable, portable) hash of libabigail’s internal type names and is intended to make the XML files easier to diff. .IP \(bu 2 \fB\-\-check\-alternate\-debug\-info\-base\-name\fP <\fIelf\-path\fP> .sp Like \fB\-\-check\-alternate\-debug\-info\fP, but in the success message, only mention the base name of the debug info file; not its full path. .IP \(bu 2 \fB\-\-load\-all\-types\fP .sp By default, \fBlibabigail\fP (and thus \fBabidw\fP) 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 \fBabidw\fP\&. This option however makes \fBabidw\fP load \fIall\fP the types defined in the binaries, even those that are not reachable from public declarations. .IP \(bu 2 \fB\-\-abidiff\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 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. .sp This is a debugging and sanity check option. .INDENT 0.0 .IP \(bu 2 \fB\-\-debug\-abidiff\fP .UNINDENT .sp Same as \fB\-\-abidiff\fP but in debug mode. In this mode, error messages are emitted for types which fail type canonicalization. .sp 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. .INDENT 0.0 .IP \(bu 2 \fB\-\-debug\-type\-canonicalization | \-\-debug\-tc\fP .UNINDENT .sp 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. .sp This option is available only if the package was configured with the –enable\-debug\-type\-canonicalization option. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fB\-\-no\-assume\-odr\-for\-cplusplus\fP .sp When analysing a binary originating from C++ code using \fI\%DWARF\fP debug information, libabigail assumes the \fI\%One Definition Rule\fP 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. .sp This option disables that assumption and instructs libabigail to actually actually compare the types to determine if they are equal. .IP \(bu 2 \fB\-\-no\-leverage\-dwarf\-factorization\fP .sp When analysing a binary which \fI\%DWARF\fP debug information was processed with the \fI\%DWZ\fP tool, the type information is supposed to be already factorized. That context is used by libabigail to perform some speed optimizations. .sp This option disables those optimizations. .IP \(bu 2 \fB\-\-ctf\fP .sp Extract ABI information from \fI\%CTF\fP debug information, if present in the given object. .IP \(bu 2 \fB\-\-annotate\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 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. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fB\-\-stats\fP .sp Emit statistics about various internal things. .IP \(bu 2 \fB\-\-verbose\fP .sp Emit verbose logs about the progress of miscellaneous internal things. .UNINDENT .UNINDENT .UNINDENT .SS Usage examples .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP 1. 3 Emitting an \fBABIXML\fP representation of a binary: .INDENT 3.0 .INDENT 3.5 .sp .EX $ abidw binary > binary.abi .EE .UNINDENT .UNINDENT .IP 2. 3 Emitting an \fBABIXML\fP representation of a set of binaries specified on the command line: .INDENT 3.0 .INDENT 3.5 .sp .EX $ abidw \-\-added\-binaries=bin1,bin2,bin3 \e \-\-added\-binaries\-dir /some/where \e binary > binaries.abi .EE .UNINDENT .UNINDENT .sp Note that the binaries bin1, bin2 and bin3 are to be found in the directory \fB/some/where\fP\&. A representation of the ABI of the set of binaries \fBbinary, bin1, bin2\fP and \fBbin3\fP called an \fBABI corpus group\fP is serialized in the file binaries.abi. .IP 3. 3 Emitting an \fBABIXML\fP representation of a binary and its dependencies: .INDENT 3.0 .INDENT 3.5 .sp .EX $ abidw \-\-follow\-dependencies \e \-\-added\-binaries\-dir /some/where \e binary > binary.abi .EE .UNINDENT .UNINDENT .sp Note that only the dependencies that are found in the directory \fB/some/where\fP are analysed. Their ABIs, along with the ABI the binary named \fBbinary\fP are represented as an ABI corpus group and serialized in the file \fBbinary.abi\fP, in the ABIXML format. .UNINDENT .UNINDENT .UNINDENT .SS Notes .SS Alternate debug info files .sp As of the version 4 of the DWARF specification, \fI\%Alternate debug information\fP is a \fI\%GNU\fP 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 \fI\%here\fP\&. .SS abicompat .sp 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. .SS Invocation .INDENT 0.0 .INDENT 3.5 .sp .EX abicompat [options] [ ] .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fB\-\-help\fP .sp Display a short help about the command and exit. .IP \(bu 2 \fI–version | \-v\fP .sp Display the version of the program and exit. .IP \(bu 2 \fB\-\-list\-undefined\-symbols | \-u\fP .sp Display the list of undefined symbols of the application and exit. .IP \(bu 2 \fB\-\-show\-base\-names | \-b\fP .sp 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. .IP \(bu 2 \fB\-\-app\-debug\-info\-dir | \-\-appd\fP .sp 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. .IP \(bu 2 \fB\-\-lib\-debug\-info\-dir1 | \-\-libd1\fP .sp 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. .IP \(bu 2 \fB\-\-lib\-debug\-info\-dir2 | \-\-libd2\fP .sp 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. .IP \(bu 2 \fB\-\-suppressions | \-\-suppr\fP <\fIpath\-to\-suppressions\fP> .sp Use a \fI\%suppression specification\fP file located at \fIpath\-to\-suppressions\fP\&. Note that this option can appear multiple times on the command line; all the suppression specification files are then taken into account. .IP \(bu 2 \fB\-\-no\-show\-locs\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Do not show information about where in the \fIsecond shared library\fP the respective type was changed. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fB\-\-ctf\fP .sp When comparing binaries, extract ABI information from CTF debug information, if present. .IP \(bu 2 \fB\-\-fail\-no\-debug\-info\fP .sp 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. .IP \(bu 2 \fB\-\-ignore\-soname\fP .sp Ignore differences in the SONAME when doing a comparison .IP \(bu 2 \fB\-\-weak\-mode\fP .sp This triggers the weak mode of \fBabicompat\fP\&. In this mode, only one version of the library is required. That is, abicompat is invoked like this: .INDENT 2.0 .INDENT 3.5 .sp .EX abicompat \-\-weak\-mode .EE .UNINDENT .UNINDENT .sp Note that the \fB\-\-weak\-mode\fP option can even be omitted if only one version of the library is given, along with the application; in that case, \fBabicompat\fP automatically switches to operate in weak mode: .INDENT 2.0 .INDENT 3.5 .sp .EX abicompat .EE .UNINDENT .UNINDENT .sp 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, \fBabicompat\fP tells the user what the differences are. .sp In other words, in this mode, \fBabicompat\fP 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. .sp Note that in this mode, \fIabicompat\fP 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 \fBweak\fP mode. .UNINDENT .UNINDENT .UNINDENT .SS Return values .sp The exit code of the \fBabicompat\fP 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. .sp In the later case, the exit code is a 8\-bits\-wide bit field in which each bit has a specific meaning. .sp The first bit, of value 1, named \fBABIDIFF_ERROR\fP means there was an error. .sp The second bit, of value 2, named \fBABIDIFF_USAGE_ERROR\fP 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 \fBABIDIFF_ERROR\fP bit must be set as well. .sp The third bit, of value 4, named \fBABIDIFF_ABI_CHANGE\fP means the ABI of the binaries being compared are different. .sp The fourth bit, of value 8, named \fBABIDIFF_ABI_INCOMPATIBLE_CHANGE\fP means the ABI of the binaries compared are different in an incompatible way. If this bit is set, then the \fBABIDIFF_ABI_CHANGE\fP bit must be set as well. If the \fBABIDIFF_ABI_CHANGE\fP is set and the \fBABIDIFF_INCOMPATIBLE_CHANGE\fP is \fINOT\fP 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. .sp The remaining bits are not used for the moment. .SS Usage examples .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 Detecting a possible ABI incompatibility in a new shared library version: .INDENT 2.0 .INDENT 3.5 .sp .EX $ 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 \(dqtest0.h\(dq 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 \(dqtest0.h\(dq 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 \(dqtest1.h\(dq 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\(aqs comment out the definition of third_func() 19 void 20 third_func() 21 { 22 } 23 */ $ .EE .UNINDENT .UNINDENT .INDENT 2.0 .IP \(bu 2 Compile the first and second versions of the libraries: \fBlibtest\-0.so\fP and \fBlibtest\-1.so\fP: .INDENT 2.0 .INDENT 3.5 .sp .EX $ g++ \-g \-Wall \-shared \-o libtest\-0.so test0.cc $ g++ \-g \-Wall \-shared \-o libtest\-1.so test1.cc .EE .UNINDENT .UNINDENT .IP \(bu 2 Compile the application and link it against the first version of the library, creating the \fBtest\-app\fP binary: .INDENT 2.0 .INDENT 3.5 .sp .EX $ g++ \-g \-Wall \-o test\-app \-L. \-ltest\-0.so test\-app.cc .EE .UNINDENT .UNINDENT .IP \(bu 2 Now, use \fBabicompat\fP to see if libtest\-1.so is ABI compatible with app, with respect to the ABI of libtest\-0.so: .INDENT 2.0 .INDENT 3.5 .sp .EX $ abicompat test\-app libtest\-0.so libtest\-1.so ELF file \(aqtest\-app\(aq might not be ABI compatible with \(aqlibtest\-1.so\(aq due to differences with \(aqlibtest\-0.so\(aq 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]\(aqfunction foo* first_func()\(aq has some indirect sub\-type changes: return type changed: in pointed to type \(aqstruct foo\(aq: size changed from 32 to 64 bits 1 data member insertion: \(aqchar foo::m1\(aq, at offset 32 (in bits) [C]\(aqfunction void second_func(foo&)\(aq has some indirect sub\-type changes: parameter 0 of type \(aqfoo&\(aq has sub\-type changes: referenced type \(aqstruct foo\(aq changed, as reported earlier $ .EE .UNINDENT .UNINDENT .IP \(bu 2 Now use the weak mode of abicompat, that is, providing just the application and the new version of the library: .INDENT 2.0 .INDENT 3.5 .sp .EX $ abicompat \-\-weak\-mode test\-app libtest\-1.so functions defined in library \(aqlibtest\-1.so\(aq have sub\-types that are different from what application \(aqtest\-app\(aq expects: function foo* first_func(): return type changed: in pointed to type \(aqstruct foo\(aq: size changed from 32 to 64 bits 1 data member insertion: \(aqchar foo::m1\(aq, at offset 32 (in bits) $ .EE .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SS abilint .sp abilint parses the native XML representation of an ABI as emitted by \fI\%abidw\fP\&. Once it has parsed the XML representation of the ABI, \fBabilint\fP 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. .sp Note that the main intent of this tool to help debugging issues in the underlying Libabigail library. .sp Note also that \fBabilint\fP can also read an \fI\%ELF\fP input file, build the in\-memory model for its ABI, and serialize that model back into XML to standard output. In that case, the \fI\%ELF\fP input file must be accompanied with its debug information in the \fI\%DWARF\fP format. .SS Invocation .INDENT 0.0 .INDENT 3.5 .sp .EX abilint [options] [] .EE .UNINDENT .UNINDENT .SS Options .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fB\-\-help\fP .sp Display a short help message and exits. .IP \(bu 2 \fI–version | \-v\fP .sp Display the version of the program and exit. .IP \(bu 2 \fB\-\-debug\-info\-dir\fP <\fIpath\fP> .sp When reading an \fI\%ELF\fP input file which debug information is split out into a separate file, this options tells \fBabilint\fP where to find that separate debug information file. .sp Note that \fIpath\fP 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 \fB/usr/lib/debug\fP\&. .sp Note also that this option is not mandatory for split debug information installed by your system’s package manager because then \fBabidiff\fP knows where to find it. .IP \(bu 2 \fB\-\-diff\fP .sp 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. .IP \(bu 2 \fB\-\-noout\fP .sp Do not display anything on standard output. The return code of the command is the only way to know if the command succeeded. .IP \(bu 2 \fB\-\-suppressions | suppr\fP <\fIpath\-to\-suppression\-specifications\-file\fP> .sp Use a \fI\%suppression specification\fP file located at \fIpath\-to\-suppression\-specifications\-file\fP\&. 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. .IP \(bu 2 \fB\-\-headers\-dir | \-\-hd\fP .sp 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. .IP \(bu 2 \fB\-\-header\-file | \-\-hf\fP .sp 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. .IP \(bu 2 \fB\-\-stdin | \-\-\fP .sp Read the input content from standard input. .IP \(bu 2 \fB\-\-tu\fP .sp Expect the input XML to represent a single translation unit. .IP \(bu 2 \fB\-\-ctf\fP .sp Extract ABI information from CTF debug information, if present in the given object. .UNINDENT .UNINDENT .UNINDENT .SS fedabipkgdiff .sp \fBfedabipkgdiff\fP compares the ABI of shared libraries in \fI\%Fedora\fP packages. It’s a convenient way to do so without having to manually download packages from the \fI\%Fedora Build System\fP\&. .sp \fBfedabipkgdiff\fP knows how to talk with the \fI\%Fedora Build System\fP 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. .sp 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. .SS Invocation .INDENT 0.0 .INDENT 3.5 .sp .EX fedabipkgdiff [option] ... .EE .UNINDENT .UNINDENT .SS Environment .sp fedabipkgdiff loads two default \fI\%suppression specifications files\fP, merges their content and use it to filter out ABI change reports that might be considered as false positives to users. .INDENT 0.0 .IP \(bu 2 Default system\-wide suppression specification file .sp 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. .IP \(bu 2 Default user suppression specification file. .sp 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. .UNINDENT .SS Options .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fB\-\-help | \-h\fP .sp Display a short help about the command and exit. .IP \(bu 2 \fB\-\-dry\-run\fP .sp Don’t actually perform the ABI comparison. Details about what is going to be done are emitted on standard output. .IP \(bu 2 \fB\-\-debug\fP .sp Emit debugging messages about the execution of the program. Details about each method invocation, including input parameters and returned values, are emitted. .IP \(bu 2 \fB\-\-traceback\fP .sp Show traceback when an exception raised. This is useful for developers of the tool itself to know more exceptional errors. .IP \(bu 2 \fB\-\-server\fP .sp Specifies the URL of the \fI\%Koji\fP XMLRPC service the tool talks to. The default value of this option is \fI\%http://koji.fedoraproject.org/kojihub\fP\&. .IP \(bu 2 \fB\-\-topurl\fP .sp Specifies the URL of the package store the tool downloads RPMs from. The default value of this option is \fI\%https://kojipkgs.fedoraproject.org\fP\&. .IP \(bu 2 \fB\-\-from\fP .sp Specifies the name of the baseline \fI\%Fedora\fP distribution in which to find the first \fI\%build\fP that is used for comparison. The \fBdistro\fP value can be any valid value of the RPM macro \fB%{?dist}\fP for \fI\%Fedora\fP, for example, \fBfc4\fP, \fBfc23\fP, \fBfc25\fP\&. .IP \(bu 2 \fB\-\-to\fP .sp Specifies the name of the \fI\%Fedora\fP distribution in which to find the \fI\%build\fP that is compared against the baseline specified by option \fB\-\-from\fP\&. The \fBdistro\fP value could be any valid value of the RPM macro \fB%{?dist}\fP for \fI\%Fedora\fP, for example, \fBfc4\fP, \fBfc23\fP\&. .IP \(bu 2 \fB\-\-all\-subpackages\fP .sp Instructs the tool to also compare the ABI of the binaries in the sub\-packages of the packages specified. .IP \(bu 2 \fB\-\-dso\-only\fP .sp 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. .IP \(bu 2 \fB\-\-suppressions\fP <\fIpath\-to\-suppresions\fP> .sp Use a \fI\%suppression specification\fP file located at \fIpath\-to\-suppressions\fP\&. .IP \(bu 2 \fB\-\-no\-default\-suppression\fP .sp Do not load the \fI\%default suppression specification files\fP\&. .IP \(bu 2 \fB\-\-no\-devel\-pkg\fP .sp 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. .IP \(bu 2 \fB\-\-show\-identical\-binaries\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 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. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fB\-\-abipkgdiff\fP .sp Specify an alternative abipkgdiff instead of the one installed in system. .IP \(bu 2 \fB\-\-clean\-cache\-before\fP .sp Clean cache before ABI comparison. .IP \(bu 2 \fB\-\-clean\-cache\-after\fP .sp Clean cache after ABI comparison. .IP \(bu 2 \fB\-\-clean\-cache\fP .sp If you want to clean cache both before and after ABI comparison, \fB\-\-clean\-cache\fP is the convenient way for you to save typing of two options at same time. .UNINDENT .UNINDENT .UNINDENT .sp 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 \fI\%Fedora Naming Guidelines\fP .SS Return value .sp The exit code of the \fBabipkgdiff\fP 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. .sp In the later case, the value of the exit code is the same as for the \fI\%abidiff tool\fP\&. .SS Use cases .sp Below are some usage examples currently supported by \fBfedabipkgdiff\fP\&. .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP 1. 3 Compare the ABI of binaries in a local package against the ABI of the latest stable package in \fI\%Fedora\fP 23. .sp Suppose you have built just built the \fBhttpd\fP 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 \fBhttp\fP build from \fI\%Fedora\fP 23. The command line invocation would be: .INDENT 3.0 .INDENT 3.5 .sp .EX $ fedabipkgdiff \-\-from fc23 ./httpd\-2.4.18\-2.fc24.x86_64.rpm .EE .UNINDENT .UNINDENT .IP 2. 3 Compare the ABI of binaries in two local packages. .sp 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: .INDENT 3.0 .INDENT 3.5 .sp .EX $ fedabipkgdiff path/to/httpd\-2.4.23\-3.fc23.x86_64.rpm another/path/to/httpd\-2.4.23\-4.fc24.x86_64.rpm .EE .UNINDENT .UNINDENT .sp All what fedabipkgdiff does happens on local machine without the need of querying or downloading RPMs from Koji. .IP 3. 3 Compare the ABI of binaries in the latest build of the \fBhttpd\fP package in \fBFedora 23\fP against the ABI of the binaries in the latest build of the same package in 24. .sp In this case, note that neither of the two packages are available locally. The tool is going to talk with the \fI\%Fedora Build System\fP, determine what the versions and releases of the latest packages are, download them and perform the comparison locally. The command line invocation would be: .INDENT 3.0 .INDENT 3.5 .sp .EX $ fedabipkgdiff \-\-from fc23 \-\-to fc24 httpd .EE .UNINDENT .UNINDENT .IP 4. 3 Compare the ABI of binaries of two builds of the \fBhttpd\fP package, designated their versions and releases. .sp If we want to do perform the ABI comparison for all the processor architectures supported by \fI\%Fedora\fP the command line invocation would be: .INDENT 3.0 .INDENT 3.5 .sp .EX $ fedabipkgdiff httpd\-2.8.14.fc23 httpd\-2.8.14.fc24 .EE .UNINDENT .UNINDENT .sp But if we want to perform the ABI comparison for a specific architecture, say, x86_64, then the command line invocation would be: .INDENT 3.0 .INDENT 3.5 .sp .EX $ fedabipkgdiff httpd\-2.8.14.fc23.x86_64 httpd\-2.8.14.fc24.x86_64 .EE .UNINDENT .UNINDENT .IP 5. 3 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: .INDENT 3.0 .INDENT 3.5 .sp .EX $ fedabipkgdiff \-\-all\-subpackages httpd\-2.8.14.fc23 httpd\-2.8.14.fc24 .EE .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SH CONCEPTS .SS ABI artifacts .sp 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 \fI\%ELF\fP symbols exported by a shared library. .sp The set of ABI artifact for a binary is called an ABI Corpus. .SS Harmful changes .sp 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. .SS Harmless changes .sp 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. .sp By default, \fBabidiff\fP filters harmless changes from the diff report. .SS Suppression specifications .SS Definition .sp A suppression specification file is a way for a user to instruct \fI\%abidiff\fP, \fI\%abipkgdiff\fP or any other relevant libabigail tool to avoid emitting reports for changes involving certain \fI\%ABI artifacts\fP\&. .sp It contains directives (or specifications) that describe the set of ABI artifacts to avoid emitting change reports about. .SS Introductory examples .sp Its syntax is based on a simplified and customized form of \fI\%Ini File Syntax\fP\&. For instance, to specify that change reports on a type named FooPrivateType should be suppressed, one could write this suppression specification: .INDENT 0.0 .INDENT 3.5 .sp .EX [suppress_type] name = FooPrivateType .EE .UNINDENT .UNINDENT .sp If we want to ensure that only change reports about structures named FooPrivateType should be suppressed, we could write: .INDENT 0.0 .INDENT 3.5 .sp .EX [suppress_type] type_kind = struct name = FooPrivateType .EE .UNINDENT .UNINDENT .sp But we could also want to suppress change reports avoid typedefs named FooPrivateType. In that case we would write: .INDENT 0.0 .INDENT 3.5 .sp .EX [suppress_type] type_kind = typedef name = FooPrivateType .EE .UNINDENT .UNINDENT .sp Or, we could want to suppress change reports about all struct which names end with the string “PrivateType”: .INDENT 0.0 .INDENT 3.5 .sp .EX [suppress_type] type_kind = struct name_regexp = ^.*PrivateType .EE .UNINDENT .UNINDENT .sp Let’s now look at the generic syntax of suppression specification files. .SS Syntax .SS Properties .sp More generally, the format of suppression lists is organized around the concept of \fIproperty\fP\&. Every property has a name and a value, delimited by the \fB=\fP sign. E.g: .INDENT 0.0 .INDENT 3.5 .sp .EX name = value .EE .UNINDENT .UNINDENT .sp Leading and trailing white spaces are ignored around property names and values. .SS Regular expressions .sp The value of some properties might be a regular expression. In that case, they must comply with the syntax of \fI\%extended POSIX regular expressions\fP\&. Note that Libabigail uses the regular expression engine of the \fI\%GNU C Library\fP\&. .SS Escaping a character in a regular expression .sp When trying to match a string that contains a \fB*\fP character, like in the pointer type \fBint*\fP, one must be careful to notice that the character \fB*\fP 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 \fBint*\fP in a suppression file should be .INDENT 0.0 .INDENT 3.5 .sp .EX int\e\e* .EE .UNINDENT .UNINDENT .sp Wait; but then why the two \fB\e\fP characters? Well, because the \fB\e\fP character is a special character in the \fI\%Ini File Syntax\fP used for specifying suppressions. So it must be escaped as well, so that the Ini File parser leaves a \fB\e\fP character intact in the data stream that is handed to the regular expression engine. Hence the \fB\e\e\fP targeted at the Ini File parser. .sp So, in short, to escape a character in a regular expression, always prefix the character with the \fB\e\e\fP sequence. .SS Modus operandi .sp Suppression specifications can be applied at two different points of the processing pipeline of libabigail. .sp 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. .sp 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. .SS Sections .sp 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: .INDENT 0.0 .INDENT 3.5 .sp .EX [section_name] property1_name = property1_value property2_name = property2_value .EE .UNINDENT .UNINDENT .sp 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. .SS Section names .sp Each different section can be thought of as being a directive to suppress ABI change reports for a particular kind of ABI artifact. .SS \fB[suppress_file]\fP .sp 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. .sp Note that for the \fB[suppress_file]\fP directive to work, at least one of the following properties must be provided: .INDENT 0.0 .INDENT 3.5 \fBfile_name_regexp\fP, \fBfile_name_not_regexp\fP, \fBsoname_regexp\fP, \fBsoname_not_regexp\fP\&. .UNINDENT .UNINDENT .sp If none of the above properties are provided, then the \fB[suppress_file]\fP directive is simply ignored. .sp The potential properties of this sections are listed below: .INDENT 0.0 .IP \(bu 2 \fBfile_name_not_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBfile_name_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Prevents the system from loading the file which name does not match the regular expression specified as value of this property. .IP \(bu 2 \fBfile_name_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBfile_name_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Prevents the system from loading the file which name matches the regular expression specified as value of this property. .IP \(bu 2 \fBlabel\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBlabel\fP \fB=\fP .UNINDENT .UNINDENT .sp 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. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsoname_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBsoname_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .IP \(bu 2 \fBsoname_not_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBsoname_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Prevents the system from loading the file which contains a SONAME property that does \fINOT\fP match the regular expression of this property. Note that this property also works on an abixml file if it contains a SONAME property. .UNINDENT .SS \fB[suppress_type]\fP .sp This directive suppresses report messages about a type change. .sp Note that for the \fB[suppress_type]\fP directive to work, at least one of the following properties must be provided: .INDENT 0.0 .INDENT 3.5 \fBfile_name_regexp\fP, \fBfile_name_not_regexp\fP, \fBsoname_regexp\fP, \fBsoname_not_regexp\fP, \fBname\fP, \fBname_regexp\fP, \fBname_not_regexp\fP, \fBsource_location_not_in\fP, \fBsource_location_not_regexp\fP, \fBtype_kind\fP\&. .UNINDENT .UNINDENT .sp If none of the above properties are provided, then the \fB[suppress_type]\fP directive is simply ignored. .sp The potential properties of this sections are listed below: .INDENT 0.0 .INDENT 3.5 .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBaccessed_through\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBaccessed_through\fP \fB=\fP .UNINDENT .UNINDENT .sp 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: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBdirect\fP .sp So if the \fB[suppress_type]\fP contains the property description: .INDENT 2.0 .INDENT 3.5 .sp .EX accessed_through = direct .EE .UNINDENT .UNINDENT .sp then changes about a type that is referred\-to directly (i.e, not through a pointer or a reference) are going to be suppressed. .IP \(bu 2 \fBpointer\fP .sp If the \fBaccessed_through\fP property is set to the value \fBpointer\fP then changes about a type that is referred\-to through a pointer are going to be suppressed. .IP \(bu 2 \fBreference\fP .sp If the \fBaccessed_through\fP property is set to the value \fBreference\fP then changes about a type that is referred\-to through a reference are going to be suppressed. .IP \(bu 2 \fBreference\-or\-pointer\fP .sp If the \fBaccessed_through\fP property is set to the value \fBreference\-or\-pointer\fP then changes about a type that is referred\-to through either a reference or a pointer are going to be suppressed. .UNINDENT .UNINDENT .UNINDENT .sp For an extensive example of how to use this property, please check out the example below about \fI\%suppressing change reports about types accessed either directly or through pointers\fP\&. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBchanged_enumerators\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBchanged_enumerators\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving changes in the value of enumerators of a given enum type. This property is applied if the \fBtype_kind\fP property is set to the value \fBenum\fP, at least. The value of the \fBchanged_enumerators\fP is a comma\-separated list of the enumerators that the user expects to change. For instance: .INDENT 2.0 .INDENT 3.5 .sp .EX changed_enumerators = LAST_ENUMERATORS0, LAST_ENUMERATOR1 .EE .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBchanged_enumerators_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBchanged_enumerators_regexp\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving changes in the value of enumerators of a given enum type. This property is applied if the \fBtype_kind\fP property is set to the value \fBenum\fP, at least. The value of the \fBchanged_enumerators_regexp\fP 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: .INDENT 2.0 .INDENT 3.5 .sp .EX changed_enumerators_regexp = .*_MAX$, .*_LAST$, .*_NUM$, .*_NBITS$ .EE .UNINDENT .UNINDENT .sp In the example above, change reports to any enumerator which name ends with _MAX, _LAST, _NUM or _NBITS will be suppressed. .sp Note that for this property to be applied to changes to an enum type, the size of the enum type must \fINOT\fP have changed. .IP \(bu 2 \fBdrop\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBdrop\fP \fB=\fP yes | no .UNINDENT .UNINDENT .sp 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 \fI\%early suppression specification mode\fP\&. The net effect is that it potentially reduces the memory used to represent the ABI being analyzed. .sp Please note that for this property to be effective, the enclosing suppression specification must have at least one of the following properties specified: \fBname_regexp\fP, \fBname\fP, \fBname_regexp\fP, \fBsource_location_not_in\fP or \fBsource_location_not_regexp\fP\&. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBfile_name_not_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBfile_name_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .IP \(bu 2 \fBfile_name_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBfile_name_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .UNINDENT .INDENT 0.0 .INDENT 3.5 .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBhas_data_member\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBhas_data_member\fP \fB=\fP <\fBlist\-of\-data\-member\-names\fP> .UNINDENT .UNINDENT .UNINDENT .sp Suppresses change reports involving a type which contains data members whose names are provided in the list value of this property. .sp A usage examples of this property would be: .INDENT 0.0 .INDENT 3.5 .sp .EX has_data_member = {private_data_member0, private_data_member1} .EE .UNINDENT .UNINDENT .sp The property above would match any type which contains at least two data members whose names are \fBprivate_data_member0\fP and \fBprivate_data_member1\fP\&. .sp Another usage examples of this property would be: .INDENT 0.0 .INDENT 3.5 .sp .EX has_data_member = another_private_data_member .EE .UNINDENT .UNINDENT .sp The property above would match any type which contains a data member which name is \fBanother_private_data_member0\fP\&. .INDENT 0.0 .INDENT 3.5 .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBhas_data_member_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBhas_data_member_regexp\fP \fB=\fP <\fBa\-regular\-expression\fP> .UNINDENT .UNINDENT .UNINDENT .sp Suppresses change reports involving a type which contains data members whose names match the regular expression provided as the value of this property. .sp A usage examples of this property would be: .INDENT 0.0 .INDENT 3.5 .sp .EX has_data_member_regexp = ^private_data_member .EE .UNINDENT .UNINDENT .sp The property above would match any type which contains data members whose names match the regular expression \fB^private_data_member\fP\&. In other words, it would match any type which contains data members whose names start with the string “private_data_member”. .INDENT 0.0 .INDENT 3.5 .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBhas_data_member_inserted_at\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBhas_data_member_inserted_at\fP \fB=\fP <\fBoffset\-in\-bit\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving a type which has at least one data member inserted at an offset specified by the property value \fBoffset\-in\-bit\fP\&. Please note that if the size of the type changed, then the type change will \fINOT\fP be suppressed by the evaluation of this property, unless the \fI\%has_size_change\fP property is present and set to \fByes\fP\&. .sp The value \fBoffset\-in\-bit\fP is either: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 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. .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 data member offset selector expressions, such as: .INDENT 2.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 the keyword \fBend\fP which is a named constant which value equals the offset of the end of the structure or class. .IP \(bu 2 the keyword \fBoffset_of_flexible_array_data_member\fP which is a named constant that evaluates to the offset of the flexible array data member contained in the relevant structure. .IP \(bu 2 the function call expression \fBoffset_of(data\-member\-name)\fP where \fIdata\-member\-name\fP 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 \fBdata\-member\-name\fP\&. .IP \(bu 2 the function call expression \fBoffset_after(data\-member\-name)\fP where \fIdata\-member\-name\fP 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 \fBdata\-member\-name\fP\&. .IP \(bu 2 the function call expression \fBoffset_of_first_data_member_regexp(data\-member\-name\-regexp)\fP where \fIdata\-member\-name\-regexp\fP 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. .IP \(bu 2 the function call expression \fBoffset_of_last_data_member_regexp(data\-member\-name\-regexp)\fP where \fIdata\-member\-name\-regexp\fP 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. .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBhas_data_member_inserted_between\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBhas_data_member_inserted_between\fP \fB=\fP {<\fBrange\-begin\fP>, <\fBrange\-end\fP>} .UNINDENT .UNINDENT .sp Suppresses change reports involving a type which has at least one data member inserted at an offset that is comprised in the range between \fBrange\-begin\fP and \fBrange\-end\fP\&. Please note that each of the values \fBrange\-begin\fP and \fBrange\-end\fP can be of the same form as the \fI\%has_data_member_inserted_at\fP property above. Please also note that if the size of the type changed, then the type change will \fINOT\fP be suppressed by the evaluation of this property, unless the \fI\%has_size_change\fP property is present and set to \fByes\fP\&. Note that data member deletions happening in the range between \fBrange\-begin\fP and \fBrange\-end\fP 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 \fI\%has_size_change\fP property is present and set to \fByes\fP\&. .sp Usage examples of this properties are: .INDENT 0.0 .INDENT 3.5 .sp .EX has_data_member_inserted_between = {8, 64} .EE .UNINDENT .UNINDENT .sp or: .INDENT 0.0 .INDENT 3.5 .sp .EX has_data_member_inserted_between = {16, end} .EE .UNINDENT .UNINDENT .sp or: .INDENT 0.0 .INDENT 3.5 .sp .EX has_data_member_inserted_between = {offset_after(member1), end} .EE .UNINDENT .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBhas_data_members_inserted_between\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBhas_data_members_inserted_between\fP \fB=\fP {} .UNINDENT .UNINDENT .sp 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: .INDENT 0.0 .INDENT 3.5 .sp .EX has_data_members_inserted_between = {{8, 31}, {72, 95}} .EE .UNINDENT .UNINDENT .sp 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 \fBhas_data_members_inserted_between\fP 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 \fI\%has_data_member_inserted_at\fP property above. Please also note that if the size of the type changed, then the type will \fINOT\fP be suppressed by the evaluation of this property, unless the \fI\%has_size_change\fP property is present and set to \fByes\fP\&. 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 \fI\%has_size_change\fP property is present and set to \fByes\fP\&. .sp Another usage example of this property is thus: .INDENT 0.0 .INDENT 3.5 .sp .EX has_data_members_inserted_between = { {offset_after(member0), offset_of(member1)}, {72, end} } .EE .UNINDENT .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBhas_strict_flexible_array_data_member_conversion\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBhas_strict_flexible_array_data_member_conversion\fP \fB=\fP yes | no .UNINDENT .UNINDENT .sp 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 \fBdata[1]\fP being converted to \fBdata[]\fP\&. .sp Please note that if the size of the type changed, then the type change will \fINOT\fP be suppressed by the evaluation of this property, unless the \fI\%has_size_change\fP property is present and set to \fByes\fP\&. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBhas_size_change\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBhas_size_change\fP \fB=\fP yes | no .UNINDENT .UNINDENT .UNINDENT .UNINDENT .sp This property is to be used in conjunction with the properties \fI\%has_data_member_inserted_between\fP, \fI\%has_data_members_inserted_between\fP, and \fI\%has_strict_flexible_array_data_member_conversion\fP Those properties will not match a type change if the size of the type changes, unless the \fBhas_size_changes\fP property is set to \fByes\fP\&. .INDENT 0.0 .INDENT 3.5 .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBlabel\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBlabel\fP \fB=\fP .UNINDENT .UNINDENT .sp 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. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBname\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBname\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving types whose name equals the value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBname_not_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBname_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving types whose name does \fINOT\fP 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. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBname_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBname_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving types whose name matches the regular expression specified as value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsoname_not_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBsoname_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .IP \(bu 2 \fBsoname_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBsoname_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .UNINDENT .INDENT 0.0 .INDENT 3.5 .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsource_location_not_in\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsource_location_not_in\fP \fB=\fP <\fBlist\-of\-file\-paths\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving a type which is defined in a file which path is \fINOT\fP listed in the value \fBlist\-of\-file\-paths\fP\&. Note that the value is a comma\-separated list of file paths e.g, this property .INDENT 0.0 .INDENT 3.5 .sp .EX source_location_not_in = libabigail/abg\-ir.h, libabigail/abg\-dwarf\-reader.h .EE .UNINDENT .UNINDENT .sp suppresses change reports about all the types that are \fINOT\fP defined in header files whose path end up with the strings libabigail/abg\-ir.h or libabigail/abg\-dwarf\-reader.h. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsource_location_not_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsource_location_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving a type which is defined in a file which path does \fINOT\fP match the \fI\%regular expression\fP provided as value of the property. E.g, this property .INDENT 0.0 .INDENT 3.5 .sp .EX source_location_not_regexp = libabigail/abg\-.*\e\e.h .EE .UNINDENT .UNINDENT .sp suppresses change reports involving all the types that are \fINOT\fP defined in header files whose path match the regular expression provided a value of the property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBtype_kind\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .TP .B \fBtype_kind\fP \fB=\fP \fBclass\fP | \fBstruct\fP | \fBunion\fP | \fBenum\fP | \fBarray\fP | \fBtypedef\fP | \fBbuiltin\fP .UNINDENT .UNINDENT .UNINDENT .sp 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: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 .INDENT 2.0 .TP .B \fBclass\fP: 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. .UNINDENT .IP \(bu 2 .INDENT 2.0 .TP .B \fBstruct\fP: suppress change reports for struct types in C or C++. Note that the value \fBclass\fP above is a super\-set of this one. .UNINDENT .IP \(bu 2 \fBunion\fP: suppress change reports for union types. .IP \(bu 2 \fBenum\fP: suppress change reports for enum types. .IP \(bu 2 \fBarray\fP: suppress change reports for array types. .IP \(bu 2 \fBtypedef\fP: suppress change reports for typedef types. .IP \(bu 2 \fBbuiltin\fP: suppress change reports for built\-in (or native) types. Example of built\-in types are char, int, unsigned int, etc. .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .SS \fB[suppress_function]\fP .sp This directive suppresses report messages about changes on a set of functions. .sp Note that for the \fB[suppress_function]\fP directive to work, at least one of the following properties must be provided: .INDENT 0.0 .INDENT 3.5 \fBlabel\fP, \fBfile_name_regexp\fP, \fBfile_name_not_regexp\fP, \fBsoname_regexp\fP, \fBsoname_not_regexp\fP, \fBname\fP, \fBname_regexp\fP, \fBname_not_regexp\fP, \fBparameter\fP, \fBreturn_type_name\fP, \fBreturn_type_regexp\fP, \fBsymbol_name\fP, \fBsymbol_name_regexp\fP, \fBsymbol_name_not_regexp\fP, \fBsymbol_version\fP, \fBsymbol_version_regexp\fP\&. .UNINDENT .UNINDENT .sp If none of the above properties are provided, then the \fB[suppress_function]\fP directive is simply ignored. .sp The potential properties of this sections are: .INDENT 0.0 .INDENT 3.5 .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBchange_kind\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBchange_kind\fP \fB=\fP .UNINDENT .UNINDENT .sp 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: .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fBfunction\-subtype\-change\fP .sp This suppression specification applies to functions that which have at least one sub\-type that has changed. .IP \(bu 2 \fBadded\-function\fP .sp This suppression specification applies to functions that have been added to the binary. .IP \(bu 2 \fBdeleted\-function\fP .sp This suppression specification applies to functions that have been removed from the binary. .IP \(bu 2 \fBall\fP .sp This suppression specification applies to functions that have all of the changes above. Note that not providing the \fBchange_kind\fP property at all is equivalent to setting it to the value \fBall\fP\&. .UNINDENT .UNINDENT .UNINDENT .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBdrop\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBdrop\fP \fB=\fP yes | no .UNINDENT .UNINDENT .sp 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 \fI\%early suppression specification mode\fP\&. The net effect is that it potentially reduces the memory used to represent the ABI being analyzed. .sp Please note that for this property to be effective, the enclosing suppression specification must have at least one of the following properties specified: \fBname_regexp\fP, \fBname\fP, \fBname_regexp\fP, \fBsource_location_not_in\fP or \fBsource_location_not_regexp\fP\&. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBfile_name_not_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBfile_name_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .IP \(bu 2 \fBfile_name_regexp\fP .sp Usage: .sp \fBfile_name_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .sp 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. .IP \(bu 2 \fBlabel\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBlabel\fP \fB=\fP .UNINDENT .UNINDENT .sp This property is the same as the \fI\%label property\fP defined above. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBname\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBname\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose name equals the value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBname_not_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBname_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose names don’t match the regular expression specified as value of this property. .sp The rules for functions that have several symbol names are the same rules as for the \fBname_regexp\fP property above. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBname_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBname_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose name matches the regular expression specified as value of this property. .sp 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. .sp 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. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBparameter\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBparameter\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose parameters match the parameter specification indicated as value of this property. .sp The format of the function parameter specification is: .sp \fB\(aq\fP \fB\fP \fB\fP \fB\fP .sp 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. .sp If the parameter type name is designated by a regular expression, then said regular expression must be enclosed between two slashes; like \fB/some\-regular\-expression/\fP\&. .sp 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. .sp Examples of function parameter specifications are: .INDENT 0.0 .INDENT 3.5 .sp .EX \(aq0 int .EE .UNINDENT .UNINDENT .sp Which means, the parameter at index 0, whose type name is \fBint\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX \(aq4 unsigned char* .EE .UNINDENT .UNINDENT .sp Which means, the parameter at index 4, whose type name is \fBunsigned char*\fP\&. .INDENT 0.0 .INDENT 3.5 .sp .EX \(aq2 /^foo.*&/ .EE .UNINDENT .UNINDENT .sp 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”. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBreturn_type_name\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBreturn_type_name\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose return type name equals the value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBreturn_type_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBreturn_type_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose return type name matches the regular expression specified as value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsoname_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBsoname_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .IP \(bu 2 \fBsoname_not_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBsoname_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .IP \(bu 2 \fBsymbol_name\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsymbol_name\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose symbol name equals the value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsymbol_name_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsymbol_name_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose symbol name matches the regular expression specified as value of this property. .sp 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. .sp 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. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsymbol_name_not_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsymbol_name_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose symbol name does not match the regular expression specified as value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsymbol_version\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsymbol_version\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose symbol version equals the value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsymbol_version_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsymbol_version_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving functions whose symbol version matches the regular expression specified as value of this property. .UNINDENT .UNINDENT .SS \fB[suppress_variable]\fP .sp This directive suppresses report messages about changes on a set of variables. .sp Note that for the \fB[suppress_variable]\fP directive to work, at least one of the following properties must be provided: .INDENT 0.0 .INDENT 3.5 \fBlabel\fP, \fBfile_name_regexp\fP, \fBfile_name_not_regexp\fP, \fBsoname_regexp\fP, \fBsoname_not_regexp\fP, \fBname\fP, \fBname_regexp\fP, \fBname_not_regexp\fP, \fBsymbol_name\fP, \fBsymbol_name_regexp\fP, \fBsymbol_name_not_regexp\fP, \fBsymbol_version\fP, \fBsymbol_version_regexp\fP, \fBtype_name\fP, \fBtype_name_regexp\fP\&. .UNINDENT .UNINDENT .sp If none of the above properties are provided, then the \fB[suppress_variable]\fP directive is simply ignored. .sp The potential properties of this sections are: .INDENT 0.0 .IP \(bu 2 \fBlabel\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBlabel\fP \fB=\fP .UNINDENT .UNINDENT .sp This property is the same as the \fI\%label property\fP defined above. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBfile_name_regexp\fP .sp Usage: .sp \fBfile_name_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .sp 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. .IP \(bu 2 \fBfile_name_not_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBfile_name_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .IP \(bu 2 \fBsoname_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBsoname_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .IP \(bu 2 \fBsoname_not_regexp\fP .sp Usage: .INDENT 2.0 .INDENT 3.5 \fBsoname_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp 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. .IP \(bu 2 \fBname\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBname\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving variables whose name equals the value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBname_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBname_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving variables whose name matches the regular expression specified as value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBchange_kind\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBchange_kind\fP \fB=\fP .UNINDENT .UNINDENT .sp 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 \fI\%used in the [suppress_function] section\fP\&. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsymbol_name\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsymbol_name\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving variables whose symbol name equals the value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 symbol_name_regexp .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsymbol_name_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving variables whose symbol name matches the regular expression specified as value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsymbol_name_not_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsymbol_name_not_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving variables whose symbol name does not match the regular expression specified as value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsymbol_version\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsymbol_version\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving variables whose symbol version equals the value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBsymbol_version_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBsymbol_version_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving variables whose symbol version matches the regular expression specified as value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBtype_name\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBtype_name\fP \fB=\fP .UNINDENT .UNINDENT .sp Suppresses change reports involving variables whose type name equals the value of this property. .UNINDENT .UNINDENT .INDENT 0.0 .IP \(bu 2 \fBtype_name_regexp\fP .UNINDENT .INDENT 0.0 .INDENT 3.5 Usage: .INDENT 0.0 .INDENT 3.5 \fBtype_name_regexp\fP \fB=\fP <\fI\%regular\-expression\fP> .UNINDENT .UNINDENT .sp Suppresses change reports involving variables whose type name matches the regular expression specified as value of this property. .UNINDENT .UNINDENT .SS Comments .sp \fB;\fP or \fB#\fP ASCII character at the beginning of a line indicates a comment. Comment lines are ignored. .SS Code examples .INDENT 0.0 .IP 1. 3 Suppressing change reports about types. .sp Suppose we have a library named \fBlibtest1\-v0.so\fP which contains this very useful code: .INDENT 3.0 .INDENT 3.5 .sp .EX $ 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 }; $ .EE .UNINDENT .UNINDENT .UNINDENT .sp 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 \fBlibtest1\-v1.so\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX $ 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 }; $ .EE .UNINDENT .UNINDENT .sp Let’s compile both examples. We shall not forget to compile them with debug information generation turned on: .INDENT 0.0 .INDENT 3.5 .sp .EX $ g++ \-shared \-g \-Wall \-o libtest1\-v0.so test1\-v0.cc $ g++ \-shared \-g \-Wall \-o libtest1\-v1.so test1\-v1.cc .EE .UNINDENT .UNINDENT .sp Let’s ask \fI\%abidiff\fP which ABI differences it sees between \fBlibtest1\-v0.so\fP and \fBlibtest1\-v1.so\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX $ 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]\(aqfunction void foo(opaque_type*)\(aq has some indirect sub\-type changes: parameter 0 of type \(aqopaque_type*\(aq has sub\-type changes: in pointed to type \(aqstruct opaque_type\(aq: size changed from 64 to 96 bits 1 data member insertion: \(aqchar opaque_type::added_member\(aq, at offset 0 (in bits) 2 data member changes: \(aqint opaque_type::member0\(aq offset changed from 0 to 32 \(aqchar opaque_type::member1\(aq offset changed from 32 to 64 .EE .UNINDENT .UNINDENT .sp So \fBabidiff\fP 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 (\fBstruct opaque_type\fP) of an exported function (\fBfoo()\fP) 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 \fBfoo()\fP and the type \fBstruct opaque_type\fP is to stay away from the data members of the type. So layout changes of \fBstruct opaque_type\fP should not impact \fBfoo()\fP\&. .sp Now to teach \fBabidiff\fP about this soft contract and have it avoid emitting what amounts to false positives in this case, we write the suppression specification file below: .INDENT 0.0 .INDENT 3.5 .sp .EX $ cat test1.suppr [suppress_type] type_kind = struct name = opaque_type .EE .UNINDENT .UNINDENT .sp Translated in plain English, this suppression specification would read: “Do not emit change reports about a struct which name is opaque_type”. .sp Let’s now invoke \fBabidiff\fP on the two versions of the library again, but this time with the suppression specification: .INDENT 0.0 .INDENT 3.5 .sp .EX $ 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 .EE .UNINDENT .UNINDENT .sp As you can see, \fBabidiff\fP does not report the change anymore; it tells us that it was filtered out instead. .sp Suppressing change reports about types with data member insertions .sp Suppose the first version of a library named \fBlibtest3\-v0.so\fP has this source code: .INDENT 0.0 .INDENT 3.5 .sp .EX /* 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\(aqt change the offset of member1. Right? */ }; int foo(struct S* s) { return s\->member0 + s\->member1; } .EE .UNINDENT .UNINDENT .sp Now, suppose the second version of the library named \fBlibtest3\-v1.so\fP 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: .INDENT 0.0 .INDENT 3.5 .sp .EX /* 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; } .EE .UNINDENT .UNINDENT .sp In libtest3\-v1.so, adding char data members \fBS::inserted1\fP and \fBS::inserted2\fP 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 \fBabidiff\fP on these two versions of library yields: .INDENT 0.0 .INDENT 3.5 .sp .EX $ 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]\(aqfunction int foo(S*)\(aq has some indirect sub\-type changes: parameter 0 of type \(aqS*\(aq has sub\-type changes: in pointed to type \(aqstruct S\(aq: type size changed from 64 to 96 bits 2 data member insertions: \(aqchar S::inserted1\(aq, at offset 8 (in bits) \(aqchar S::inserted2\(aq, at offset 64 (in bits) $ .EE .UNINDENT .UNINDENT .sp That is, \fBabidiff\fP 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. .sp Luckily, we can devise a suppression specification that essentially tells abidiff to filter out change reports about adding a data member between \fBS::member0\fP and \fBS::member1\fP, 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: .INDENT 0.0 .INDENT 3.5 .sp .EX [suppress_type] name = S has_data_member_inserted_between = {offset_after(member0), offset_of(member1)} has_data_member_inserted_at = end .EE .UNINDENT .UNINDENT .sp Now running \fBabidiff\fP with this suppression specification yields: .INDENT 0.0 .INDENT 3.5 .sp .EX $ ../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 $ .EE .UNINDENT .UNINDENT .sp Hooora! \eo/ (I guess) .sp Suppressing change reports about types accessed either directly or through pointers .sp Suppose we have a first version of an object file which source code is the file widget\-v0.cc below: .INDENT 0.0 .INDENT 3.5 .sp .EX // 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 ... } .EE .UNINDENT .UNINDENT .sp 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 \fBstruct widget\fP; here is what the content of that file would look like: .INDENT 0.0 .INDENT 3.5 .sp .EX // 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 ... } .EE .UNINDENT .UNINDENT .sp When we invoke \fBabidiff\fP on the object files resulting from the compilation of the two file above, here is what we get: .INDENT 0.0 .INDENT 3.5 .sp .EX $ 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]\(aqfunction void fun0(widget*)\(aq has some indirect sub\-type changes: parameter 1 of type \(aqwidget*\(aq has sub\-type changes: in pointed to type \(aqstruct widget\(aq: type size changed from 64 to 128 bits 2 data member insertions: \(aqint widget::w\(aq, at offset 64 (in bits) \(aqint widget::h\(aq, at offset 96 (in bits) [C]\(aqfunction void fun2(widget)\(aq has some indirect sub\-type changes: parameter 1 of type \(aqstruct widget\(aq has sub\-type changes: details were reported earlier $ .EE .UNINDENT .UNINDENT .sp I guess a little bit of explaining is due here. \fBabidiff\fP detects that two data member got added at the end of \fBstruct widget\fP\&. it also tells us that the type change impacts the exported function \fBfun0()\fP which uses the type \fBstruct widget\fP through a pointer, in its signature. .sp Careful readers will notice that the change to \fBstruct widget\fP also impacts the exported function \fBfun1()\fP, that uses type \fBstruct widget\fP through a reference. But then \fBabidiff\fP doesn’t tell us about the impact on that function \fBfun1()\fP because it has evaluated that change as being \fBredundant\fP with the change it reported on \fBfun0()\fP\&. It has thus filtered it out, to avoid cluttering the output with noise. .sp 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. .sp That is why \fBabidiff\fP tells us about the impact that the change to \fBstruct widget\fP has on function \fBfun2()\fP\&. In this case, that function uses the type \fBstruct widget\fP \fBdirectly\fP (in its signature). It does not use it via a pointer or a reference. In this case, the direct use of this type causes \fBfun2()\fP to be exposed to a potentially harmful ABI change. Hence, the report about \fBfun2()\fP is not filtered out, even though it’s about that same change on \fBstruct widget\fP\&. .sp 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 \fBstruct widget\fP change when it impacts uses of \fBstruct widget\fP through a pointer or reference. In other words, suppress the change reports about \fBfun0()\fP \fBand\fP \fBfun1()\fP\&. We would then write this suppression specification, in file \fBwidget.suppr\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX [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 \(aqstruct widget\(aq, 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. .EE .UNINDENT .UNINDENT .sp Invoking \fBabidiff\fP on \fBwidget\-v0.o\fP and \fBwidget\-v1.o\fP with this suppression specification yields: .INDENT 0.0 .INDENT 3.5 .sp .EX $ 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]\(aqfunction void fun2(widget)\(aq has some indirect sub\-type changes: parameter 1 of type \(aqstruct widget\(aq has sub\-type changes: type size changed from 64 to 128 bits 2 data member insertions: \(aqint widget::w\(aq, at offset 64 (in bits) \(aqint widget::h\(aq, at offset 96 (in bits) $ .EE .UNINDENT .UNINDENT .sp As expected, I guess. .sp Suppressing change reports about functions. .sp Suppose we have a first version a library named \fBlibtest2\-v0.so\fP whose source code is: .INDENT 0.0 .INDENT 3.5 .sp .EX $ 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 } $ .EE .UNINDENT .UNINDENT .sp And then we come up with a second version \fBlibtest2\-v1.so\fP of that library; the source code is modified by making the structures \fBS1\fP, \fBS2\fP, \fBS3\fP inherit another struct: .INDENT 0.0 .INDENT 3.5 .sp .EX $ 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 } $ .EE .UNINDENT .UNINDENT .sp Now let’s build the two libraries: .INDENT 0.0 .INDENT 3.5 .sp .EX g++ \-Wall \-g \-shared \-o libtest2\-v0.so test2\-v0.cc g++ \-Wall \-g \-shared \-o libtest2\-v0.so test2\-v0.cc .EE .UNINDENT .UNINDENT .sp Let’s look at the output of \fBabidiff\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX $ 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]\(aqfunction unsigned int func(S3)\(aq has some indirect sub\-type changes: parameter 0 of type \(aqstruct S3\(aq has sub\-type changes: size changed from 32 to 64 bits 1 base class insertion: struct base_type 1 data member change: \(aqint S3::m0\(aq offset changed from 0 to 32 [C]\(aqfunction char func(S2*)\(aq has some indirect sub\-type changes: parameter 0 of type \(aqS2*\(aq has sub\-type changes: in pointed to type \(aqstruct S2\(aq: size changed from 32 to 64 bits 1 base class insertion: struct base_type 1 data member change: \(aqint S2::m0\(aq offset changed from 0 to 32 [C]\(aqfunction int func(S1&)\(aq has some indirect sub\-type changes: parameter 0 of type \(aqS1&\(aq has sub\-type changes: in referenced type \(aqstruct S1\(aq: size changed from 32 to 64 bits 1 base class insertion: struct base_type 1 data member change: \(aqint S1::m0\(aq offset changed from 0 to 32 $ .EE .UNINDENT .UNINDENT .sp Let’s tell \fBabidiff\fP to avoid showing us the differences on the overloads of \fBfunc\fP that takes either a pointer or a reference. For that, we author this simple suppression specification: .INDENT 0.0 .INDENT 3.5 .sp .EX $ cat \-n libtest2.suppr 1 [suppress_function] 2 name = func 3 parameter = \(aq0 S1& 4 5 [suppress_function] 6 name = func 7 parameter = \(aq0 S2* $ .EE .UNINDENT .UNINDENT .sp And then let’s invoke \fBabidiff\fP with the suppression specification: .INDENT 0.0 .INDENT 3.5 .sp .EX $ ../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]\(aqfunction unsigned int func(S3)\(aq has some indirect sub\-type changes: parameter 0 of type \(aqstruct S3\(aq has sub\-type changes: size changed from 32 to 64 bits 1 base class insertion: struct base_type 1 data member change: \(aqint S3::m0\(aq offset changed from 0 to 32 .EE .UNINDENT .UNINDENT .sp The suppression specification could be reduced using \fI\%regular expressions\fP: .INDENT 0.0 .INDENT 3.5 .sp .EX $ cat \-n libtest2\-1.suppr 1 [suppress_function] 2 name = func 3 parameter = \(aq0 /^S.(&|\e\e*)/ $ $ ../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]\(aqfunction unsigned int func(S3)\(aq has some indirect sub\-type changes: parameter 0 of type \(aqstruct S3\(aq has sub\-type changes: size changed from 32 to 64 bits 1 base class insertion: struct base_type 1 data member change: \(aqint S3::m0\(aq offset changed from 0 to 32 $ .EE .UNINDENT .UNINDENT .SH AUTHOR Dodji Seketeli .SH COPYRIGHT 2014-2024, Red Hat, Inc. .\" Generated by docutils manpage writer. .