abicheck(1) | General Commands Manual | abicheck(1) |
abicheck - check application binaries for calls to private or evolving symbols in libraries and for static linking of some system libraries.
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
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.
The following options are supported:
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,
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.
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.
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).
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.
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:
There is one line per problem (there may be multiple problems per binary checked) which look like the following:
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:
(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 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.
The following exit values are returned:
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 - ...
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.
ld(1), ldd(1),
26 August 2003 |