NAME
abicheck - check application binaries for calls to private or evolving
symbols in libraries and for static linking of some system libraries.
SYNOPSIS
abicheck [-h] [-k] [-a] [-I] [-v] [-f listfile] [-o outfile] [-p
pattern] [-e pattern] [-j njobs] [-l library] [-L ldpath] [(-s|-S)
dbfile] [(-d|-D) dbfile] [-O dbfile] [-A listfile] files
DESCRIPTION
abicheck 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 library package.
· 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.
OPTIONS
The following options are supported:
-k Keep on checking binaries even if there are serious errors
(dynamic linker reports unresolved symbols, ldd(1) failures, no
symbols detected).
-h Print out long form of help.
-v 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,
-p ’FOO_VERS.*::_foopriv’
or
-p ’libfoo.so.*::_foopriv’
-e pattern
Same as -p but for "evolving" interfaces.
-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 random.
-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.
-a 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 recorded.)
-I 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 these forms:
library|symbol
library|class|symbol
library|FILE=path
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:
library|symbol|class
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 use.
Examples:
libfoo.so.1|__bar|private
/lib/libxyz.so.1|baz|public
__SKIP__|__fputwc_xpg5
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:
shmat|/usr/lib/libc.a:shmsys.o
shmctl|/usr/lib/libc.a:shmsys.o
shmdt|/usr/lib/libc.a:shmsys.o
shmget|/usr/lib/libc.a:shmsys.o
...
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
internal database.
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 finishes.
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).
OPERANDS
The following operands are supported:
files A list of application binary objects to check.
OUTPUT
There is one line per problem (there may be multiple problems per
binary checked) which look like the following:
If no problems were found:
filename: OK
If private symbol usage:
filename: PRIVATE (library:private_version) private_sym
If evolving symbol usage:
filename: EVOLVING (library:evolving_vers) evolving_sym
If file statically linked in a system archive library:
filename: STATIC_LINK (archive)
If checking of the file was skipped:
filename: 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:
filename: DELETED_SYM: symbol/library
(library will be "unbound" if the symbol was unbound)
If an entire library has been deleted on some release or is
otherwise unstable to use:
filename: UNSTABLE_LIB: library-soname = library-path
(library-path may be "file not found" if the library could not
be found)
The following problems will cause a fatal error unless the -k option is
used:
If the dynamic linker could not resolve N symbols when ldd -r
was run:
filename: UNBOUND_SYMBOLS: N
If the dynamic linker found no dynamic bindings:
filename: NO_BINDINGS
If ldd -r with LD_DEBUG=files,bindings failed:
filename: LDD_ERROR
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 with
LD_DEBUG=files,bindings set). On some systems the dynamic linker will
not process SUID programs with LD_DEBUG set (this usually results in
NO_BINDINGS in the abicheck output).
Note that if you are running abicheck on a shared library (for example,
libfoo.so) that has not been built with -l lib flags to 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 -l option of abicheck.
EXIT STATUS
The following exit values are returned:
0 No errors and no problems found.
1 A fatal error occurred.
2 No fatal errors occurred, but some binaries had problems
detected.
NOTES
Only ELF objects are checked.
In the -s -S -d and -O dbfiles the ’#’ character starts a comment line
in the usual way.
Unless one is using the "::" custom matches supplied via the -p or -e
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 - ...
BUGS
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, abicheck will break whenever the output format
changes. On Solaris it is possible that the Link Auditing C interface
could be used to avoid this problem.
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 copies instead.
SEE ALSO
ld(1), ldd(1),
26 August 2003 abicheck(1)