проверить совместимость ABI (check ABI compatibility)
Имя (Name)
abicompat - check ABI compatibility
abicompat checks that an application that links against a given
shared library is still ABI compatible with a subsequent version
of that library. If the new version of the library introduces an
ABI incompatibility, then abicompat hints the user at what
exactly that incompatibility is.
Вызов (Invocation)
abicompat [options] [<application> <shared-library-first-version> <shared-library-second-version>]
Параметры (Options)
• --help
Display a short help about the command and exit.
• --version | -v
Display the version of the program and exit.
• --list-undefined-symbols | -u
Display the list of undefined symbols of the application and
exit.
• --show-base-names | -b
In the resulting report emitted by the tool, this option
makes the application and libraries be referred to by their
base names only; not by a full absolute name. This can be
useful for use in scripts that wants to compare names of the
application and libraries independently of what their
directory names are.
• --app-debug-info-dir | --appd
<path-to-app-debug-info-directory>
Set the path to the directory under which the debug
information of the application is supposed to be laid out.
This is useful for application binaries for which the debug
info is in a separate set of files.
• --lib-debug-info-dir1 | --libd1
<path-to-lib1-debug-info>
Set the path to the directory under which the debug
information of the first version of the shared library is
supposed to be laid out. This is useful for shared library
binaries for which the debug info is in a separate set of
files.
• --lib-debug-info-dir2 | --libd2
<path-to-lib1-debug-info>
Set the path to the directory under which the debug
information of the second version of the shared library is
supposed to be laid out. This is useful for shared library
binaries for which the debug info is in a separate set of
files.
• --suppressions | --suppr
<path-to-suppressions>
Use a suppression specification file located at
path-to-suppressions. Note that this option can appear
multiple times on the command line; all the suppression
specification files are then taken into account.
• --no-show-locs
Do not show information about where in the second shared
library the respective type was changed.
• --weak-mode
This triggers the weak mode of abicompat
. In this mode,
only one version of the library is required. That is,
abicompat is invoked like this:
abicompat --weak-mode <the-application> <the-library>
Note that the --weak-mode
option can even be omitted if only
one version of the library is given, along with the
application; in that case, abicompat
automatically switches
to operate in weak mode:
abicompat <the-application> <the-library>
In this weak mode, the types of functions and variables
exported by the library and consumed by the application (as
in, the symbols of the these functions and variables are
undefined in the application and are defined and exported by
the library) are compared to the version of these types as
expected by the application. And if these two versions of
types are different, abicompat
tells the user what the
differences are.
In other words, in this mode, abicompat
checks that the
types of the functions and variables exported by the library
mean the same thing as what the application expects, as far
as the ABI is concerned.
Note that in this mode, abicompat doesn't detect exported
functions or variables (symbols) that are expected by the
application but that are removed from the library. That is
why it is called weak
mode.
Возвращаемое значение (Return value)
The exit code of the abicompat
command is either 0 if the ABI of
the binaries being compared are equal, or non-zero if they differ
or if the tool encountered an error.
In the later case, the exit code is a 8-bits-wide bit field in
which each bit has a specific meaning.
The first bit, of value 1, named ABIDIFF_ERROR
means there was an
error.
The second bit, of value 2, named ABIDIFF_USAGE_ERROR
means there
was an error in the way the user invoked the tool. It might be
set, for instance, if the user invoked the tool with an unknown
command line switch, with a wrong number or argument, etc. If
this bit is set, then the ABIDIFF_ERROR
bit must be set as well.
The third bit, of value 4, named ABIDIFF_ABI_CHANGE
means the ABI
of the binaries being compared are different.
The fourth bit, of value 8, named ABIDIFF_ABI_INCOMPATIBLE_CHANGE
means the ABI of the binaries compared are different in an
incompatible way. If this bit is set, then the
ABIDIFF_ABI_CHANGE
bit must be set as well. If the
ABIDIFF_ABI_CHANGE
is set and the ABIDIFF_INCOMPATIBLE_CHANGE
is
NOT set, then it means that the ABIs being compared might or
might not be compatible. In that case, a human being needs to
review the ABI changes to decide if they are compatible or not.
The remaining bits are not used for the moment.
Примеры использования (Usage example)
• Detecting a possible ABI incompatibility in a new shared
library version:
$ cat -n test0.h
1 struct foo
2 {
3 int m0;
4
5 foo()
6 : m0()
7 {}
8 };
9
10 foo*
11 first_func();
12
13 void
14 second_func(foo&);
15
16 void
17 third_func();
$
$ cat -n test-app.cc
1 // Compile with:
2 // g++ -g -Wall -o test-app -L. -ltest-0 test-app.cc
3
4 #include "test0.h"
5
6 int
7 main()
8 {
9 foo* f = first_func();
10 second_func(*f);
11 return 0;
12 }
$
$ cat -n test0.cc
1 // Compile this with:
2 // g++ -g -Wall -shared -o libtest-0.so test0.cc
3
4 #include "test0.h"
5
6 foo*
7 first_func()
8 {
9 foo* f = new foo();
10 return f;
11 }
12
13 void
14 second_func(foo&)
15 {
16 }
17
18 void
19 third_func()
20 {
21 }
$
$ cat -n test1.h
1 struct foo
2 {
3 int m0;
4 char m1; /* <-- a new member got added here! */
5
6 foo()
7 : m0(),
8 m1()
9 {}
10 };
11
12 foo*
13 first_func();
14
15 void
16 second_func(foo&);
17
18 void
19 third_func();
$
$ cat -n test1.cc
1 // Compile this with:
2 // g++ -g -Wall -shared -o libtest-1.so test1.cc
3
4 #include "test1.h"
5
6 foo*
7 first_func()
8 {
9 foo* f = new foo();
10 return f;
11 }
12
13 void
14 second_func(foo&)
15 {
16 }
17
18 /* Let's comment out the definition of third_func()
19 void
20 third_func()
21 {
22 }
23 */
$
• Compile the first and second versions of the libraries:
libtest-0.so
and libtest-1.so
:
$ g++ -g -Wall -shared -o libtest-0.so test0.cc
$ g++ -g -Wall -shared -o libtest-1.so test1.cc
• Compile the application and link it against the first
version of the library, creating the test-app
binary:
$ g++ -g -Wall -o test-app -L. -ltest-0.so test-app.cc
• Now, use abicompat
to see if libtest-1.so is ABI
compatible with app, with respect to the ABI of
libtest-0.so:
$ abicompat test-app libtest-0.so libtest-1.so
ELF file 'test-app' might not be ABI compatible with 'libtest-1.so' due to differences with 'libtest-0.so' below:
Functions changes summary: 0 Removed, 2 Changed, 0 Added functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
2 functions with some indirect sub-type change:
[C]'function foo* first_func()' has some indirect sub-type changes:
return type changed:
in pointed to type 'struct foo':
size changed from 32 to 64 bits
1 data member insertion:
'char foo::m1', at offset 32 (in bits)
[C]'function void second_func(foo&)' has some indirect sub-type changes:
parameter 0 of type 'foo&' has sub-type changes:
referenced type 'struct foo' changed, as reported earlier
$
• Now use the weak mode of abicompat, that is, providing
just the application and the new version of the library:
$ abicompat --weak-mode test-app libtest-1.so
functions defined in library
'libtest-1.so'
have sub-types that are different from what application
'test-app'
expects:
function foo* first_func():
return type changed:
in pointed to type 'struct foo':
size changed from 32 to 64 bits
1 data member insertion:
'char foo::m1', at offset 32 (in bits)
$