abicheck - check application binaries for calls to private or evolving symbols
in libraries and for static linking of some system libraries.
[-h] [-k] [-a] [-I] [-v] [-f listfile]
[-A listfile] files
is run on application binaries and issues warnings whenever any
of the following three conditions are detected:
• Private symbol usage.
Private symbols are functions or data
variables in a library package that are internal to that package. They are
used by the libraries in the package for internal communication and are not
part of the API/ABI that application developers should use.
• Evolving symbol usage.
Evolving symbols are functions or data
variables in a library package that are intended for developer consumption,
but have been marked as "evolving" or "unstable" in the
sense that they may become incompatible or disappear on a later release of the
• Static linking.
Static linking of system libraries (for example,
libc.a) into an application is generally not a good idea because the system
library code it "locks" into the application binary may become
incompatible with later releases of the system. abicheck attempts to detect
static linking of a few system libraries.
The default behavior is, for each binary object checked, to examine direct calls
from that binary object only. The -l
option allows the libraries the
binary object brings in to have their calls checked as well.
The following options are supported:
- Keep on checking binaries even if there are serious errors
(dynamic linker reports unresolved symbols, ldd(1) failures, no
- Print out long form of help.
- Verbose. Print out additional information.
- -f listfile
- The listfile is a file containing a list of binary
objects to check, one per line. This list is appended to any files
provided as arguments on the command line. If listfile is
"-", then stdin is used.
- -o outfile
- Write output to outfile instead of stdout.
- -p pattern
- Modify the version name pattern match labelling private
version sets. Default is /private/ using a case-insensitive match.
If a component of the regex pattern contains two colons in a row:
patt1::patt2, then symbol-level matching will be activated by
checking whether version::symbol or library::symbol matches
pattern (where the symbol name, version (if any), and library
basename are substituted for symbol, version, and
library). For example,
- -e pattern
- Same as -p but for "evolving"
- -L ldpath
- Set the LD_LIBRARY_PATH environment variable to
ldpath before invoking dynamic linker. Use -L ""
to unset LD_LIBRARY_PATH.
If one of the components of ldpath is the string "find",
then all shared libraries in files are found and their paths
inserted into the "find" location. Note that the order will
- -l library
- Add the basename or full pathname of the shared library
library to the list of objects to be checked for making private
calls. This option may occur more than once on the command line and is
additive. By default, only direct calls from a binary to the system
libraries are checked. The -l switch allows checking of indirect
calls e.g.: app -> supportlib -> systemlib.
- Loop through all of the binaries before checking and
collect the list of all shared objects. Take the basename of each shared
object found and act as though it was specified with the -l option
option and then run the abicheck checks. This way, calls from all
"application internal" objects are checked rather than just the
direct calls. (Useful when shared objects do not have their dependencies
- Ignore shared libraries in checking, only check
executables. Compatible with -a, libraries will be searched for
first but then not checked.
- -d dbfile, -D dbfile
- Specify fallback flat-file symbol database for the dynamic
(public vs. private) test. These classifications will be used if the
library is not versioned (i.e. classification does not exist in the
library itself). Use -D to indicate that only information from
dbfile should be used. Lines in dbfile can be of one of
library must be the full path to the library to be specified (it
cannot be a basename).
The first form marks symbol as private.
The second form marks symbol with class where class may
be public, private, or evolving.
The third form indicates the file path should be opened on demand
when library is first encountered. File path contains lines
of the first two forms except for the library field. The third form
is a speedup to avoid processing many classification lines for libraries
never encountered in the run.
- -O dbfile
- Specify an override file to modify the symbol
classification for the dynamic (public vs. private) test. The format for
the override file is like:
The library can be the full path or basename. If library is
"__SKIP__" the symbol will be ignored for any library it is
found in. The class can be "public", "private",
"evolving", or "deleted". The "deleted"
class is special-cased, means the symbol was deleted from the library on
some release. The symbol "__ALL__" for the "deleted"
class means the entire library was deleted or is otherwise unstable to
These settings override any classification inside the library (from library
versioning, obtainable from pvs(1), etc).
- -A listfile
- Set the ABI libraries of interest to the libraries listed
in listfile (full pathnames, one per line). Only calls into these
libraries will be checked; all other library calls will be ignored.
- -s dbfile, -S dbfile
- Specify more extensive symbol databases for the static
linking test. dbfile may be a comma separated list of files. If a
file is a static archive (lib*.a) it is processed to extract the symbols.
Otherwise it is a database file consisting of lines of the form
symbol|library:module for example:
When all symbols in a module.o are defined in the application, static
linking of that module (and corresponding library archive) is assumed. Use
-S to indicate that only the static link test should be performed.
Use -S int to do only the static link check and using the
Use -s none or -S none to skip the static
linking check entirely.
- -j njobs
- Run njobs in parallel as separate processes. Implies
-k. Primarily intended for multiple CPU machines where njobs
should be close to the number of processors. Output is collected in tmp
files and printed all at once near the end of the run as each job
If njobs is "-", "detect", or "n", then
njobs will be set to a number depending on the number of processors
on the current machine (if that can be determined).
The following operands are supported:
- A list of application binary objects to check.
There is one line per problem (there may be multiple problems per binary
checked) which look like the following:
If no problems were found:
If private symbol usage:
PRIVATE ( library
If evolving symbol usage:
: EVOLVING (library
If file statically linked in a system archive library:
: STATIC_LINK (archive
If checking of the file was skipped:
: SKIP (reason
Under use of the deleted class in the -O
override file option, these
problems may be found:
If a symbol has been deleted from the library
on some release:
: DELETED_SYM: symbol
will be "unbound" if the symbol was unbound)
If an entire library has been deleted on some release or is otherwise unstable
: UNSTABLE_LIB: library-soname
may be "file not found" if the library could not
The following problems will cause a fatal error unless the -k
If the dynamic linker could not resolve
symbols when ldd -r
: UNBOUND_SYMBOLS: N
If the dynamic linker found no dynamic bindings:
If ldd -r
In these latter three cases run ldd -r
on the binary file for more
information on what went wrong (note that abicheck
runs ldd -r
set). On some systems the dynamic linker
will not process SUID programs with LD_DEBUG
set (this usually results
in the abicheck
Note that if you are running abicheck on a shared library (for example,
libfoo.so) that has not
been built with -l lib
record its library dependencies, then the "unbound symbols" problem
is very likely. There is not much that can be done besides rebuilding the
library or checking an application binary that uses the library and using the
option of abicheck.
The following exit values are returned:
- No errors and no problems found.
- A fatal error occurred.
- No fatal errors occurred, but some binaries had problems
Only ELF objects are checked.
In the -s -S -d
dbfiles the '#' character
starts a comment line in the usual way.
Unless one is using the "::" custom matches supplied via the -p
flags, abicheck can only check against system libraries that have
had symbol versioning applied to them (i.e. the private and/or evolving
information recorded for each symbol in the library itself). For more info
about symbol versioning, see the "Solaris Linker and Libraries
Guide" answerbook at the URL http://docs.sun.com/ab2/coll.45.13 and the
Commands/Version-Script section of the GNU linker "ld" info page.
The default symbol version name matching patterns are case insensitive matches
to the strings "private" and "evolving" for the private
and evolving cases, respectively.
Odd filenames containing the single-quote character or newline will be skipped;
such characters interfere with calling commands via the shell.
To recurse directories use find
(1) and either collect the output to a
file for use with the -f
option, or in a pipe in via:
find ... | abicheck -f - ...
The program is dependent on the form of the runtime linker's debug output. Since
this output is intended to be human readable rather than machine readable,
will break whenever the output format changes. On Solaris it
is possible that the Link Auditing C interface could be used to avoid this
On Linux when ldd
(1) is run on a SUID binary, it (ldd and the
dynamic-linker) will sometimes actually run the binary. On Linux SUID/SGID
binaries are currently skipped even if the user is root; test unprivileged