intf_check.1 revision 7c478bd95313f5f23a4c958a745db2134aa03244
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:

 % intf_check /usr/lib/libfoo.so.1 

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:

 % intf_check -V -o -m  \\\ \&        -b $SRC/tools/abi/etc \\\ \&        -d $SRC/interfaces.out $ROOT \\\ \&        > $SRC/interfaces.out/log  % ls -1R $SRC/interfaces.out Public-32
Public-64
audit/
log
man/

$SRC/interfaces.out/audit:
usr=lib=libadm.so.1
usr=lib=libaio.so.1
usr=lib=libfoo.so.1
\.\.\.\.\.\.\.

% cat log
\.\.\.\.\.\.\.
 ERROR: usr/lib/libfoo.so.1: bar: was public in 5.8, is now unexported
\.\.\.\.\.\.\.

SEE ALSO
ld (1), ldd (1), elfdump (1), pvs (1), nightly (1), README.spec.

.TZ LLM