1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate #include <stdio.h> 30*7c478bd9Sstevel@tonic-gate #include <string.h> 31*7c478bd9Sstevel@tonic-gate #include <floatingpoint.h> 32*7c478bd9Sstevel@tonic-gate #include <libctf.h> 33*7c478bd9Sstevel@tonic-gate #include <apptrace.h> 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate typedef struct printarg { 36*7c478bd9Sstevel@tonic-gate ulong_t pa_addr; 37*7c478bd9Sstevel@tonic-gate ctf_file_t *pa_ctfp; 38*7c478bd9Sstevel@tonic-gate int pa_depth; 39*7c478bd9Sstevel@tonic-gate int pa_nest; 40*7c478bd9Sstevel@tonic-gate } printarg_t; 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate typedef void printarg_f(ctf_id_t, ulong_t, printarg_t *); 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate static int elt_print(const char *, ctf_id_t, ulong_t, int, void *); 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate const char * 47*7c478bd9Sstevel@tonic-gate type_name(ctf_file_t *ctfp, ctf_id_t type, char *buf, size_t len) 48*7c478bd9Sstevel@tonic-gate { 49*7c478bd9Sstevel@tonic-gate if (ctf_type_name(ctfp, type, buf, len) == NULL) 50*7c478bd9Sstevel@tonic-gate (void) snprintf(buf, len, "<%ld>", type); 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate return (buf); 53*7c478bd9Sstevel@tonic-gate } 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate void 56*7c478bd9Sstevel@tonic-gate print_value(ctf_file_t *ctfp, ctf_id_t type, ulong_t value) 57*7c478bd9Sstevel@tonic-gate { 58*7c478bd9Sstevel@tonic-gate ctf_id_t rtype = ctf_type_resolve(ctfp, type); 59*7c478bd9Sstevel@tonic-gate ctf_encoding_t e; 60*7c478bd9Sstevel@tonic-gate 61*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "0x%p", (void *)value); 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate if (ctf_type_kind(ctfp, rtype) == CTF_K_POINTER) { 64*7c478bd9Sstevel@tonic-gate type = ctf_type_reference(ctfp, rtype); 65*7c478bd9Sstevel@tonic-gate rtype = ctf_type_resolve(ctfp, type); 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate if (ctf_type_encoding(ctfp, rtype, &e) == 0 && 68*7c478bd9Sstevel@tonic-gate (e.cte_format & (CTF_INT_CHAR | CTF_INT_SIGNED)) == 69*7c478bd9Sstevel@tonic-gate (CTF_INT_CHAR | CTF_INT_SIGNED) && e.cte_bits == NBBY) { 70*7c478bd9Sstevel@tonic-gate if ((char *)value != NULL) 71*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, 72*7c478bd9Sstevel@tonic-gate " \"%s\"", (char *)value); 73*7c478bd9Sstevel@tonic-gate else 74*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, " <NULL>"); 75*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 76*7c478bd9Sstevel@tonic-gate return; 77*7c478bd9Sstevel@tonic-gate } 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate if (ctf_type_kind(ctfp, rtype) == CTF_K_STRUCT) { 80*7c478bd9Sstevel@tonic-gate printarg_t pa; 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, " "); 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate pa.pa_addr = value; 85*7c478bd9Sstevel@tonic-gate pa.pa_ctfp = ctfp; 86*7c478bd9Sstevel@tonic-gate pa.pa_nest = 0; 87*7c478bd9Sstevel@tonic-gate pa.pa_depth = 0; 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate (void) ctf_type_visit(ctfp, rtype, elt_print, &pa); 90*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "\t}"); 91*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 92*7c478bd9Sstevel@tonic-gate return; 93*7c478bd9Sstevel@tonic-gate } 94*7c478bd9Sstevel@tonic-gate } 95*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 96*7c478bd9Sstevel@tonic-gate } 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate static void 99*7c478bd9Sstevel@tonic-gate print_bitfield(ulong_t off, ctf_encoding_t *ep) 100*7c478bd9Sstevel@tonic-gate { 101*7c478bd9Sstevel@tonic-gate uint64_t mask = (1ULL << ep->cte_bits) - 1; 102*7c478bd9Sstevel@tonic-gate uint64_t value = 0; 103*7c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN 104*7c478bd9Sstevel@tonic-gate size_t size = (ep->cte_bits + (NBBY - 1)) / NBBY; 105*7c478bd9Sstevel@tonic-gate uint8_t *buf = (uint8_t *)&value; 106*7c478bd9Sstevel@tonic-gate #endif 107*7c478bd9Sstevel@tonic-gate uint8_t shift; 108*7c478bd9Sstevel@tonic-gate 109*7c478bd9Sstevel@tonic-gate /* 110*7c478bd9Sstevel@tonic-gate * On big-endian machines, we need to adjust the buf pointer to refer 111*7c478bd9Sstevel@tonic-gate * to the lowest 'size' bytes in 'value', and we need shift based on 112*7c478bd9Sstevel@tonic-gate * the offset from the end of the data, not the offset of the start. 113*7c478bd9Sstevel@tonic-gate */ 114*7c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN 115*7c478bd9Sstevel@tonic-gate buf += sizeof (value) - size; 116*7c478bd9Sstevel@tonic-gate off += ep->cte_bits; 117*7c478bd9Sstevel@tonic-gate #endif 118*7c478bd9Sstevel@tonic-gate shift = off % NBBY; 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate /* 121*7c478bd9Sstevel@tonic-gate * Offsets are counted from opposite ends on little- and 122*7c478bd9Sstevel@tonic-gate * big-endian machines. 123*7c478bd9Sstevel@tonic-gate */ 124*7c478bd9Sstevel@tonic-gate #ifdef _BIG_ENDIAN 125*7c478bd9Sstevel@tonic-gate shift = NBBY - shift; 126*7c478bd9Sstevel@tonic-gate #endif 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate /* 129*7c478bd9Sstevel@tonic-gate * If the bits we want do not begin on a byte boundary, shift the data 130*7c478bd9Sstevel@tonic-gate * right so that the value is in the lowest 'cte_bits' of 'value'. 131*7c478bd9Sstevel@tonic-gate */ 132*7c478bd9Sstevel@tonic-gate if (off % NBBY != 0) 133*7c478bd9Sstevel@tonic-gate value >>= shift; 134*7c478bd9Sstevel@tonic-gate 135*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%llu", (unsigned long long)(value & mask)); 136*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 137*7c478bd9Sstevel@tonic-gate } 138*7c478bd9Sstevel@tonic-gate 139*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 140*7c478bd9Sstevel@tonic-gate static void 141*7c478bd9Sstevel@tonic-gate print_int(ctf_id_t base, ulong_t off, printarg_t *pap) 142*7c478bd9Sstevel@tonic-gate { 143*7c478bd9Sstevel@tonic-gate ctf_file_t *ctfp = pap->pa_ctfp; 144*7c478bd9Sstevel@tonic-gate ctf_encoding_t e; 145*7c478bd9Sstevel@tonic-gate size_t size; 146*7c478bd9Sstevel@tonic-gate ulong_t addr = pap->pa_addr + off / NBBY; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate if (ctf_type_encoding(ctfp, base, &e) == CTF_ERR) { 149*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "???"); 150*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 151*7c478bd9Sstevel@tonic-gate return; 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate if (e.cte_format & CTF_INT_VARARGS) { 155*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "...\n"); 156*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 157*7c478bd9Sstevel@tonic-gate return; 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate size = e.cte_bits / NBBY; 161*7c478bd9Sstevel@tonic-gate if (size > 8 || (e.cte_bits % NBBY) != 0 || (size & (size - 1)) != 0) { 162*7c478bd9Sstevel@tonic-gate print_bitfield(off, &e); 163*7c478bd9Sstevel@tonic-gate return; 164*7c478bd9Sstevel@tonic-gate } 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate if (((e).cte_format & (CTF_INT_CHAR | CTF_INT_SIGNED)) == 167*7c478bd9Sstevel@tonic-gate (CTF_INT_CHAR | CTF_INT_SIGNED) && (e).cte_bits == NBBY) { 168*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "'%c'", *(char *)addr); 169*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 170*7c478bd9Sstevel@tonic-gate return; 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate switch (size) { 174*7c478bd9Sstevel@tonic-gate case sizeof (uint8_t): 175*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%#x", *(uint8_t *)addr); 176*7c478bd9Sstevel@tonic-gate break; 177*7c478bd9Sstevel@tonic-gate case sizeof (uint16_t): 178*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%#x", *(uint16_t *)addr); 179*7c478bd9Sstevel@tonic-gate break; 180*7c478bd9Sstevel@tonic-gate case sizeof (uint32_t): 181*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%#x", *(uint32_t *)addr); 182*7c478bd9Sstevel@tonic-gate break; 183*7c478bd9Sstevel@tonic-gate case sizeof (uint64_t): 184*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%#llx", 185*7c478bd9Sstevel@tonic-gate (unsigned long long)*(uint64_t *)addr); 186*7c478bd9Sstevel@tonic-gate break; 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 192*7c478bd9Sstevel@tonic-gate static void 193*7c478bd9Sstevel@tonic-gate print_float(ctf_id_t base, ulong_t off, printarg_t *pap) 194*7c478bd9Sstevel@tonic-gate { 195*7c478bd9Sstevel@tonic-gate ctf_file_t *ctfp = pap->pa_ctfp; 196*7c478bd9Sstevel@tonic-gate ctf_encoding_t e; 197*7c478bd9Sstevel@tonic-gate 198*7c478bd9Sstevel@tonic-gate union { 199*7c478bd9Sstevel@tonic-gate float f; 200*7c478bd9Sstevel@tonic-gate double d; 201*7c478bd9Sstevel@tonic-gate long double ld; 202*7c478bd9Sstevel@tonic-gate } u; 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate u.f = 0; 205*7c478bd9Sstevel@tonic-gate if (ctf_type_encoding(ctfp, base, &e) == 0) { 206*7c478bd9Sstevel@tonic-gate if (e.cte_format == CTF_FP_SINGLE && 207*7c478bd9Sstevel@tonic-gate e.cte_bits == sizeof (float) * NBBY) { 208*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%+.7e", u.f); 209*7c478bd9Sstevel@tonic-gate } else if (e.cte_format == CTF_FP_DOUBLE && 210*7c478bd9Sstevel@tonic-gate e.cte_bits == sizeof (double) * NBBY) { 211*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%+.7e", u.d); 212*7c478bd9Sstevel@tonic-gate } else if (e.cte_format == CTF_FP_LDOUBLE && 213*7c478bd9Sstevel@tonic-gate e.cte_bits == sizeof (long double) * NBBY) { 214*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, 215*7c478bd9Sstevel@tonic-gate "%+.16LE", u.ld); 216*7c478bd9Sstevel@tonic-gate } 217*7c478bd9Sstevel@tonic-gate } 218*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 222*7c478bd9Sstevel@tonic-gate static void 223*7c478bd9Sstevel@tonic-gate print_ptr(ctf_id_t base, ulong_t off, printarg_t *pap) 224*7c478bd9Sstevel@tonic-gate { 225*7c478bd9Sstevel@tonic-gate ctf_file_t *ctfp = pap->pa_ctfp; 226*7c478bd9Sstevel@tonic-gate ulong_t addr = pap->pa_addr + off / NBBY; 227*7c478bd9Sstevel@tonic-gate ctf_encoding_t e; 228*7c478bd9Sstevel@tonic-gate 229*7c478bd9Sstevel@tonic-gate if (ctf_type_kind(ctfp, base) != CTF_K_POINTER) 230*7c478bd9Sstevel@tonic-gate return; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if ((base = ctf_type_reference(ctfp, base)) == CTF_ERR) 233*7c478bd9Sstevel@tonic-gate return; 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate if ((base = ctf_type_resolve(ctfp, base)) == CTF_ERR) 236*7c478bd9Sstevel@tonic-gate return; 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate if (ctf_type_encoding(ctfp, base, &e) != 0) 239*7c478bd9Sstevel@tonic-gate return; 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate if (((e).cte_format & (CTF_INT_CHAR | CTF_INT_SIGNED)) == 242*7c478bd9Sstevel@tonic-gate (CTF_INT_CHAR | CTF_INT_SIGNED) && (e).cte_bits == NBBY) 243*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "'%c'", *(char *)addr); 244*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 248*7c478bd9Sstevel@tonic-gate static void 249*7c478bd9Sstevel@tonic-gate print_array(ctf_id_t base, ulong_t off, printarg_t *pap) 250*7c478bd9Sstevel@tonic-gate { 251*7c478bd9Sstevel@tonic-gate ulong_t addr = pap->pa_addr + off / NBBY; 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "0x%p", (void *)addr); 254*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate 257*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 258*7c478bd9Sstevel@tonic-gate static void 259*7c478bd9Sstevel@tonic-gate print_sou(ctf_id_t base, ulong_t off, printarg_t *pap) 260*7c478bd9Sstevel@tonic-gate { 261*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "{"); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 265*7c478bd9Sstevel@tonic-gate static void 266*7c478bd9Sstevel@tonic-gate print_enum(ctf_id_t base, ulong_t off, printarg_t *pap) 267*7c478bd9Sstevel@tonic-gate { 268*7c478bd9Sstevel@tonic-gate ctf_file_t *ctfp = pap->pa_ctfp; 269*7c478bd9Sstevel@tonic-gate const char *ename; 270*7c478bd9Sstevel@tonic-gate int value = 0; 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate if ((ename = ctf_enum_name(ctfp, base, value)) != NULL) 273*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%s", ename); 274*7c478bd9Sstevel@tonic-gate else 275*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%d", value); 276*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 277*7c478bd9Sstevel@tonic-gate } 278*7c478bd9Sstevel@tonic-gate 279*7c478bd9Sstevel@tonic-gate /* ARGSUSED */ 280*7c478bd9Sstevel@tonic-gate static void 281*7c478bd9Sstevel@tonic-gate print_tag(ctf_id_t base, ulong_t off, printarg_t *pap) 282*7c478bd9Sstevel@tonic-gate { 283*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "; "); 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate static printarg_f *const printfuncs[] = { 287*7c478bd9Sstevel@tonic-gate print_int, /* CTF_K_INTEGER */ 288*7c478bd9Sstevel@tonic-gate print_float, /* CTF_K_FLOAT */ 289*7c478bd9Sstevel@tonic-gate print_ptr, /* CTF_K_POINTER */ 290*7c478bd9Sstevel@tonic-gate print_array, /* CTF_K_ARRAY */ 291*7c478bd9Sstevel@tonic-gate print_ptr, /* CTF_K_FUNCTION */ 292*7c478bd9Sstevel@tonic-gate print_sou, /* CTF_K_STRUCT */ 293*7c478bd9Sstevel@tonic-gate print_sou, /* CTF_K_UNION */ 294*7c478bd9Sstevel@tonic-gate print_enum, /* CTF_K_ENUM */ 295*7c478bd9Sstevel@tonic-gate print_tag /* CTF_K_FORWARD */ 296*7c478bd9Sstevel@tonic-gate }; 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate static int 299*7c478bd9Sstevel@tonic-gate elt_print(const char *name, ctf_id_t id, ulong_t off, int depth, void *data) 300*7c478bd9Sstevel@tonic-gate { 301*7c478bd9Sstevel@tonic-gate char type[256]; 302*7c478bd9Sstevel@tonic-gate int kind, d; 303*7c478bd9Sstevel@tonic-gate ctf_id_t base; 304*7c478bd9Sstevel@tonic-gate printarg_t *pap = data; 305*7c478bd9Sstevel@tonic-gate ctf_file_t *ctfp = pap->pa_ctfp; 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate for (d = pap->pa_depth - 1; d >= depth; d--) { 308*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%*s}\n", 309*7c478bd9Sstevel@tonic-gate (depth + pap->pa_nest) * 4, ""); 310*7c478bd9Sstevel@tonic-gate } 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate if ((base = ctf_type_resolve(ctfp, id)) == CTF_ERR || 313*7c478bd9Sstevel@tonic-gate (kind = ctf_type_kind(ctfp, base)) == CTF_ERR) 314*7c478bd9Sstevel@tonic-gate return (-1); 315*7c478bd9Sstevel@tonic-gate 316*7c478bd9Sstevel@tonic-gate if (ctf_type_name(ctfp, id, type, sizeof (type)) == NULL) 317*7c478bd9Sstevel@tonic-gate (void) snprintf(type, sizeof (type), "<%ld>", id); 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "%*s", (depth + pap->pa_nest) * 4, ""); 320*7c478bd9Sstevel@tonic-gate if (name[0] != '\0') 321*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "\t%s: ", name); 322*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "(%s) ", type); 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate printfuncs[kind - 1](base, off, pap); 325*7c478bd9Sstevel@tonic-gate (void) fprintf(ABISTREAM, "\n"); 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate (void) fflush(ABISTREAM); 328*7c478bd9Sstevel@tonic-gate return (0); 329*7c478bd9Sstevel@tonic-gate } 330