verschk.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* 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
* 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
*/
/*
* Copyright 2002-2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "abi_audit.h"
/* Variables */
int Debug;
static const char *Numstr = "01234567689.";
/* Internal functions */
static int compare_ver_inc(char *, char *);
static void check_ver_inc(liblist_t *);
static void check_lib_ver(liblist_t *, char *);
static void check_sym_ver(symbol_t *);
/*
* assign_versions() will assign vt_lib_ver and vt_sym_ver for a given release.
* lib_ver should be the highest version of the library and sym_ver should be
* the lowest version this symbol was exported.
* The intf_check output will be read in with the highest version of the
* library first. So, for a new release, the lib_ver will need to be set,
* whereas, on subsequent calls to this function, only the sym_ver needs to be
* reset.
*/
void
{
char *oldlibver;
char *newlibver;
char *newsymver;
/* Start of a new release */
}
}
/*
* Returns the first release which is exported. Returns FAIL if the symbol was
* never exported
*/
int
{
int release = 0;
int count = 0;
bitmask = get_rel_bitmask(0);
while (count < Total_relcnt) {
if (first_exported)
return (count);
}
count ++;
}
/*
* symbol was never exported or it was scoped local during its lifetime.
*/
return (FAIL);
}
return (release);
}
/*
* Version Checker recursively checks for versioning errors in each node of
* the tree.
*/
void
{
if (rootptr) {
}
}
/*
* check_sym_ver() will traverse through the liblist_t and ensure
* versioning policies are maintained in each library of a given symbol.
*/
static void
{
}
}
/*
* check_lib_ver() prints error if:
* - base version is not maintained
* - base_vers is not < lib_vers
* - version incrementing between new releases of a lib does not
* follow library versioning policies of incrementing by only ".1"
*/
static void
{
int i = 0;
char *libver;
char *next_libver;
char *prev_sym_ver, *curr_sym_ver;
if (!lib->lt_check_me) {
return;
}
if (Debug)
"%s: check_lib_ver: %s was never exported",
}
if (!iflag) {
/* symbol existed in last Solaris Release */
} else {
/* symbol is unexported in last Solaris Release */
}
}
for (i = first_vers; i < Total_relcnt; i ++) {
/*
* flag WARNING if SUNWobsolete->SUNWprivate_m.o
* flag ERROR if SUNWobsolete->SUNW_m.n.o or any new version
* ASSERTION check to make sure it does not happen
*/
(i < Total_relcnt - 1)) {
if (next_libver) {
else
"new interface introduced to the "
"obsolete library\n");
}
}
/*
* only do base and new version checking for public symbols.
* current_sym_ver can be NULL for releases in which the
* symbol is unexported.
*/
if (!get_sym_ver(lib, i)) {
continue;
}
if (!curr_sym_ver) {
continue;
}
continue;
}
/*
* ensure the base version is maintained through all
* releases of a library
*/
"ERROR: %s: %s: "
"base version not maintained, was %s in %s, "
"becomes %s in ",
if (i != (Total_relcnt - 1)) {
get_rel_name(i));
} else {
}
}
/*
* ensure new symbols are versioned with the
* highest lib_version. Sym's base version must equal
* it's highest lib_version.
*/
if (libver &&
/*
* new symbols could have been introduced in update
* releases and they have to be versioned in micro
* number if only a subset of the new symbols are
* backported from the market release to a update
* or patch release. The new version name needs
* to be validated.
*/
if (!iflag &&
continue;
}
if ((var =
((var == 2) &&
== FAIL))) {
"ERROR: %s: %s:"
" invalid new version, %s "
"should be %s in ",
if (i != (Total_relcnt - 1)) {
get_rel_name(i));
} else {
"current release\n");
}
}
break;
}
}
prev_ver_num = i;
}
/*
* ensure that the version is incremented by at most ".1"
* between previous and new releases of a library
*/
}
/*
* It ensures the integrity of version incrementing is maintained between
* multiple releases of a library. If not, an error message is printed
*/
static void
{
char *prev_ver;
int prev_ver_num;
char *current_ver;
int i;
int first_rel;
if (Debug)
"%s: check_ver_inc: never exported", program);
}
/* current_ver can only be NULL when a symbol is always scoped_local */
return;
/*
* Only check versioning for public symbols, but skip checking of
* SYSVABI and SISCD standards versions
*/
return;
/* prev_ver refers to first release this symbol was exported */
/*
* compare prev_ver to current_ver by always comparing the versions
* pairwise. Reset prev_ver to the last version exported.
*/
/*
* check to make sure that increments between releases
* of a lib are no greater than .1
*/
continue;
}
"ERROR: %s: was %s in %s, becomes %s in ",
if (i != (Total_relcnt - 1)) {
get_rel_name(i));
} else {
"current release:");
}
" inconsistent increment of version\n");
}
prev_ver_num = i;
}
}
}
/*
* compare_ver_inc() checks the major, minor and micro numbers
* of two public version strings to ensure that the new version hasn't been
* incremented by more than ".1" per release. Versioning prior to SUNW_1.1
* is ignored. Strings matching "SUNW_m.n.o" where "o" is optional, will
* be checked for this version incrementing scheme.
*/
static int
{
char *oversion;
char *nversion;
int omicro = 0;
int nmicro = 0;
/* scoped local symbols contain no version numbering */
return (SUCCEED);
}
return (FAIL);
}
/* extracting major, minor and micro number from old version */
return (FAIL);
}
oversion ++;
oversion ++;
}
/* extracting major, minor and micro number from new version */
return (FAIL);
}
nversion ++;
nversion ++;
}
/* new symbol should be versioned with major >= 1 & minor >= 1 */
return (FAIL);
/* ignore all versioning prior to 1.1 */
return (SUCCEED);
/*
* omajor < nmajor; incompatible changes within a library
* i.e., SUNW_1.n.o vs. SUNW_2.n.o
* omajor > nmajor; impossible to have within a library
* i.e., SUNW_2.n.o vs. SUNW_1.n.o
*/
return (FAIL);
/* omajor == nmajor */
/*
* m stays, n is incremented with optional o
*/
/* i.e., SUNW_1.2 vs. SUNW_1.4 */
return (FAIL);
/* i.e., SUNW_1.2 vs. SUNW_1.3.1 */
/* i.e., SUNW_1.2.1 vs. SUNW_1.3.1 */
else if (nmicro != 0)
return (FAIL);
else
return (SUCCEED);
/*
* m & n stay the same but o is incremented
*/
/* old m.n.o equals to new m.n.o */
/* i.e., SUNW_1.20.3 vs. SUNW_1.20.3 */
return (SUCCEED);
/* i.e., SUNW_1.20 vs. SUNW_1.20.2 */
/* i.e., SUNW_1.20.1 vs. SUNW_1.20.3 */
return (FAIL);
else
/* i.e., SUNW_1.20 vs. SUNW_1.20.1 */
/* i.e., SUNW_1.8.2 vs. SUNW_1.8.3 */
return (SUCCEED);
/*
* m stays & old minor > new minor version
* i.e., SUNW_1.21 vs. SUNW_1.20
*/
return (FAIL);
else
return (SUCCEED);
} else {
/* It's impossible to reach here but just in case */
}
return (FAIL);
}