fth_struct.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 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Used to dump structures and unions in forth mode.
*
* structures and unions are a bit more complicated than enums. To make things
* just that much more interesting, we have to dump the members in reverse
* order, which is nice. But wait! It gets better! For compatibility reasons,
* we need to dump the members in reverse-offset order, even if member-specific
* mode was used to request the members in something other than that order.
*
* The header op prints the macro header and saves the type being printed.
*
* In member-specific mode, the member op will be invoked for each structure
* or union member. The member op adds the member name, format, type ID,
* and offset to a list, sorted in reverse order by offset.
*
* The trailer op is called when the structure or enum is complete. If no
* members were specifically requested, then the trailer iterates through all
* of the members of the structure, pretending they were. Each member is thus
* added, in reverse-offset order, to the list used in specific-member mode.
* Either way, we then proceed through the list, dumping each member out with
* fth_print_member. Structure and union members are printed out differently,
* depending on member type, as follows:
*
* Integer:
* Normal integers: ' <format> <offset> <type>-field <name>
* <format> defaults to ".d" for enums, ".x" for others
* <offset> is the member offset, in bytes.
* <type> is "byte", "short", "long", or "ext" for 8-, 16-, 32-, and
* 64-bit integers, respectively.
* <name> is the name of the member being printed
*
* Bitfields: ' <format> <shift> <mask> <offset> bits-field <name>
* <format> defaults to ".x"
* <shift> is the number of times to right-shift the masked value
* <mask> use to extract the bit-field value from the read value
* <offset> is the member offset, in bytes
* <name> is the name of the member being printed
*
* Float: Ignored
*
* Pointer: ' <format> <offset> ptr-field <name>
* <format> defaults to .x
* <offset> is in bytes
* <name> is the name of the member being printed
*
* Array:
* Arrays have a content-type-specific prefix, followed by an array
* suffix. The resulting line looks like this if the array contents
* type is an integer, a pointer, or an enum:
*
* ' <fldc> ' <fmt> <sz> <elsz> <off> array-field <name>
*
* The following is printed for array contents that are arrays:
*
* ' noop ' .x <sz> <elsz> <off> array-field <name>
*
* The following is printed for array contents that are structs:
*
* ' noop ' <fmt> <sz> <elsz> <off> array-field <name>
*
* <fldc> is "c@", "w@", "l@", or "x@", depending on whether array
* elements are 8, 16, 32 or 64 bits wide.
* <fmt> defaults to ".x"
* <sz> is the size of the array, in bytes
* <elsz> is the size of the array elements
* <off> is the member offset, in bytes
* <name> is the nam eof the member being printed
*
* <format> defaults to ".x"
* <offset> is the member offset, in bytes
* <name> is the name of the member being printed
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ctf_headers.h"
#include "forth.h"
#include "list.h"
#include "memory.h"
static ctf_id_t fth_str_curtid;
static list_t *fth_str_curmems;
/*
* Node type for the member-storage list (fth_str_curmems) built by
* fth_struct_members()
*/
typedef struct fth_str_mem {
char *fsm_memname;
char *fsm_format;
typedef struct fth_struct_members_data {
char *fsmd_strname;
char *fsmd_memfilter;
char *fsmd_format;
int fsmd_matched;
static int fth_print_member(fth_str_mem_t *, int);
/* Comparison routined used to insert members into the fth_str_curmems list */
static int
{
return (1);
return (-1);
else
return (0);
}
static void
{
if (mem->fsm_format)
}
static int
{
return (0);
}
/* Print the array prefix for integer and pointer members */
static int
{
return (parse_warn("Unexpected bit size %d in %s",
bits, fth_curtype));
}
return (0);
}
/*
* Return the format to be used to print the member. If one of the builtin
* formats "d" or "x" were specified, return ".d" or ".x", respectively.
* Otherwise, use the user-provided format as is, or use the default if none
* was provided.
*/
static char *
{
return (def);
return (dot);
} else
return (format);
}
static int
int level)
{
if (bits > 64) {
return (parse_warn("%s.%s is too large (>8 bytes)",
fth_curtype, memname));
}
if (level != 0)
/* bit field */
} else {
char *type[] = {
};
}
return (0);
}
static int
int level)
{
if (level != 0)
memname);
return (0);
}
static int
int level)
{
if (level != 0)
else {
}
return (0);
}
static int
int level)
{
if (level != 0)
else {
memname);
}
return (0);
}
static int
{
if (level != 0)
else {
/*
* print the prefix for the array contents type, then print
* the array macro
*/
return (parse_warn("Can't read array in %s.%s",
fth_curtype, memname));
}
return (-1);
}
return (0);
}
/* dump a structure or union member */
static int
{
int kind;
mem->fsm_memname));
}
return (parse_warn("Can't get kind for %s.%s",
}
return (parse_warn("Can't get size for %s.%s",
}
switch (kind) {
case CTF_K_INTEGER:
case CTF_K_FLOAT:
(void) parse_warn("Ignoring floating point member %s.%s",
return (0);
case CTF_K_POINTER:
case CTF_K_ARRAY:
case CTF_K_STRUCT:
case CTF_K_UNION:
case CTF_K_ENUM:
case CTF_K_FORWARD:
default:
}
}
/*
* Add a member to list of members to be printed (fth_str_curmems). If
* fsmd_memfilter is non-null, only add this member if its name matches that
* in the filter.
*/
static int
{
memname) != 0)
return (0);
if (fsmd->fsmd_format)
return (0);
}
/*
* If memfilter is non-null, iterate through the members of this type, causing
* every member to be added to the list. Otherwise, use the iterator and
* the callback to add only the specified member.
*/
static int
{
fsmd.fsmd_matched = 0;
&fsmd) != 0)
return (-1);
memfilter));
}
return (0);
}
static int
fth_struct_trailer(void)
{
if (list_count(fth_str_curmems) == 0) {
return (-1);
}
while (!list_empty(fth_str_curmems)) {
if (fth_print_member(mem, 0) < 0)
return (-1);
}
return (0);
}
};