ident "%Z%%M% %I% %E% SMI" Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. CDDL HEADER START The contents of this file are subject to the terms of the Common Development and Distribution License, Version 1.0 only (the "License"). You may not use this file except in compliance with the License. You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] CDDL HEADER END intf_check 1 "20 October 2004"
NAME
intf_check - detect and report possible Solaris ABI stability problems
SYNOPSIS
intf_check [-aimopstVT] [-d intf-dir] [-g ABI_DB_filename] [-r release]
[-b ABI_DB_path] [-A sparc | i386] file | dir, ...
DESCRIPTION
"Solaris ABI Auditing tool" "intf_check" "" "intf_check" The
intf_check tool attempts to check a number of shared objects
for consistency with common build rules and practices for the
OS/
Net
consolidation. In addition, it will audit the version definitions of
any shared object against the Solaris ABI database. (See NOTES section
and
-b option).
intf_check is typically called from nightly(1) when the -A
option is in effect. In this case the shared objects under the associated
proto area ($ROOT) are audited against a Solaris ABI database
(under $SRC/tools/abi/etc).
intf_check can also be run standalone against any set of dynamic objects.
intf_check uses elfdump(1) and various forms of pvs(1) to check file naming
standardization, compilation symbolic link requirements, versioning
consistency, and successive symbolic interface consistency.
To perform its task,
intf_check creates versions databases to allow for the auditing of interfaces and
monitoring of the evolution of the shared objects interfaces. Once these
version databases are created, two types of checking can be performed to
ensure that all the RULES are followed (See RULES section):
4
Discrepancy Checking. This ABI behavior checking compares the latest
release specified in the Solaris ABI database with the file(s)/dir(s) listed
on the command line. All misbehaviors/errors found are reported
to stdout. This is the default behavior performed by
intf_check.
Integrity Checking. This ABI behavior checking compares all releases
specified in the Solaris ABI database with the file(s)/dir(s) listed
on the command line. All misbehaviors/errors found are reported to stdout.
OPTIONS
The following options are supported:
"-a" 6
Prints all releases associated with the Solaris ABI database file
(See NOTES section).
"-b ABI_DB_path" 6
ABI_DB_path must contain the following files: ABI_*.db and exceptions.
By specifying the
-b option, the
file(s)/dir(s) will be audited against the ABI_*.db under the ABI_DB_path (See NOTES section).
"-d intf-dir" 6
Identifies the directory in which to capture a complete breakdown of the
files' version definitions.
intf-dir will reflect the association of the shared object's global symbols with
a recorded
version definition (See
ld(1) and
pvs(1) for details). By default, a temporary
intf-dir is created under
/tmp/abi_audit.$$/ and will be deleted after completion
of auditing against a Solaris ABI database.
"-m" 6
Generate a template SGML man page for each
file containing a public interface. The
-d option must be specified
since the template is deposited into the
intf-dir specified. This is intended as a convenience for new library developers
so that a complete
/usr/man/sman3lib man page, describing the library, and defining its interfaces, can be
constructed.
"-g ABI_DB_filename" 6
Generate an ABI database file
ABI_DB_filename. This is used to provide a mechanism to record Solaris ABI information
on new releases. The Solaris ABI database is generated by this option.
This option must be used in conjunction with the
-r option.
"-r release" 6
Record the release associated with the file(s)/dir(s) on the command line
into the ABI_DB_filename specified with the
-g option. This option
must be used in conjunction with the
-g option.
"-o" 6
Check for omitted libraries by comparing all libraries in ABI_*.db to the
file(s)/dir(s) listed on the command line. This flag is intended for users interested in
auditing against the complete list of libraries present in the ABI_*.db.
"-A sparc | i386" 6
Perform checking against a platform specific ABI database. Any name other
than
sparc and
i386 is currently ignored as an usage error.
"-i" 6
Perform Integrity Checking. This option will audit the snapshot of
the current ABI information in the
intf-dir to all previous releases specified in the Solaris ABI database. Normal
users need not worry about this option.
"-p" 6
Report new Public interfaces introduced in the file(s)/dir(s) as WARNING
(See RULES section, number W7).
"-s" 6
Silence all WARNING messages (See OUTPUT MESSAGES section for details). This
option overrides the
-p and
-t options.
"-t" 6
Report symbol transitions from private to public as WARNING (See RULES section, number W8).
"-T" 6
Report symbol transitions from private to unexported as WARNING (See RULES section, number W6).
"-V" 6
Report version number of this tool.
Specifying the -g option overrides the -i, -t,
and -o options.
In addition, the -A and -b options are mutually exclusive.
No file(s)/dir(s) need to be specified with the -V and -a options.
OPERANDS
The following operands are supported:
"file | dir ..." 6
The path name of a
file or a directory containing shared objects to be audited.
OUTPUT
Standard Output
OUTPUT FILES
By default, a more detailed breakdown of shared objects versioning is
stored in a temporary
intf-dir under
/tmp/abi_audit.$$ (See -d option to specify an alternative intf-dir).
This directory will be used as the current
build/
release in auditing
with the previous Solaris release(s).
There are several version databases created under the
intf-dir:
"Public-32 or Public-64" 6
Shared objects that provide public version definitions are recorded as
file control directives. These files therefore describe the public
interfaces available for a particular release, and may be used by the
link-editor (
ld(1)) to control symbol binding when building other
objects.
"audit/" 6
All version definitions found within a shared object, together with their
associated symbols, are recorded within an audit subdirectory. Each
object is identified by an individual file that identifies the object's
name.
In addition, since multiple objects with the same name may exist under
different pathnames, each name is uniquely identified by its install
location as well, e.g.
libcurses.so.1 exists in the
following install locations:
In order to resolve the path names, the shared objects are matched against
libraries found in the Solaris ABI database. Heuristics are then used
to narrow the possible path names corresponding to the shared object
(e.g., path names containing sparcv9 are eliminated if the
file is a 32-bit shared object. See file(1) for details.)
If multiple matches are still found for a particular shared object, a message
is reported to STDERR and the first match will be used for auditing.
If no match is found in the ABI_*.db, then the relative pathname is used
to identify this shared object. For example, if the
dir passed on the command line is $ROOT, and a new shared object exists
under $ROOT/usr/lib/libfoo.so.1, the new shared object will be
identified by audit/usr=lib=libfoo.so.1.
These files provide a complete cross reference of version-to-interface
relationships and are the basis for auditing interfaces in a shared
object from release to release. Any addition, deletion or regrouping
of versioning information can be detected by checking against
the Solaris ABI database.
"man/" 6
If the
-m option is specified, all template sgml man pages will
be deposited into this directory.
RULES
By default, a shared object will be verified to ensure it has followed
all the RULES listed below. (NOTE: The prefix to the numbers identify the
type of OUTPUT MESSAGE generated when a RULE is violated. The prefix can
be one of two types: "E" for ERROR, or "W" for WARNING). Violation of
the following RULES will yield an ERROR message:
"(E1)" 6
Version definitions must follow a standard naming convention, i.e.,
SUNW_m.n.o, SUNWprivate_m.n, SUNWprivate,
SUNWobsolete or a base version name.
For SUNW_m.n.o and SUNWprivate_m.n, m is the major number,
n is the minor number, and o is an optional micro number.
SUNWobsolete is used to label the whole library which is expected to
end-of-life soon. It is an empty version section containing no symbol
definitions on top of the inheritance chain in the "versions" or mapfile.
The base version name represents the filename and any associated
SONAME, and is used by the compiler/linker as the default "version".
It is used to record any reserved interface symbols generated by the tools
(i.e., _end, _etext, etc.).
In addition, note that non-conforming base version name is often
generated by accident when the file itself has an internal identification
that differs from the actual filename (See ld(1) -h
option for details).
An example would be a file called nss_files.so.1 in the filesystem, but asserts
via its SONAME that it will be called libnss_files.so.1 at
runtime, it is buggered.
A convention for other ABI interface naming would need to use some other
naming convention. SUNW* names only apply to the Solaris ABI.
Note that the reserved version definition names SISCD_2.3[a|b]
and SYSVABI_1.[2|3]
define industry standard interfaces in the System V Interface Definition and
the Sparc Compliance Definition. Do not use these version names when
copying the implementation of standard interfaces to a non-standard library.
Instead, use the Public interface naming convention outlined above.
"(E2)" 6
A proper inheritance chain must be maintained. Version inheritance is
tracked through the versions file under the spec/ subdirectory (See
README.spec
for details). If the subsequent version set is not incremented properly
(i.e., it increments by more that .1 per release of a library), then this
results in a malformed inheritance chain. Errors made in the inheritance
chain prior to 1.1 will be ignored by
intf_check for historical purposes (See
pvs(1) -d option for details).
"(E3)" 6
Public symbols must not be scoped local or removed from a library.
A shared object delivered in a previous software release has made available
all its global symbols for others to bind with. Therefore, if a public
symbol is removed or scoped local on the current release, applications
depending on the removed public interface will break.
"(E4)" 6
Public symbols must not be demoted to private. This is a dangerous
practice since a committed public interface has become unstable.
"(E5)" 6
A new symbol must be assigned to the highest version name of
its library. A version definition exists to allow tracking of all intended
interfaces offered in a given release of the library. Once the integrity
of these version definitions are broken, users of the shared object can no
longer track interfaces offered on each software release. Therefore,
new symbols should be assigned to the current minor release-level of the
library. For new libraries, Public interface versioning begins with SUNW_1.1
while Private interface versioning should be SUNWprivate. If the library
already has Private interfaces, they may have numbered version names like
SUNWprivate_
m.n. If so, just use the highest numbered private
version name for the new interface.
"(E6)" 6
A symbol must remain assigned to the same version throughout the life of the
library. This version indicates when the symbol was first introduced.
If the interface is reassigned to a different version on another release,
its history information is lost.
"(E7)" 6
The highest version number of a library must not be incremented by more than
".1" between releases. Since each version definition indicates the interfaces
applied to each software release, no more than one version definition should
be specified per release of a library.
Note that the major revision number is incremented whenever an incompatible
change is made to an interface. This could be the case if an API changes so
dramatically as to invalidate dependencies. This is expected to rarely occur
in practice.
Also note that micro version numbers are used as a means of managing the
inclusion of a subset of an existing version into a micro release
(i.e., update release, feature patch...) When these subset interfaces are
introduced to a micro release, the symbol version is incremented by a
micro number [m.n.(o++)]. When release N+1 is frozen (at which time it
is expected that no more update releases for release N will be produced),
the micro versions of "N" must be inherited by the "N+1" release.
For example; the "versions" file for minor release "N+1" to reflect its
inclusion of micro release(s) (i.e., m.n.o) will look like the following:
sparc {
SUNW_1.4: {SUNW_1.3.2}; # release N+1
SUNW_1.3.2: {SUNW_1.3.1}; # micro release 2
SUNW_1.3.1: {SUNW_1.3}; # micro release 1
SUNW_1.3: {SUNW_1.2}; # release N
SUNW_1.2: {SUNW_1.1};
SUNW_1.1;
SUNWprivate_1.1;
}
and the corresponding update/patch "versions" file will be:
sparc {
SUNW_1.3.2: {SUNW_1.3.1}; # micro release 2
SUNW_1.3.1: {SUNW_1.3}; # micro release 1
SUNW_1.3: {SUNW_1.2}; # release N
SUNW_1.2: {SUNW_1.1};
SUNW_1.1;
SUNWprivate_1.1;
}
"(E8)" 6
A shared object with an associated compilation environment name must have
a SONAME recorded.
"(E9)" 6
A shared object with an associated compilation environment name and
a recorded SONAME must have its SONAME identical to the actual filename.
"(E10)" 6
When you select a new version name (i.e., SUNW_m.n.o) to version a library
(i.e.,
libfoo.so.4), its major version number chosen must be the same as the
major version number present in its filename (i.e., m = 4).
"(E11)" 6
Sun library filename must not contain any minor version number.
"(E12)" 6
You must not introduce any new public interfaces to an already obsolete library.
Violation of any of the following RULES will yield a WARNING message, but may
be silenced with the -s option (See OUTPUT MESSAGES section):
"(W1)" 6
A shared object should exist with a versioned filename. A versioned
filename commonly takes the form of a
.so suffix followed by a version
number. For example,
/usr/lib/libc.so.1 is the shared object
representation of version one of the standard C library made available to
the runtime environment. A versioned filename allows for a change in the
exported interface of the shared object over a series of software releases.
"(W2)" 6
A shared object containing a public interface should have an associated
compilation environment name. Given that a file does exist as a versioned
filename, a compilation environment filename should also exist if the shared
object offers any public interfaces. This compilation environment name is
typically established as a symbolic link to the latest versioned filename.
In the compilation environment, this name provides for processing by the
link-editor (
ld(1) using the
-l option, and takes the form
of a
lib prefix and
.so suffix.). For example,
libc.so exists
as a compilation symlink for the versioned filename
libc.so.1.
"(W3)" 6
A shared object containing only private interfaces should not have an
associated compilation environment name. Note that it may be the case
that a compilation environment name exists to simplify the building of
other components, however if the versioned filename does not provide a
public interface, a compilation environment name may not be required to be
provided to external users.
"(W4)" 6
A shared object should contain interfaces that are versioned. Versions
should be defined within a shared object both to clarify its public or
private use, and to explicitly define the interfaces that it makes available.
The reduction in object size, and relocation cost created by reducing
non-interface symbols to locals is an added bonus.
"(W5)" 6
Version definitions should offer at least one interface. Note there exist
some legitimate uses of empty version definitions, as interfaces have been
regrouped, and old version definitions must exist to insure backward
compatibility. However other empty interface definitions are typically the
result of cut-and-paste use within spec files.
"(W6)" 6
Private symbols should not be removed or scoped local to a library without
careful analysis of dependencies on these interfaces. Review of your contracts
with those who depend on these private interfaces is advised before changing
any symbols.
"(W7)" 6
A new Public symbol should have a corresponding manpage and a 3lib manpage
entry. If no documentation is available for the interface (i.e., the
interface is meant to be private), then this interface should be labeled
as SUNWprivate.
"(W8)" 6
A committed private (a private contract between the supplier and
external user) interface should not be promoted to public if the transition
involves signature changes. ARC approval is needed to allow such promotions.
"(W9)" 6
Private interfaces should not be introduced to an already obsolete library.
"(W10)" 6
Existing library should not be removed without following the appropriate
SAC "Obsolete and the EOF process".
OUTPUT MESSAGES
All messages reported by
intf_check are classified into two categories:
ERROR and WARNING. These messages are generated when one of the RULES is
violated (See RULES section).
ERROR messages require immediate attention. ARC approval is needed to
exempt these errors. If ARC approval is granted, the
exceptions file should be updated to silence any output messages
(See FILES section). In the nightly
mail_msg log, the section labeled
"Check versioning and ABI information" corresponds to these types of errors.
The following is a list of ERROR messages that may appear:
usr/lib/libfoo.so.1: version name: non-standard version name
(See RULES section, number E1)
usr/lib/libfoo.so.1: old version->version name: invalid inheritance
(See RULES section, number E2)
usr/lib/libfoo.so.1: symbol: was public in 5.8, is now unexported
(See RULES section, number E3)
usr/lib/libfoo.so.1: symbol: was public in 5.8, is now private
(See RULES section, number E4)
usr/lib/libfoo.so.1: symbol: invalid new version,
SUNW_1.20 should be SUNW_1.21 in current release
(See RULES section, number E5)
usr/lib/libfoo.so.1: symbol: base version not maintained,
was SUNW_0.7 in 5.8, becomes SUNW_1.2 in current release
(See RULES section, number E6)
usr/lib/libfoo.so.1: was old version in old release, becomes
version name in current release: inconsistent increment of version
(See RULES section, number E7)
usr/lib/libfoo.so.1: no SONAME recorded
(See RULES section, number E8)
usr/lib/libfoo.so.1: SONAME recorded differs from the actual filename
(See RULES section, number E9)
usr/lib/libfoo.so.4: SUNW_1.1: invalid version name, should be SUNW_4.1
to reflect major version
(See RULES section, number E10)
usr/lib/libfoo.so.2.3: invalid library filename; should not use minor
version number (.3) as part of filename
(See RULES section, number E11)
usr/lib/libfoo.so.3: SUNWobsolete->version name: new public
interface introduced to the obsolete library
(See RULES section, number E12)
WARNING messages may not cause immediate application breakage,
but they should be carefully reviewed as they indicate deviations from
standard practices. In the nightly
mail_msg
log, the section labeled "Diff versioning warnings (since last build)"
corresponds to any differences in WARNING messages between the previous
and current builds. The following is a list of WARNING messages that
may appear:
usr/lib/libfoo.so: does not have a versioned name
(See RULES section, number W1)
usr/lib/libfoo.so: no compilation symlink (.so) exists
(See RULES section, number W2)
usr/lib/libfoo.so.1: unnecessary compilation symlink (.so) exists
(See RULES section, number W3)
usr/lib/libfoo.so.1: no versions found
(See RULES section, number W4)
usr/lib/libfoo.so.1: version name: version offers no interfaces
(See RULES section, number W5)
usr/lib/libfoo.so.1: symbol: was private in 5.8, is now unexported
(See RULES section, number W6)
usr/lib/libfoo.so.1: symbol: new public interface introduced
(See RULES section, number W7 and -p option)
usr/lib/libfoo.so.1: symbol: was private in 5.8, is now public
(See RULES section, number W8 and -t option)
usr/lib/libfoo.so.4: SUNWobsolete->SUNWprivate_1.1: new private
interface introduced to the obsolete library
(See RULES section, number W9 and -t option)
usr/lib/libfoo.so.1: library is not found
(See RULES section, number W10)
EXIT STATUS
The following exit values are returned:
"0" 6
Successful completion.
"1" 6
An execution error occurred.
LIMITATIONS
Comparing two snapshots of on81 builds requires approximately 35 MB
swap space (3 MB for each additional build).
NOTES
intf_check skips certain files and directories that are known to contain
shared objects that don't offer public interfaces. Examples are plugins
for mdb and picl, and the ABI tracing interceptors for apptrace.
Note that such skipped directories must not contain shared objects that
do have public interfaces; such shared objects must be versioned and
audited by
intf_check. The list of things to skip is contained in the
intf_check script itself; requests to modify the list should be directed
to either the the Solaris ABI team or the OS/Net gatekeepers.
The Solaris ABI database file contains the ABI information for all
interfaces in one or more Solaris releases (See -a option).
A default collection of data files (i.e., a Solaris ABI database file and
the exceptions file) are located under /opt/onbld/etc/abi provided
with the SUNWonbld package. A workspace may contain a newer version of the
files by specifying the -b option with $SRC/tools/abi/etc as the
ABI_DB_path, or if the -b option is not specified, the $SRC environment
variable needs to be set to access these files.
By default, intf_check will use the database file corresponding to the
machine architecture this tool is run from (i.e., $MACH). However, the
developer may enable auditing against a different platform by specifying
the -A option. (See OPTIONS section for details).
FILES
Solaris ABI database file for SPARC platform.
Solaris ABI database file for i386 platform.
ABI exceptions file.
exceptions contains historical bugs which have been excused by an ARC case number or a bugid. One of the following formats must be used when making additions to this database:
<ARC # or bugid>: <RULE #>: <library>: <symbol>
<ARC # or bugid>: <RULE #>: <library>: <version name>
<ARC # or bugid>: <RULE #>: <library>
The <ARC #> must have the following format:
<ARC name> <4 digit year>/<3 digit case number>
where the ARC name refers to the corresponding ARC from which approval is granted. i.e., PSARC, LSARC, etc.
The <RULE #> corresponds to the RULE which was violated
by this bug. (See OUTPUT MESSAGES to identify the RULE
to specify in this field.)
Also, see OUTPUT MESSAGES to identify the <symbol> and <version name> fields.
For examples of entries, please refer to the exceptions file itself.
EXAMPLES
For library developers, only check for ABI instabilities on a single
shared object:
For gatekeepers or developers who wish to check for ABI instabilities
on the entire ON gate, the -b option should be specified to ensure that
the most relevant ABI database and exceptions files are used for auditing.
In addition, the -o option ensures all omitted libraries are detected:
SEE ALSO
ld (1), ldd (1), elfdump (1), pvs (1), nightly (1), README.spec.
.TZ LLM