util.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"
int Debug;
char *program;
/* Internal functions */
static char * bv_chunktos(ull_t, char *, int);
static rellist_t * find_rel_node(int);
static ull_t stobv_chunk(char *);
/*
* Creates and assigns symbol information to a tree node.
* Insertion of this symbol node to the Sym_List tree will result in either
* updating an existing node or creating a new node on the tree.
*/
int
{
int taller;
return (FAIL);
}
/* Assign tree elements */
/* initialize taller variable */
return (SUCCEED);
}
/*
* Trim off the leading and trailing blanks or tabs for a char string
*/
char *
{
char *end;
char *start;
if (str[0] == '\0')
return (NULL);
*(end --) = '\0';
else
break;
}
return (str);
}
/*
* To convert ascii string to bv_chunk
*/
static ull_t
stobv_chunk(char *str)
{
if (!str)
return ((ull_t)0);
else {
}
}
/*
* Wrapper to convert ascii string to a linked list of bv_chunk (bvlist_t)
*/
{
int num_nodes;
int i;
"%s: atobv: calloc: bv: %s\n",
return (NULL);
}
for (i = 0; i < num_nodes; i ++) {
if (i == num_nodes - 1)
break;
if (tmp_ptr) {
}
"%s: atobv: calloc: bv_ptr: %s\n",
return (NULL);
}
}
/*
* Now, needs to pad the rest of the substr with zeros
* to form substr with a length of RELMAX. In this way,
* the str to bv_chunk translation will be accurate.
*/
substr[i] = '0';
}
substr[i] = '\0';
return (bv);
}
/*
* Convert bv_chunk to character string
*/
static char *
{
int i;
int size;
return (string);
}
/*
* Wrapper to convert a linked list of bv_chunk (bvlist_t) to character string
*/
char *
{
char *string;
char *str;
int num_nodes;
int i;
"%s: bvtos: calloc: %s\n",
return (NULL);
}
for (i = 0; i < num_nodes - 1; i ++) {
}
return (string);
}
/*
* Construct the category bitvectors
* against and the version name associated with the symbol
* from the "pvs -dosl" output, classifies the symbol into
* public, private, unexported and scoped. We consider the
* symbol as private if its version name contains "private"
* string or "sunwabi_", otherwise the symbol is considered
* to be public.
*/
int
{
char *cat_str;
int i;
"%s: build_cat_bits: strdup: cat_str: %s\n",
return (FAIL);
}
for (i = 0; cat_str[i] != '\0'; i ++)
if (!cat->ct_private)
if (!cat->ct_unexported)
if (!cat->ct_evolving)
if (!cat->ct_obsolete)
if (!cat->ct_unclassified)
} else {
}
return (SUCCEED);
}
/*
* Store the symbol name, its type (FUNCTION or OBJECT) and size
* if the symbol is an OBJECT.
* For example; _pagesize (4)
*/
void
{
char *token;
if (!sym->st_sym_name) {
"%s: build_sym_tag: strdup: token: %s\n",
return;
}
} else {
if (!sym->st_sym_name) {
"%s: build_sym_tag: strdup: name: %s\n",
return;
}
}
}
/*
* and also the symbol version name and highest version name for that
* library.
*/
int
{
return (FAIL);
}
/*
* sym_ver and lib_ver start off at the same version. They will
* get reassigned if necessary in assign_versions()
*/
"%s: build_lib_tag: strdup: lib_ver: %s\n",
return (FAIL);
}
if (!lib->lt_lib_name) {
"%s: build_lib_tag: strdup: lib_name: %s\n",
return (FAIL);
}
return (SUCCEED);
}
/*
* It is used when a duplicate symbol name is found while trying to
* add a new node onto the AVL tree. If the linked list for that
* particular tree node is not created, it will first create a new one,
* and then add that new node to the list. If there is an existing
* linked list, it will try to match the new node's attributes.
* If there is a match, the existing linked list node information will
* be updated, otherwise, the new node will be added to the end of the
* linked list.
*/
static liblist_t *
{
if (!p) {
p = node;
} else {
loc = p;
/*
* walk through the linked list of
* that symbol. If the library-symbol
* pair matches, update symbol's info
*/
/* free the memory allocated for node */
break;
} else {
else
break;
}
}
}
}
return (p);
}
/*
* Walk through the linked list, and write out the symbol information
* onto a ABI database file.
*/
static void
{
if (!p)
return;
while (p->st_lib) {
generate_db(p, fp);
}
}
/*
* Destroy a linked list of sequence_t structure
*/
void
{
sequence_t *p;
while (listptr) {
listptr = p;
}
}
/*
* Tree balancing routine for single left rotation.
*/
static tree_t *
rotate_left(tree_t *p)
{
if (!p) {
if (Debug)
"%s: rotate_left: Tree is NULL\n", program);
} else if (!p->tt_right) {
if (Debug)
"%s: rotate_left: Cannot rotate to left...\n",
program);
} else {
}
return (temp);
}
/*
* Tree balancing routine for single right rotation.
*/
static tree_t *
rotate_right(tree_t *p)
{
if (!p) {
if (Debug)
"%s: rotate_right: Tree is NULL\n",
program);
} else if (!p->tt_left) {
if (Debug)
"%s: rotate_right: Cannot rotate to right...\n",
program);
} else {
}
return (temp);
}
/*
* Right balance of AVL tree if right subtree is higher than
* the left subtree.
*/
static tree_t *
{
case RH:
/* single rotation left */
p = rotate_left(p);
break;
case EH:
/* tree is already balanced */
break;
case LH:
/* double rotation left */
case RH:
break;
case EH:
break;
case LH:
}
p = rotate_left(p);
}
return (p);
}
/*
* Left balance of AVL tree if left subtree is higher
* than the right subtree.
*/
static tree_t *
{
case LH:
/* single rotation right */
p = rotate_right(p);
break;
case EH:
/* tree is already balanced */
break;
case RH:
/* double rotation right */
case LH:
break;
case EH:
break;
case RH:
}
p = rotate_right(p);
}
return (p);
}
/*
* Inserts a new tree node into the AVL tree. If a duplicate symbol
* is found, inserts or updates its associated linked list.
*/
static tree_t *
{
if (p == NULL) {
p = new;
} else {
p->tt_sym->st_sym_name) < 0) {
p->tt_left =
if (*taller) /* Left subtree is taller */
switch (p->tt_bf) {
case LH:
/* Node was left high */
p = left_balance(p, taller);
break;
case EH:
/* Node is now left high */
break;
case RH:
/* Node now has balanced height */
break;
}
p->tt_sym->st_sym_name) > 0) {
p->tt_right =
if (*taller) /* Right subtree is taller */
switch (p->tt_bf) {
case LH:
/* Node now has balanced height */
break;
case EH:
/* Node is right high */
break;
case RH:
/* Node is right high */
p = right_balance(p, taller);
break;
}
} else {
/*
* In this case, same symbol exists in
* different libraries
*/
/*
* now, free the memory previously allocated
* in build_sym_tag()
*/
}
}
return (p);
}
/*
* It will do a inorder tree traversal to output the symbol information
*/
void
{
if (rootptr) {
}
}
/*
* Reads in the library information for those need to be checked
* and store them onto the simple linked list.
*/
list_t *
{
if (!p) {
"%s: store_lib_info: calloc: %s\n",
return (NULL);
}
if (!p->lt_name) {
"%s: store_lib_info: strdup: p->lt_name: %s\n",
return (NULL);
}
} else {
loc = p;
} else {
else
break;
}
}
"%s: store_lib_info: calloc: %s\n",
return (NULL);
}
"%s: store_lib_info: strdup: "
"loc->lt_name: %s\n",
return (NULL);
}
}
}
return (p);
}
/*
* Checks if the library name is on the linked list, returns TRUE.
* otherwise, returns FALSE.
*/
int
{
while (loc) {
return (TRUE);
}
return (FALSE);
}
/*
* To find out the number of items on the linked list if there are more than
* 64 releases to keep track.
*/
int
find_num_nodes(int index)
{
else
}
/*
* To perform AND operation on two linked lists of bv_chunk
* (bvlist_t). If the result of AND operation is != 0 return TRUE
* else FALSE.
*/
int
{
while (tmp_bv1) {
return (TRUE);
}
return (FALSE);
}
/*
* To perform OR operation on two linked lists of bv_chunk (bvlist_t).
*/
void
{
while (tmp_bv1) {
}
}
/*
* To perform left SHIFT operation on a linked list of ull_t (bvlist_t)
*/
{
int num_nodes;
int i;
for (i = 0; i < num_nodes; i ++) {
if (bv_ptr->bt_bitvector == 0) {
} else
break;
}
}
return (bv);
}
/*
* To perform right SHIFT operation on a linked list of ull_t (bvlist_t)
*/
{
int num_nodes;
int i;
for (i = 0; i < num_nodes; i ++) {
if (bv_ptr->bt_bitvector == 0) {
} else
break;
}
}
return (bv);
}
/*
* To perform bitvector comparison on two linked list of ull_t (bvlist_t)
* and return TRUE or FALSE appropriately
*/
int
{
while (tmp_bv1) {
return (FALSE);
}
}
return (TRUE);
}
/*
* To check if all the values of a linked list of ull_t (bvlist_t) are
* zero and return TRUE or FALSE appropriately
*/
int
{
while (tmp_bv) {
if (tmp_bv->bt_bitvector != 0)
return (FALSE);
}
return (TRUE);
}
/*
* To check if linked list A of ull_t is greater or equal to linked list B
* of ullt_t.
* i.e., list A >= list B
*/
int
{
int i, num_nodes;
for (i = 0; i < num_nodes; i ++) {
return (TRUE);
if (tmp_bv2->bt_bitvector != 0) {
return (TRUE);
} else {
}
} else {
return (FALSE);
}
}
return (FALSE);
}
/*
* To copy all the values of linked list B to linked list A
* i.e., list A = list B
*/
void
{
while (tmp_bv1) {
}
}
/*
* Given an index, to return an appropriate node referencing the index
*/
static verlist_t *
{
int num_nodes;
int i;
for (i = 0; i < num_nodes; i ++) {
if (tmp_verlist->vlt_next)
else
break;
} else
break;
}
return (tmp_verlist);
}
/*
* Given an index and library name, assign the library name to the appropriate
* position in liblist_t->verlist_t->vlt_rel_ver[position].vt_lib_ver
*/
void
{
if (lib_ver_name) {
"%s: assign_lib_ver: strdup: lib_ver_name: %s\n",
NULL;
}
} else
NULL;
}
/*
* Given an index and symbol name, assign the symbol name to the appropriate
* position in liblist_t->verlist_t->vlt_rel_ver[position].vt_sym_ver
*/
void
{
if (sym_ver_name) {
"%s: assign_sym_ver: strdup: sym_ver_name: %s\n",
NULL;
}
} else
NULL;
}
/*
* Given an index and a liblist_t, return the appropriate library name
* liblist_t->verlist_t->vlt_rel_ver[position].vt_lib_ver
*/
char *
{
}
/*
* Given an index and a liblist_t, return the appropriate symbol name
* liblist_t->verlist_t->vlt_rel_ver[position].vt_sym_ver
*/
char *
{
}
/*
* Create if not exist or add new node onto a linked list of verlist_t.
*/
int
{
int i, j;
int nodes_needed = 0;
int num_nodes = 0;
/* count number of nodes currently present on linked list of versions */
while (end_verlist != NULL) {
num_nodes ++;
else
break;
}
for (i = 0; i < nodes_needed; i ++) {
"%s: add_verlist: calloc: new_verlist: %s\n",
return (FAIL);
}
for (j = 0; j < RELMAX; j ++) {
}
/* add new_verlist to end of verlist */
if (!lib->lt_version) {
} else {
}
}
return (SUCCEED);
}
/*
* Return the appropriate node of Rel (the linked list of rellist_t)
* referencing the index
*/
static rellist_t *
find_rel_node(int index)
{
int num_nodes;
int i;
tmp_rellist = Rel;
for (i = 0; i < num_nodes; i ++) {
if (tmp_rellist->rt_next)
else
break;
} else
break;
}
return (tmp_rellist);
}
/*
* Given an index, to return the appropriate linked list of ull_t (bvlist_t)
* which contains the release information referencing the index.
*/
bvlist_t *
get_rel_bitmask(int index)
{
int i;
int num_nodes;
for (i = 0; i < num_nodes; i ++) {
} else
break;
}
return (node);
}
/*
* Given an index, to return the name of a release
*/
char *
get_rel_name(int index)
{
if (tmp_rellist)
else
return (NULL);
}
/*
* To assign the name of a release associated with a proper index
* to rellist_t->rt_release[proper index].rt_rel_name
*/
void
{
if (rel_name) {
"%s: assign_rel_name: strdup: rt_rel_name: %s\n",
NULL;
}
}
}
/*
* Create if not exist or add new node onto a linked list of rellist_t.
*/
int
add_rellist(int cnt)
{
int i;
int nodes_needed = 0;
int num_nodes = 0;
/* count number of nodes currently present on linked list of versions */
end_rellist = Rel;
while (end_rellist != NULL) {
num_nodes ++;
else
break;
}
for (i = 0; i < nodes_needed; i ++) {
"%s: add_rellist: calloc: new_rellist: %s\n",
return (FAIL);
}
/* add new_rellist to end of Rel */
if (!Rel) {
Rel = new_rellist;
} else {
}
}
return (SUCCEED);
}
/*
* To create a linked list of ull_t (bvlist_t) and initialize each ull_t
* value to zero
*/
bvlist_t *
create_bv_list(int cnt)
{
int num_nodes;
int i;
"%s: create_bv_list: calloc: list: %s\n",
return (NULL);
}
for (i = 0; i < num_nodes; i ++) {
if (i == num_nodes - 1)
break;
"%s: create_bv_list: calloc: tmp: %s\n",
return (NULL);
}
tmp->bt_bitvector = 0;
}
return (list);
}
/*
* To destroy the linked list of ull_t (bvlist_t)
*/
void
{
bvlist_t *p;
while (bv) {
bv = p;
}
}