4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
31 #include <floatingpoint.h>
35 typedef struct printarg
{
42 typedef void printarg_f(ctf_id_t
, ulong_t
, printarg_t
*);
44 static int elt_print(const char *, ctf_id_t
, ulong_t
, int, void *);
47 type_name(ctf_file_t
*ctfp
, ctf_id_t type
, char *buf
, size_t len
)
49 if (ctf_type_name(ctfp
, type
, buf
, len
) == NULL
)
50 (void) snprintf(buf
, len
, "<%ld>", type
);
56 print_value(ctf_file_t
*ctfp
, ctf_id_t type
, ulong_t value
)
58 ctf_id_t rtype
= ctf_type_resolve(ctfp
, type
);
61 (void) fprintf(ABISTREAM
, "0x%p", (void *)value
);
63 if (ctf_type_kind(ctfp
, rtype
) == CTF_K_POINTER
) {
64 type
= ctf_type_reference(ctfp
, rtype
);
65 rtype
= ctf_type_resolve(ctfp
, type
);
67 if (ctf_type_encoding(ctfp
, rtype
, &e
) == 0 &&
68 (e
.cte_format
& (CTF_INT_CHAR
| CTF_INT_SIGNED
)) ==
69 (CTF_INT_CHAR
| CTF_INT_SIGNED
) && e
.cte_bits
== NBBY
) {
70 if ((char *)value
!= NULL
)
71 (void) fprintf(ABISTREAM
,
72 " \"%s\"", (char *)value
);
74 (void) fprintf(ABISTREAM
, " <NULL>");
75 (void) fflush(ABISTREAM
);
79 if (ctf_type_kind(ctfp
, rtype
) == CTF_K_STRUCT
) {
82 (void) fprintf(ABISTREAM
, " ");
89 (void) ctf_type_visit(ctfp
, rtype
, elt_print
, &pa
);
90 (void) fprintf(ABISTREAM
, "\t}");
91 (void) fflush(ABISTREAM
);
95 (void) fflush(ABISTREAM
);
99 print_bitfield(ulong_t off
, ctf_encoding_t
*ep
)
101 uint64_t mask
= (1ULL << ep
->cte_bits
) - 1;
104 size_t size
= (ep
->cte_bits
+ (NBBY
- 1)) / NBBY
;
105 uint8_t *buf
= (uint8_t *)&value
;
110 * On big-endian machines, we need to adjust the buf pointer to refer
111 * to the lowest 'size' bytes in 'value', and we need shift based on
112 * the offset from the end of the data, not the offset of the start.
115 buf
+= sizeof (value
) - size
;
121 * Offsets are counted from opposite ends on little- and
122 * big-endian machines.
125 shift
= NBBY
- shift
;
129 * If the bits we want do not begin on a byte boundary, shift the data
130 * right so that the value is in the lowest 'cte_bits' of 'value'.
135 (void) fprintf(ABISTREAM
, "%llu", (unsigned long long)(value
& mask
));
136 (void) fflush(ABISTREAM
);
141 print_int(ctf_id_t base
, ulong_t off
, printarg_t
*pap
)
143 ctf_file_t
*ctfp
= pap
->pa_ctfp
;
146 ulong_t addr
= pap
->pa_addr
+ off
/ NBBY
;
148 if (ctf_type_encoding(ctfp
, base
, &e
) == CTF_ERR
) {
149 (void) fprintf(ABISTREAM
, "???");
150 (void) fflush(ABISTREAM
);
154 if (e
.cte_format
& CTF_INT_VARARGS
) {
155 (void) fprintf(ABISTREAM
, "...\n");
156 (void) fflush(ABISTREAM
);
160 size
= e
.cte_bits
/ NBBY
;
161 if (size
> 8 || (e
.cte_bits
% NBBY
) != 0 || (size
& (size
- 1)) != 0) {
162 print_bitfield(off
, &e
);
166 if (((e
).cte_format
& (CTF_INT_CHAR
| CTF_INT_SIGNED
)) ==
167 (CTF_INT_CHAR
| CTF_INT_SIGNED
) && (e
).cte_bits
== NBBY
) {
168 (void) fprintf(ABISTREAM
, "'%c'", *(char *)addr
);
169 (void) fflush(ABISTREAM
);
174 case sizeof (uint8_t):
175 (void) fprintf(ABISTREAM
, "%#x", *(uint8_t *)addr
);
177 case sizeof (uint16_t):
178 (void) fprintf(ABISTREAM
, "%#x", *(uint16_t *)addr
);
180 case sizeof (uint32_t):
181 (void) fprintf(ABISTREAM
, "%#x", *(uint32_t *)addr
);
183 case sizeof (uint64_t):
184 (void) fprintf(ABISTREAM
, "%#llx",
185 (unsigned long long)*(uint64_t *)addr
);
188 (void) fflush(ABISTREAM
);
193 print_float(ctf_id_t base
, ulong_t off
, printarg_t
*pap
)
195 ctf_file_t
*ctfp
= pap
->pa_ctfp
;
205 if (ctf_type_encoding(ctfp
, base
, &e
) == 0) {
206 if (e
.cte_format
== CTF_FP_SINGLE
&&
207 e
.cte_bits
== sizeof (float) * NBBY
) {
208 (void) fprintf(ABISTREAM
, "%+.7e", u
.f
);
209 } else if (e
.cte_format
== CTF_FP_DOUBLE
&&
210 e
.cte_bits
== sizeof (double) * NBBY
) {
211 (void) fprintf(ABISTREAM
, "%+.7e", u
.d
);
212 } else if (e
.cte_format
== CTF_FP_LDOUBLE
&&
213 e
.cte_bits
== sizeof (long double) * NBBY
) {
214 (void) fprintf(ABISTREAM
,
218 (void) fflush(ABISTREAM
);
223 print_ptr(ctf_id_t base
, ulong_t off
, printarg_t
*pap
)
225 ctf_file_t
*ctfp
= pap
->pa_ctfp
;
226 ulong_t addr
= pap
->pa_addr
+ off
/ NBBY
;
229 if (ctf_type_kind(ctfp
, base
) != CTF_K_POINTER
)
232 if ((base
= ctf_type_reference(ctfp
, base
)) == CTF_ERR
)
235 if ((base
= ctf_type_resolve(ctfp
, base
)) == CTF_ERR
)
238 if (ctf_type_encoding(ctfp
, base
, &e
) != 0)
241 if (((e
).cte_format
& (CTF_INT_CHAR
| CTF_INT_SIGNED
)) ==
242 (CTF_INT_CHAR
| CTF_INT_SIGNED
) && (e
).cte_bits
== NBBY
)
243 (void) fprintf(ABISTREAM
, "'%c'", *(char *)addr
);
244 (void) fflush(ABISTREAM
);
249 print_array(ctf_id_t base
, ulong_t off
, printarg_t
*pap
)
251 ulong_t addr
= pap
->pa_addr
+ off
/ NBBY
;
253 (void) fprintf(ABISTREAM
, "0x%p", (void *)addr
);
254 (void) fflush(ABISTREAM
);
259 print_sou(ctf_id_t base
, ulong_t off
, printarg_t
*pap
)
261 (void) fprintf(ABISTREAM
, "{");
266 print_enum(ctf_id_t base
, ulong_t off
, printarg_t
*pap
)
268 ctf_file_t
*ctfp
= pap
->pa_ctfp
;
272 if ((ename
= ctf_enum_name(ctfp
, base
, value
)) != NULL
)
273 (void) fprintf(ABISTREAM
, "%s", ename
);
275 (void) fprintf(ABISTREAM
, "%d", value
);
276 (void) fflush(ABISTREAM
);
281 print_tag(ctf_id_t base
, ulong_t off
, printarg_t
*pap
)
283 (void) fprintf(ABISTREAM
, "; ");
286 static printarg_f
*const printfuncs
[] = {
287 print_int
, /* CTF_K_INTEGER */
288 print_float
, /* CTF_K_FLOAT */
289 print_ptr
, /* CTF_K_POINTER */
290 print_array
, /* CTF_K_ARRAY */
291 print_ptr
, /* CTF_K_FUNCTION */
292 print_sou
, /* CTF_K_STRUCT */
293 print_sou
, /* CTF_K_UNION */
294 print_enum
, /* CTF_K_ENUM */
295 print_tag
/* CTF_K_FORWARD */
299 elt_print(const char *name
, ctf_id_t id
, ulong_t off
, int depth
, void *data
)
304 printarg_t
*pap
= data
;
305 ctf_file_t
*ctfp
= pap
->pa_ctfp
;
307 for (d
= pap
->pa_depth
- 1; d
>= depth
; d
--) {
308 (void) fprintf(ABISTREAM
, "%*s}\n",
309 (depth
+ pap
->pa_nest
) * 4, "");
312 if ((base
= ctf_type_resolve(ctfp
, id
)) == CTF_ERR
||
313 (kind
= ctf_type_kind(ctfp
, base
)) == CTF_ERR
)
316 if (ctf_type_name(ctfp
, id
, type
, sizeof (type
)) == NULL
)
317 (void) snprintf(type
, sizeof (type
), "<%ld>", id
);
319 (void) fprintf(ABISTREAM
, "%*s", (depth
+ pap
->pa_nest
) * 4, "");
321 (void) fprintf(ABISTREAM
, "\t%s: ", name
);
322 (void) fprintf(ABISTREAM
, "(%s) ", type
);
324 printfuncs
[kind
- 1](base
, off
, pap
);
325 (void) fprintf(ABISTREAM
, "\n");
327 (void) fflush(ABISTREAM
);