/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Routines for manipulating tdesc and tdata structures
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <pthread.h>
#include "ctftools.h"
#include "memory.h"
#include "traverse.h"
/*
* The layout hash is used during the equivalency checking. We have a node in
* the child graph that may be equivalent to a node in the parent graph. To
* find the corresponding node (if any) in the parent, we need a quick way to
* get to all nodes in the parent that look like the node in the child. Since a
* large number of nodes don't have names, we need to incorporate the layout of
* the node into the hash. If we don't, we'll end up with the vast majority of
* nodes in bucket zero, with one or two nodes in each of the remaining buckets.
*
* There are a couple of constraints, both of which concern forward
* declarations. Recall that a forward declaration tdesc is equivalent to a
* tdesc that actually defines the structure or union. As such, we cannot
* incorporate anything into the hash for a named struct or union node that
* couldn't be found by looking at the forward, and vice versa.
*/
int
{
ulong_t h = 0;
else {
case POINTER:
case TYPEDEF:
case VOLATILE:
case CONST:
case RESTRICT:
break;
case FUNCTION:
break;
case ARRAY:
break;
case STRUCT:
case UNION:
/*
* Unnamed structures, which cannot have forward
* declarations pointing to them. We can therefore
* incorporate the name of the first member into
* the hash value, assuming there are any.
*/
break;
case ENUM:
/* Use the first element in the hash value */
break;
default:
/*
* Intrinsics, forwards, and typedefs all have
* names.
*/
warning("Unexpected unnamed %d tdesc (ID %d)\n",
}
}
if (name)
return (h % nbuckets);
}
int
{
return (0);
else
return (-1);
return (1);
else
}
int
{
}
int
{
return (0);
else
}
int
{
ulong_t h, g;
char *c;
return (0);
h = (h << 4) + *c;
if ((g = (h & 0xf0000000)) != 0) {
h ^= (g >> 24);
h ^= g;
}
}
return (h % nbuckets);
}
int
{
}
/*ARGSUSED1*/
int
{
return (1);
}
static void
{
}
static void
{
}
static void
{
while (ml) {
}
}
static void
{
while (el) {
}
}
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
};
/*ARGSUSED1*/
static int
{
return (1);
}
void
{
}
static int
{
}
void
{
}
static int
{
return (1);
}
{
return (top);
}
static int
{
}
int
{
}
(int (*)())tdata_label_find_cb)))
return (-1);
}
static int
{
return (1);
}
return (0);
}
void
{
}
/*ARGSUSED1*/
static void
{
}
void
{
}
tdata_t *
tdata_new(void)
{
/*
* This is also traversed as a list, but amortized O(1)
* lookup massively impacts part of the merge phase, so
* we store the iidescs as a hash.
*/
return (new);
}
void
{
}
/*ARGSUSED1*/
static int
{
return (1);
}
NULL,
build_hashes, /* intrinsic */
build_hashes, /* pointer */
build_hashes, /* array */
build_hashes, /* function */
build_hashes, /* struct */
build_hashes, /* union */
build_hashes, /* enum */
build_hashes, /* forward */
build_hashes, /* typedef */
tdtrav_assert, /* typedef_unres */
build_hashes, /* volatile */
build_hashes, /* const */
build_hashes /* restrict */
};
static void
{
}
void
{
}
/* Merge td2 into td1. td2 is destroyed by the merge */
void
{
/* Add td2's type tree to the hashes */
(int (*)())tdata_label_cmp);
/* free the td2 hashes (data is now part of td1) */
}