ctf_types.c revision d11c725a6a076f607c240f98ff03ca3166b581c9
/*
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef VBOX
#pragma ident "%Z%%M% %I% %E% SMI"
#endif
#include <ctf_impl.h>
{
increment = sizeof (ctf_type_t);
} else {
increment = sizeof (ctf_stype_t);
}
if (sizep)
if (incrementp)
*incrementp = increment;
return (size);
}
/*
* Iterate over the members of a STRUCT or UNION. We pass the name, member
* type, and offset of each member to the specified callback function.
*/
int
{
const ctf_type_t *tp;
int rc;
return (CTF_ERR); /* errno is set for us */
return (CTF_ERR); /* errno is set for us */
arg)) != 0)
return (rc);
}
} else {
return (rc);
}
}
return (0);
}
/*
* Iterate over the members of an ENUM. We pass the string name and associated
* integer value of each enum element to the specified callback function.
*/
int
{
const ctf_type_t *tp;
const ctf_enum_t *ep;
uint_t n;
int rc;
return (CTF_ERR); /* errno is set for us */
return (CTF_ERR); /* errno is set for us */
return (rc);
}
return (0);
}
/*
* Iterate over every root (user-visible) type in the given CTF container.
* We pass the type ID of each type to the specified callback function.
*/
int
{
return (rc);
}
return (0);
}
/*
* Follow a given type through the graph for TYPEDEF, VOLATILE, CONST, and
* RESTRICT nodes until we reach a "base" type node. This is useful when
* we want to follow a type ID to a node that has members or a size. To guard
* against infinite loops, we implement simplified cycle detection and check
* each link against itself, the previous node, and the topmost node.
*/
{
const ctf_type_t *tp;
case CTF_K_TYPEDEF:
case CTF_K_VOLATILE:
case CTF_K_CONST:
case CTF_K_RESTRICT:
}
break;
default:
return (type);
}
}
return (CTF_ERR); /* errno is set for us */
}
/*
* Lookup the given type ID and print a string name for it into buf. Return
* the actual number of bytes (not including \0) needed to format the name.
*/
{
uint_t k;
return (-1); /* simplify caller code by permitting CTF_ERR */
ctf_decl_fini(&cd);
}
/*
* If the type graph's order conflicts with lexical precedence order
* for pointers or arrays, then we need to surround the declarations at
* the corresponding lexical precedence with parentheses. This can
* result in either a parenthesized pointer (*) as in int (*)() or
* int (*)[], or in a parenthesized pointer and array as in int (*[])().
*/
k = CTF_K_POINTER; /* avoid leading whitespace (see below) */
const ctf_type_t *tp =
if (k != CTF_K_POINTER && k != CTF_K_ARRAY)
lp = -1;
}
case CTF_K_INTEGER:
case CTF_K_FLOAT:
case CTF_K_TYPEDEF:
break;
case CTF_K_POINTER:
break;
case CTF_K_ARRAY:
break;
case CTF_K_FUNCTION:
break;
case CTF_K_STRUCT:
case CTF_K_FORWARD:
break;
case CTF_K_UNION:
break;
case CTF_K_ENUM:
break;
case CTF_K_VOLATILE:
break;
case CTF_K_CONST:
break;
case CTF_K_RESTRICT:
break;
}
}
}
ctf_decl_fini(&cd);
}
/*
* Lookup the given type ID and print a string name for it into buf. If buf
* is too small, return NULL: the ECTF_NAMELEN error is set on 'fp' for us.
*/
char *
{
}
/*
* Resolve the type down to a base type node, and then return the size
* of the type storage in bytes.
*/
{
const ctf_type_t *tp;
return (-1); /* errno is set for us */
return (-1); /* errno is set for us */
case CTF_K_POINTER:
case CTF_K_FUNCTION:
return (0); /* function size is only known by symtab */
case CTF_K_ENUM:
case CTF_K_ARRAY:
/*
* Array size is not directly returned by stabs data. Instead,
* it defines the element type and requires the user to perform
* the multiplication. If ctf_get_ctt_size() returns zero, the
* current version of ctfconvert does not compute member sizes
* and we compute the size here on its behalf.
*/
return (size);
return (-1); /* errno is set for us */
default:
}
}
/*
* Resolve the type down to a base type node, and then return the alignment
* needed for the type storage in bytes.
*/
{
const ctf_type_t *tp;
ctf_arinfo_t r;
return (-1); /* errno is set for us */
return (-1); /* errno is set for us */
case CTF_K_POINTER:
case CTF_K_FUNCTION:
case CTF_K_ARRAY:
return (-1); /* errno is set for us */
case CTF_K_STRUCT:
case CTF_K_UNION: {
const void *vmp;
size < CTF_LSTRUCT_THRESH) {
for (; n != 0; n--, mp++) {
}
} else {
for (; n != 0; n--, lmp++) {
}
}
return (align);
}
case CTF_K_ENUM:
default:
}
}
/*
* Return the kind (CTF_K_* constant) for the specified type ID.
*/
int
{
const ctf_type_t *tp;
return (CTF_ERR); /* errno is set for us */
}
/*
* If the type is one that directly references another type (such as POINTER),
* then return the ID of the type to which it refers.
*/
{
const ctf_type_t *tp;
return (CTF_ERR); /* errno is set for us */
case CTF_K_POINTER:
case CTF_K_TYPEDEF:
case CTF_K_VOLATILE:
case CTF_K_CONST:
case CTF_K_RESTRICT:
default:
}
}
/*
* Find a pointer to type by looking in fp->ctf_ptrtab. If we can't find a
* pointer to the given type, see if we can compute a pointer to the type
* resulting from resolving the type down to its base type and use that
* instead. This helps with cases where the CTF data includes "struct foo *"
* but not "foo_t *" and the user accesses "foo_t *" in the debugger.
*/
{
return (CTF_ERR); /* errno is set for us */
}
/*
* Return the encoding for the specified INTEGER or FLOAT.
*/
int
{
const ctf_type_t *tp;
return (CTF_ERR); /* errno is set for us */
case CTF_K_INTEGER:
break;
case CTF_K_FLOAT:
break;
default:
}
return (0);
}
int
{
int rval;
rval = -1;
rval = 1;
else
rval = 0;
return (rval);
return (-1);
return (1);
return (rval);
}
/*
* Return a boolean value indicating if two types are compatible integers or
* floating-pointer values. This function returns true if the two types are
* the same, or if they have the same ASCII name and encoding properties.
* This function could be extended to test for compatibility for other kinds.
*/
int
{
return (1);
return (0);
switch (lkind) {
case CTF_K_INTEGER:
case CTF_K_FLOAT:
case CTF_K_POINTER:
case CTF_K_ARRAY:
case CTF_K_STRUCT:
case CTF_K_UNION:
case CTF_K_ENUM:
case CTF_K_FORWARD:
return (1); /* no other checks required for these type kinds */
default:
return (0); /* should not get here since we did a resolve */
}
}
/*
* Return the type and offset for a given member of a STRUCT or UNION.
*/
int
{
const ctf_type_t *tp;
return (CTF_ERR); /* errno is set for us */
return (CTF_ERR); /* errno is set for us */
return (0);
}
}
} else {
return (0);
}
}
}
}
/*
* Return the array type, index, and size information for the specified ARRAY.
*/
int
{
const ctf_type_t *tp;
const ctf_array_t *ap;
return (CTF_ERR); /* errno is set for us */
return (0);
}
/*
* Convert the specified value to the corresponding enum member name, if a
* matching name can be found. Otherwise NULL is returned.
*/
const char *
{
const ctf_type_t *tp;
const ctf_enum_t *ep;
uint_t n;
return (NULL); /* errno is set for us */
return (NULL); /* errno is set for us */
return (NULL);
}
}
return (NULL);
}
/*
* Convert the specified enum tag name to the corresponding value, if a
* matching name can be found. Otherwise CTF_ERR is returned.
*/
int
{
const ctf_type_t *tp;
const ctf_enum_t *ep;
uint_t n;
return (CTF_ERR); /* errno is set for us */
return (CTF_ERR); /* errno is set for us */
return (CTF_ERR);
}
return (0);
}
}
return (CTF_ERR);
}
/*
* Recursively visit the members of any type. This function is used as the
* engine for ctf_type_visit, below. We resolve the input type, recursively
* invoke ourself for each type member if the type is a struct or union, and
* then invoke the callback function on the current type. If any callback
* returns non-zero, we abort and percolate the error code back up to the top.
*/
static int
{
const ctf_type_t *tp;
int rc;
return (CTF_ERR); /* errno is set for us */
return (CTF_ERR); /* errno is set for us */
return (rc);
return (0);
return (rc);
}
} else {
depth + 1)) != 0)
return (rc);
}
}
return (0);
}
/*
* Recursively visit the members of any type. We pass the name, member
* type, and offset of each member to the specified callback function.
*/
int
{
}