4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * Copyright (c) 2013 by Delphix. All rights reserved.
27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
30 #include <mdb/mdb_ctf.h>
31 #include <mdb/mdb_ctf_impl.h>
32 #include <mdb/mdb_err.h>
33 #include <mdb/mdb_modapi.h>
34 #include <mdb/mdb_string.h>
36 #include <mdb/mdb_debug.h>
41 typedef struct tnarg
{
42 mdb_tgt_t
*tn_tgt
; /* target to use for lookup */
43 const char *tn_name
; /* query string to lookup */
44 ctf_file_t
*tn_fp
; /* CTF container from match */
45 ctf_id_t tn_id
; /* CTF type ID from match */
48 typedef struct type_iter
{
49 mdb_ctf_type_f
*ti_cb
;
54 typedef struct member_iter
{
55 mdb_ctf_member_f
*mi_cb
;
60 typedef struct type_visit
{
61 mdb_ctf_visit_f
*tv_cb
;
64 ulong_t tv_base_offset
; /* used when recursing from type_cb() */
65 int tv_base_depth
; /* used when recursing from type_cb() */
69 typedef struct mbr_info
{
70 const char *mbr_member
;
72 mdb_ctf_id_t
*mbr_typep
;
75 typedef struct synth_intrinsic
{
77 ctf_encoding_t syn_enc
;
81 typedef struct synth_typedef
{
87 * As part of our support for synthetic types via ::typedef, we define a core
90 static const synth_intrinsic_t synth_builtins32
[] = {
91 { "void", { CTF_INT_SIGNED
, 0, 0 }, CTF_K_INTEGER
},
92 { "signed", { CTF_INT_SIGNED
, 0, 32 }, CTF_K_INTEGER
},
93 { "unsigned", { 0, 0, 32 }, CTF_K_INTEGER
},
94 { "char", { CTF_INT_SIGNED
| CTF_INT_CHAR
, 0, 8 }, CTF_K_INTEGER
},
95 { "short", { CTF_INT_SIGNED
, 0, 16 }, CTF_K_INTEGER
},
96 { "int", { CTF_INT_SIGNED
, 0, 32 }, CTF_K_INTEGER
},
97 { "long", { CTF_INT_SIGNED
, 0, 32 }, CTF_K_INTEGER
},
98 { "long long", { CTF_INT_SIGNED
, 0, 64 }, CTF_K_INTEGER
},
99 { "signed char", { CTF_INT_SIGNED
| CTF_INT_CHAR
, 0, 8 }, CTF_K_INTEGER
},
100 { "signed short", { CTF_INT_SIGNED
, 0, 16 }, CTF_K_INTEGER
},
101 { "signed int", { CTF_INT_SIGNED
, 0, 32 }, CTF_K_INTEGER
},
102 { "signed long", { CTF_INT_SIGNED
, 0, 32 }, CTF_K_INTEGER
},
103 { "signed long long", { CTF_INT_SIGNED
, 0, 64 }, CTF_K_INTEGER
},
104 { "unsigned char", { CTF_INT_CHAR
, 0, 8 }, CTF_K_INTEGER
},
105 { "unsigned short", { 0, 0, 16 }, CTF_K_INTEGER
},
106 { "unsigned int", { 0, 0, 32 }, CTF_K_INTEGER
},
107 { "unsigned long", { 0, 0, 32 }, CTF_K_INTEGER
},
108 { "unsigned long long", { 0, 0, 64 }, CTF_K_INTEGER
},
109 { "_Bool", { CTF_INT_BOOL
, 0, 8 }, CTF_K_INTEGER
},
110 { "float", { CTF_FP_SINGLE
, 0, 32 }, CTF_K_FLOAT
},
111 { "double", { CTF_FP_DOUBLE
, 0, 64 }, CTF_K_FLOAT
},
112 { "long double", { CTF_FP_LDOUBLE
, 0, 128 }, CTF_K_FLOAT
},
113 { "float imaginary", { CTF_FP_IMAGRY
, 0, 32 }, CTF_K_FLOAT
},
114 { "double imaginary", { CTF_FP_DIMAGRY
, 0, 64 }, CTF_K_FLOAT
},
115 { "long double imaginary", { CTF_FP_LDIMAGRY
, 0, 128 }, CTF_K_FLOAT
},
116 { "float complex", { CTF_FP_CPLX
, 0, 64 }, CTF_K_FLOAT
},
117 { "double complex", { CTF_FP_DCPLX
, 0, 128 }, CTF_K_FLOAT
},
118 { "long double complex", { CTF_FP_LDCPLX
, 0, 256 }, CTF_K_FLOAT
},
119 { NULL
, { 0, 0, 0}, 0 }
122 static const synth_intrinsic_t synth_builtins64
[] = {
123 { "void", { CTF_INT_SIGNED
, 0, 0 }, CTF_K_INTEGER
},
124 { "signed", { CTF_INT_SIGNED
, 0, 32 }, CTF_K_INTEGER
},
125 { "unsigned", { 0, 0, 32 }, CTF_K_INTEGER
},
126 { "char", { CTF_INT_SIGNED
| CTF_INT_CHAR
, 0, 8 }, CTF_K_INTEGER
},
127 { "short", { CTF_INT_SIGNED
, 0, 16 }, CTF_K_INTEGER
},
128 { "int", { CTF_INT_SIGNED
, 0, 32 }, CTF_K_INTEGER
},
129 { "long", { CTF_INT_SIGNED
, 0, 64 }, CTF_K_INTEGER
},
130 { "long long", { CTF_INT_SIGNED
, 0, 64 }, CTF_K_INTEGER
},
131 { "signed char", { CTF_INT_SIGNED
| CTF_INT_CHAR
, 0, 8 }, CTF_K_INTEGER
},
132 { "signed short", { CTF_INT_SIGNED
, 0, 16 }, CTF_K_INTEGER
},
133 { "signed int", { CTF_INT_SIGNED
, 0, 32 }, CTF_K_INTEGER
},
134 { "signed long", { CTF_INT_SIGNED
, 0, 64 }, CTF_K_INTEGER
},
135 { "signed long long", { CTF_INT_SIGNED
, 0, 64 }, CTF_K_INTEGER
},
136 { "unsigned char", { CTF_INT_CHAR
, 0, 8 }, CTF_K_INTEGER
},
137 { "unsigned short", { 0, 0, 16 }, CTF_K_INTEGER
},
138 { "unsigned int", { 0, 0, 32 }, CTF_K_INTEGER
},
139 { "unsigned long", { 0, 0, 64 }, CTF_K_INTEGER
},
140 { "unsigned long long", { 0, 0, 64 }, CTF_K_INTEGER
},
141 { "_Bool", { CTF_INT_BOOL
, 0, 8 }, CTF_K_INTEGER
},
142 { "float", { CTF_FP_SINGLE
, 0, 32 }, CTF_K_FLOAT
},
143 { "double", { CTF_FP_DOUBLE
, 0, 64 }, CTF_K_FLOAT
},
144 { "long double", { CTF_FP_LDOUBLE
, 0, 128 }, CTF_K_FLOAT
},
145 { "float imaginary", { CTF_FP_IMAGRY
, 0, 32 }, CTF_K_FLOAT
},
146 { "double imaginary", { CTF_FP_DIMAGRY
, 0, 64 }, CTF_K_FLOAT
},
147 { "long double imaginary", { CTF_FP_LDIMAGRY
, 0, 128 }, CTF_K_FLOAT
},
148 { "float complex", { CTF_FP_CPLX
, 0, 64 }, CTF_K_FLOAT
},
149 { "double complex", { CTF_FP_DCPLX
, 0, 128 }, CTF_K_FLOAT
},
150 { "long double complex", { CTF_FP_LDCPLX
, 0, 256 }, CTF_K_FLOAT
},
151 { NULL
, { 0, 0, 0 }, 0 }
154 static const synth_typedef_t synth_typedefs32
[] = {
155 { "char", "int8_t" },
156 { "short", "int16_t" },
157 { "int", "int32_t" },
158 { "long long", "int64_t" },
159 { "int", "intptr_t" },
160 { "unsigned char", "uint8_t" },
161 { "unsigned short", "uint16_t" },
162 { "unsigned", "uint32_t" },
163 { "unsigned long long", "uint64_t" },
164 { "unsigned char", "uchar_t" },
165 { "unsigned short", "ushort_t" },
166 { "unsigned", "uint_t" },
167 { "unsigned long", "ulong_t" },
168 { "unsigned long long", "u_longlong_t" },
169 { "int", "ptrdiff_t" },
170 { "unsigned", "uintptr_t" },
174 static const synth_typedef_t synth_typedefs64
[] = {
175 { "char", "int8_t" },
176 { "short", "int16_t" },
177 { "int", "int32_t" },
178 { "long", "int64_t" },
179 { "long", "intptr_t" },
180 { "unsigned char", "uint8_t" },
181 { "unsigned short", "uint16_t" },
182 { "unsigned", "uint32_t" },
183 { "unsigned long", "uint64_t" },
184 { "unsigned char", "uchar_t" },
185 { "unsigned short", "ushort_t" },
186 { "unsigned", "uint_t" },
187 { "unsigned long", "ulong_t" },
188 { "unsigned long long", "u_longlong_t" },
189 { "long", "ptrdiff_t" },
190 { "unsigned long", "uintptr_t" },
195 set_ctf_id(mdb_ctf_id_t
*p
, ctf_file_t
*fp
, ctf_id_t id
)
197 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)p
;
204 * Callback function for mdb_tgt_object_iter used from name_to_type, below,
205 * to search the CTF namespace of each object file for a particular name.
209 obj_lookup(void *data
, const mdb_map_t
*mp
, const char *name
)
215 if ((fp
= mdb_tgt_name_to_ctf(tnp
->tn_tgt
, name
)) != NULL
&&
216 (id
= ctf_lookup_by_name(fp
, tnp
->tn_name
)) != CTF_ERR
) {
221 * We may have found a forward declaration. If we did, we'll
222 * note the ID and file pointer, but we'll keep searching in
223 * an attempt to find the real thing. If we found something
224 * real (i.e. not a forward), we stop the iteration.
226 return (ctf_type_kind(fp
, id
) == CTF_K_FORWARD
? 0 : -1);
233 * Convert a string type name with an optional leading object specifier into
234 * the corresponding CTF file container and type ID. If an error occurs, we
235 * print an appropriate message and return NULL.
238 name_to_type(mdb_tgt_t
*t
, const char *cname
, ctf_id_t
*idp
)
240 const char *object
= MDB_TGT_OBJ_EXEC
;
241 ctf_file_t
*fp
= NULL
;
245 char buf
[MDB_SYM_NAMLEN
];
246 char *name
= &buf
[0];
248 (void) mdb_snprintf(buf
, sizeof (buf
), "%s", cname
);
250 if ((p
= strrsplit(name
, '`')) != NULL
) {
252 * We need to shuffle things around a little to support
253 * type names of the form "struct module`name".
255 if ((s
= strsplit(name
, ' ')) != NULL
) {
256 bcopy(cname
+ (s
- name
), name
, (p
- s
) - 1);
257 name
[(p
- s
) - 1] = '\0';
258 bcopy(cname
, name
+ (p
- s
), s
- name
);
267 * Attempt to look up the name in the primary object file. If this
268 * fails and the name was unscoped, search all remaining object files.
269 * Finally, search the synthetic types.
271 if (((fp
= mdb_tgt_name_to_ctf(t
, object
)) == NULL
||
272 (id
= ctf_lookup_by_name(fp
, name
)) == CTF_ERR
||
273 ctf_type_kind(fp
, id
) == CTF_K_FORWARD
) &&
274 object
== MDB_TGT_OBJ_EXEC
) {
281 (void) mdb_tgt_object_iter(t
, obj_lookup
, &arg
);
283 if (arg
.tn_id
!= CTF_ERR
) {
286 } else if (mdb
.m_synth
!= NULL
) {
287 if ((id
= ctf_lookup_by_name(mdb
.m_synth
,
294 return (NULL
); /* errno is set for us */
297 (void) set_errno(ctf_to_errno(ctf_errno(fp
)));
306 * Check to see if there is ctf data in the given object. This is useful
307 * so that we don't enter some loop where every call to lookup fails.
310 mdb_ctf_enabled_by_object(const char *object
)
312 mdb_tgt_t
*t
= mdb
.m_target
;
314 return (mdb_tgt_name_to_ctf(t
, object
) != NULL
);
318 mdb_ctf_lookup_by_name(const char *name
, mdb_ctf_id_t
*p
)
320 ctf_file_t
*fp
= NULL
;
321 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)p
;
322 mdb_tgt_t
*t
= mdb
.m_target
;
325 return (set_errno(EINVAL
));
327 if ((fp
= name_to_type(t
, name
, &mcip
->mci_id
)) == NULL
) {
328 mdb_ctf_type_invalidate(p
);
329 return (-1); /* errno is set for us */
338 mdb_ctf_lookup_by_symbol(const GElf_Sym
*symp
, const mdb_syminfo_t
*sip
,
341 ctf_file_t
*fp
= NULL
;
342 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)p
;
343 mdb_tgt_t
*t
= mdb
.m_target
;
346 return (set_errno(EINVAL
));
348 if (symp
== NULL
|| sip
== NULL
) {
349 mdb_ctf_type_invalidate(p
);
350 return (set_errno(EINVAL
));
353 if ((fp
= mdb_tgt_addr_to_ctf(t
, symp
->st_value
)) == NULL
) {
354 mdb_ctf_type_invalidate(p
);
355 return (-1); /* errno is set for us */
358 if ((mcip
->mci_id
= ctf_lookup_by_symbol(fp
, sip
->sym_id
)) == CTF_ERR
) {
359 mdb_ctf_type_invalidate(p
);
360 return (set_errno(ctf_to_errno(ctf_errno(fp
))));
369 mdb_ctf_lookup_by_addr(uintptr_t addr
, mdb_ctf_id_t
*p
)
373 char name
[MDB_SYM_NAMLEN
];
375 mdb_tgt_t
*t
= mdb
.m_target
;
379 return (set_errno(EINVAL
));
381 if (mdb_tgt_lookup_by_addr(t
, addr
, MDB_TGT_SYM_EXACT
, name
,
382 sizeof (name
), NULL
, NULL
) == -1) {
383 mdb_ctf_type_invalidate(p
);
384 return (-1); /* errno is set for us */
387 if ((c
= strrsplit(name
, '`')) != NULL
) {
390 if ((mp
= mdb_tgt_addr_to_map(t
, addr
)) == NULL
) {
391 mdb_ctf_type_invalidate(p
);
392 return (-1); /* errno is set for us */
399 if (mdb_tgt_lookup_by_name(t
, obj
, c
, &sym
, &si
) == -1) {
400 mdb_ctf_type_invalidate(p
);
401 return (-1); /* errno is set for us */
404 return (mdb_ctf_lookup_by_symbol(&sym
, &si
, p
));
408 mdb_ctf_module_lookup(const char *name
, mdb_ctf_id_t
*p
)
414 if ((mod
= mdb_get_module()) == NULL
)
415 return (set_errno(EMDB_CTX
));
417 if ((fp
= mod
->mod_ctfp
) == NULL
)
418 return (set_errno(EMDB_NOCTF
));
420 if ((id
= ctf_lookup_by_name(fp
, name
)) == CTF_ERR
)
421 return (set_errno(ctf_to_errno(ctf_errno(fp
))));
423 set_ctf_id(p
, fp
, id
);
430 mdb_ctf_func_info(const GElf_Sym
*symp
, const mdb_syminfo_t
*sip
,
431 mdb_ctf_funcinfo_t
*mfp
)
433 ctf_file_t
*fp
= NULL
;
435 mdb_tgt_t
*t
= mdb
.m_target
;
436 char name
[MDB_SYM_NAMLEN
];
441 if (symp
== NULL
|| mfp
== NULL
)
442 return (set_errno(EINVAL
));
445 * In case the input symbol came from a merged or private symbol table,
446 * re-lookup the address as a symbol, and then perform a fully scoped
447 * lookup of that symbol name to get the mdb_syminfo_t for its CTF.
449 if ((fp
= mdb_tgt_addr_to_ctf(t
, symp
->st_value
)) == NULL
||
450 (mp
= mdb_tgt_addr_to_map(t
, symp
->st_value
)) == NULL
||
451 mdb_tgt_lookup_by_addr(t
, symp
->st_value
, MDB_TGT_SYM_FUZZY
,
452 name
, sizeof (name
), NULL
, NULL
) != 0)
453 return (-1); /* errno is set for us */
455 if (strchr(name
, '`') != NULL
)
456 err
= mdb_tgt_lookup_by_scope(t
, name
, NULL
, &si
);
458 err
= mdb_tgt_lookup_by_name(t
, mp
->map_name
, name
, NULL
, &si
);
461 return (-1); /* errno is set for us */
463 if (ctf_func_info(fp
, si
.sym_id
, &f
) == CTF_ERR
)
464 return (set_errno(ctf_to_errno(ctf_errno(fp
))));
466 set_ctf_id(&mfp
->mtf_return
, fp
, f
.ctc_return
);
467 mfp
->mtf_argc
= f
.ctc_argc
;
468 mfp
->mtf_flags
= f
.ctc_flags
;
469 mfp
->mtf_symidx
= si
.sym_id
;
475 mdb_ctf_func_args(const mdb_ctf_funcinfo_t
*funcp
, uint_t len
,
482 if (len
> (sizeof (cargv
) / sizeof (cargv
[0])))
483 return (set_errno(EINVAL
));
485 if (funcp
== NULL
|| argv
== NULL
)
486 return (set_errno(EINVAL
));
488 fp
= mdb_ctf_type_file(funcp
->mtf_return
);
490 if (ctf_func_args(fp
, funcp
->mtf_symidx
, len
, cargv
) == CTF_ERR
)
491 return (set_errno(ctf_to_errno(ctf_errno(fp
))));
493 for (i
= MIN(len
, funcp
->mtf_argc
) - 1; i
>= 0; i
--) {
494 set_ctf_id(&argv
[i
], fp
, cargv
[i
]);
501 mdb_ctf_type_invalidate(mdb_ctf_id_t
*idp
)
503 set_ctf_id(idp
, NULL
, CTF_ERR
);
507 mdb_ctf_type_valid(mdb_ctf_id_t id
)
509 return (((mdb_ctf_impl_t
*)&id
)->mci_id
!= CTF_ERR
);
513 mdb_ctf_type_cmp(mdb_ctf_id_t aid
, mdb_ctf_id_t bid
)
515 mdb_ctf_impl_t
*aidp
= (mdb_ctf_impl_t
*)&aid
;
516 mdb_ctf_impl_t
*bidp
= (mdb_ctf_impl_t
*)&bid
;
518 return (ctf_type_cmp(aidp
->mci_fp
, aidp
->mci_id
,
519 bidp
->mci_fp
, bidp
->mci_id
));
523 mdb_ctf_type_resolve(mdb_ctf_id_t mid
, mdb_ctf_id_t
*outp
)
526 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&mid
;
528 if ((id
= ctf_type_resolve(idp
->mci_fp
, idp
->mci_id
)) == CTF_ERR
) {
530 mdb_ctf_type_invalidate(outp
);
531 return (set_errno(ctf_to_errno(ctf_errno(idp
->mci_fp
))));
534 if (ctf_type_kind(idp
->mci_fp
, id
) == CTF_K_FORWARD
) {
535 char name
[MDB_SYM_NAMLEN
];
536 mdb_ctf_id_t lookup_id
;
538 if (ctf_type_name(idp
->mci_fp
, id
, name
, sizeof (name
)) !=
540 mdb_ctf_lookup_by_name(name
, &lookup_id
) == 0 &&
548 set_ctf_id(outp
, idp
->mci_fp
, id
);
554 mdb_ctf_type_name(mdb_ctf_id_t id
, char *buf
, size_t len
)
556 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&id
;
559 if (!mdb_ctf_type_valid(id
)) {
560 (void) set_errno(EINVAL
);
564 ret
= ctf_type_name(idp
->mci_fp
, idp
->mci_id
, buf
, len
);
566 (void) set_errno(ctf_to_errno(ctf_errno(idp
->mci_fp
)));
572 mdb_ctf_type_size(mdb_ctf_id_t id
)
574 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&id
;
577 /* resolve the type in case there's a forward declaration */
578 if ((ret
= mdb_ctf_type_resolve(id
, &id
)) != 0)
581 if ((ret
= ctf_type_size(idp
->mci_fp
, idp
->mci_id
)) == CTF_ERR
)
582 return (set_errno(ctf_to_errno(ctf_errno(idp
->mci_fp
))));
588 mdb_ctf_type_kind(mdb_ctf_id_t id
)
590 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&id
;
593 if ((ret
= ctf_type_kind(idp
->mci_fp
, idp
->mci_id
)) == CTF_ERR
)
594 return (set_errno(ctf_to_errno(ctf_errno(idp
->mci_fp
))));
600 mdb_ctf_type_reference(mdb_ctf_id_t mid
, mdb_ctf_id_t
*outp
)
602 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&mid
;
605 if ((id
= ctf_type_reference(idp
->mci_fp
, idp
->mci_id
)) == CTF_ERR
) {
607 mdb_ctf_type_invalidate(outp
);
608 return (set_errno(ctf_to_errno(ctf_errno(idp
->mci_fp
))));
612 set_ctf_id(outp
, idp
->mci_fp
, id
);
619 mdb_ctf_type_encoding(mdb_ctf_id_t id
, ctf_encoding_t
*ep
)
621 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&id
;
623 if (ctf_type_encoding(idp
->mci_fp
, idp
->mci_id
, ep
) == CTF_ERR
)
624 return (set_errno(ctf_to_errno(ctf_errno(idp
->mci_fp
))));
630 * callback proxy for mdb_ctf_type_visit
633 type_cb(const char *name
, ctf_id_t type
, ulong_t off
, int depth
, void *arg
)
635 type_visit_t
*tvp
= arg
;
638 mdb_ctf_impl_t
*basep
= (mdb_ctf_impl_t
*)&base
;
642 if (depth
< tvp
->tv_min_depth
)
645 off
+= tvp
->tv_base_offset
;
646 depth
+= tvp
->tv_base_depth
;
648 set_ctf_id(&id
, tvp
->tv_fp
, type
);
650 (void) mdb_ctf_type_resolve(id
, &base
);
651 if ((ret
= tvp
->tv_cb(name
, id
, base
, off
, depth
, tvp
->tv_arg
)) != 0)
655 * If the type resolves to a type in a different file, we must have
656 * followed a forward declaration. We need to recurse into the
659 if (basep
->mci_fp
!= tvp
->tv_fp
&& mdb_ctf_type_valid(base
)) {
662 tv
.tv_cb
= tvp
->tv_cb
;
663 tv
.tv_arg
= tvp
->tv_arg
;
664 tv
.tv_fp
= basep
->mci_fp
;
666 tv
.tv_base_offset
= off
;
667 tv
.tv_base_depth
= depth
;
668 tv
.tv_min_depth
= 1; /* depth = 0 has already been done */
670 ret
= ctf_type_visit(basep
->mci_fp
, basep
->mci_id
,
677 mdb_ctf_type_visit(mdb_ctf_id_t id
, mdb_ctf_visit_f
*func
, void *arg
)
679 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&id
;
685 tv
.tv_fp
= idp
->mci_fp
;
686 tv
.tv_base_offset
= 0;
687 tv
.tv_base_depth
= 0;
690 ret
= ctf_type_visit(idp
->mci_fp
, idp
->mci_id
, type_cb
, &tv
);
693 return (set_errno(ctf_to_errno(ctf_errno(idp
->mci_fp
))));
699 mdb_ctf_array_info(mdb_ctf_id_t id
, mdb_ctf_arinfo_t
*arp
)
701 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&id
;
704 if (ctf_array_info(idp
->mci_fp
, idp
->mci_id
, &car
) == CTF_ERR
)
705 return (set_errno(ctf_to_errno(ctf_errno(idp
->mci_fp
))));
707 set_ctf_id(&arp
->mta_contents
, idp
->mci_fp
, car
.ctr_contents
);
708 set_ctf_id(&arp
->mta_index
, idp
->mci_fp
, car
.ctr_index
);
710 arp
->mta_nelems
= car
.ctr_nelems
;
716 mdb_ctf_enum_name(mdb_ctf_id_t id
, int value
)
718 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&id
;
721 /* resolve the type in case there's a forward declaration */
722 if (mdb_ctf_type_resolve(id
, &id
) != 0)
725 if ((ret
= ctf_enum_name(idp
->mci_fp
, idp
->mci_id
, value
)) == NULL
)
726 (void) set_errno(ctf_to_errno(ctf_errno(idp
->mci_fp
)));
732 * callback proxy for mdb_ctf_member_iter
735 member_iter_cb(const char *name
, ctf_id_t type
, ulong_t off
, void *data
)
737 member_iter_t
*mip
= data
;
740 set_ctf_id(&id
, mip
->mi_fp
, type
);
742 return (mip
->mi_cb(name
, id
, off
, mip
->mi_arg
));
746 mdb_ctf_member_iter(mdb_ctf_id_t id
, mdb_ctf_member_f
*cb
, void *data
)
748 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&id
;
752 /* resolve the type in case there's a forward declaration */
753 if ((ret
= mdb_ctf_type_resolve(id
, &id
)) != 0)
758 mi
.mi_fp
= idp
->mci_fp
;
760 ret
= ctf_member_iter(idp
->mci_fp
, idp
->mci_id
, member_iter_cb
, &mi
);
763 return (set_errno(ctf_to_errno(ctf_errno(idp
->mci_fp
))));
769 mdb_ctf_enum_iter(mdb_ctf_id_t id
, mdb_ctf_enum_f
*cb
, void *data
)
771 mdb_ctf_impl_t
*idp
= (mdb_ctf_impl_t
*)&id
;
774 /* resolve the type in case there's a forward declaration */
775 if ((ret
= mdb_ctf_type_resolve(id
, &id
)) != 0)
778 return (ctf_enum_iter(idp
->mci_fp
, idp
->mci_id
, cb
, data
));
782 * callback proxy for mdb_ctf_type_iter
785 type_iter_cb(ctf_id_t type
, void *data
)
787 type_iter_t
*tip
= data
;
790 set_ctf_id(&id
, tip
->ti_fp
, type
);
792 return (tip
->ti_cb(id
, tip
->ti_arg
));
796 mdb_ctf_type_iter(const char *object
, mdb_ctf_type_f
*cb
, void *data
)
799 mdb_tgt_t
*t
= mdb
.m_target
;
803 if (object
== MDB_CTF_SYNTHETIC_ITER
)
806 fp
= mdb_tgt_name_to_ctf(t
, object
);
815 if ((ret
= ctf_type_iter(fp
, type_iter_cb
, &ti
)) == CTF_ERR
)
816 return (set_errno(ctf_to_errno(ctf_errno(fp
))));
821 /* utility functions */
824 mdb_ctf_type_id(mdb_ctf_id_t id
)
826 return (((mdb_ctf_impl_t
*)&id
)->mci_id
);
830 mdb_ctf_type_file(mdb_ctf_id_t id
)
832 return (((mdb_ctf_impl_t
*)&id
)->mci_fp
);
836 member_info_cb(const char *name
, mdb_ctf_id_t id
, ulong_t off
, void *data
)
838 mbr_info_t
*mbrp
= data
;
840 if (strcmp(name
, mbrp
->mbr_member
) == 0) {
841 if (mbrp
->mbr_offp
!= NULL
)
842 *(mbrp
->mbr_offp
) = off
;
843 if (mbrp
->mbr_typep
!= NULL
)
844 *(mbrp
->mbr_typep
) = id
;
853 mdb_ctf_member_info(mdb_ctf_id_t id
, const char *member
, ulong_t
*offp
,
859 mbr
.mbr_member
= member
;
861 mbr
.mbr_typep
= typep
;
863 rc
= mdb_ctf_member_iter(id
, member_info_cb
, &mbr
);
865 /* couldn't get member list */
867 return (-1); /* errno is set for us */
871 return (set_errno(EMDB_CTFNOMEMB
));
877 * Returns offset in _bits_ in *retp.
880 mdb_ctf_offsetof(mdb_ctf_id_t id
, const char *member
, ulong_t
*retp
)
882 return (mdb_ctf_member_info(id
, member
, retp
, NULL
));
886 * Returns offset in _bytes_, or -1 on failure.
889 mdb_ctf_offsetof_by_name(const char *type
, const char *member
)
894 if (mdb_ctf_lookup_by_name(type
, &id
) == -1) {
895 mdb_warn("couldn't find type %s", type
);
899 if (mdb_ctf_offsetof(id
, member
, &off
) == -1) {
900 mdb_warn("couldn't find member %s of type %s", member
, type
);
904 mdb_warn("member %s of type %s is an unsupported bitfield\n",
916 num_members_cb(const char *name
, mdb_ctf_id_t id
, ulong_t off
, void *data
)
924 mdb_ctf_num_members(mdb_ctf_id_t id
)
928 if (mdb_ctf_member_iter(id
, num_members_cb
, &count
) != 0)
929 return (-1); /* errno is set for us */
934 typedef struct mbr_contains
{
938 mdb_ctf_id_t
*mbc_idp
;
943 offset_to_name_cb(const char *name
, mdb_ctf_id_t id
, ulong_t off
, void *data
)
945 mbr_contains_t
*mbc
= data
;
950 if (*mbc
->mbc_offp
< off
)
953 if (mdb_ctf_type_encoding(id
, &e
) == -1)
954 size
= mdb_ctf_type_size(id
) * NBBY
;
958 if (off
+ size
<= *mbc
->mbc_offp
)
961 n
= mdb_snprintf(*mbc
->mbc_bufp
, *mbc
->mbc_lenp
, "%s", name
);
963 if (n
> *mbc
->mbc_lenp
)
969 *mbc
->mbc_offp
-= off
;
976 mdb_ctf_offset_to_name(mdb_ctf_id_t id
, ulong_t off
, char *buf
, size_t len
,
977 int dot
, mdb_ctf_id_t
*midp
, ulong_t
*moffp
)
983 if (!mdb_ctf_type_valid(id
))
984 return (set_errno(EINVAL
));
987 * Quick sanity check to make sure the given offset is within
988 * this scope of this type.
990 if (mdb_ctf_type_size(id
) * NBBY
<= off
)
991 return (set_errno(EINVAL
));
1003 * Check for an exact match.
1008 (void) mdb_ctf_type_resolve(id
, &id
);
1011 * Find the member that contains this offset.
1013 switch (mdb_ctf_type_kind(id
)) {
1015 mdb_ctf_arinfo_t ar
;
1018 (void) mdb_ctf_array_info(id
, &ar
);
1019 size
= mdb_ctf_type_size(ar
.mta_contents
) * NBBY
;
1022 id
= ar
.mta_contents
;
1025 n
= mdb_snprintf(buf
, len
, "[%u]", index
);
1035 case CTF_K_STRUCT
: {
1039 * Find the member that contains this offset
1052 ret
= mdb_ctf_member_iter(id
, offset_to_name_cb
, &mbc
);
1054 return (-1); /* errno is set for us */
1057 * If we did not find a member containing this offset
1058 * (due to holes in the structure), return EINVAL.
1061 return (set_errno(EINVAL
));
1068 * Treat unions like atomic entities since we can't
1069 * do more than guess which member of the union
1070 * might be the intended one.
1081 return (set_errno(EINVAL
));
1092 return (mbc
.mbc_total
);
1096 mdb_ctf_warn(uint_t flags
, const char *format
, ...)
1100 if (flags
& MDB_CTF_VREAD_QUIET
)
1103 va_start(alist
, format
);
1104 vwarn(format
, alist
);
1109 * Check if two types are structurally the same rather than logically
1110 * the same. That is to say that two types are equal if they have the
1111 * same logical structure rather than having the same ids in CTF-land.
1113 static int type_equals(mdb_ctf_id_t
, mdb_ctf_id_t
);
1116 type_equals_cb(const char *name
, mdb_ctf_id_t amem
, ulong_t aoff
, void *data
)
1118 mdb_ctf_id_t b
= *(mdb_ctf_id_t
*)data
;
1123 * Look up the corresponding member in the other composite type.
1125 if (mdb_ctf_member_info(b
, name
, &boff
, &bmem
) != 0)
1129 * We don't allow members to be shuffled around.
1134 return (type_equals(amem
, bmem
) ? 0 : 1);
1138 type_equals(mdb_ctf_id_t a
, mdb_ctf_id_t b
)
1142 mdb_ctf_arinfo_t aar
, bar
;
1145 * Resolve both types down to their fundamental types, and make
1146 * sure their sizes and kinds match.
1148 if (mdb_ctf_type_resolve(a
, &a
) != 0 ||
1149 mdb_ctf_type_resolve(b
, &b
) != 0 ||
1150 (asz
= mdb_ctf_type_size(a
)) == -1UL ||
1151 (bsz
= mdb_ctf_type_size(b
)) == -1UL ||
1152 (akind
= mdb_ctf_type_kind(a
)) == -1 ||
1153 (bkind
= mdb_ctf_type_kind(b
)) == -1 ||
1154 asz
!= bsz
|| akind
!= bkind
) {
1163 * For pointers we could be a little stricter and require
1164 * both pointers to reference types which look vaguely
1165 * similar (for example, we could insist that the two types
1166 * have the same name). However, all we really care about
1167 * here is that the structure of the two types are the same,
1168 * and, in that regard, one pointer is as good as another.
1175 * The test for the number of members is only strictly
1176 * necessary for unions since we'll find other problems with
1177 * structs. However, the extra check will do no harm.
1179 return (mdb_ctf_num_members(a
) == mdb_ctf_num_members(b
) &&
1180 mdb_ctf_member_iter(a
, type_equals_cb
, &b
) == 0);
1183 return (mdb_ctf_array_info(a
, &aar
) == 0 &&
1184 mdb_ctf_array_info(b
, &bar
) == 0 &&
1185 aar
.mta_nelems
== bar
.mta_nelems
&&
1186 type_equals(aar
.mta_index
, bar
.mta_index
) &&
1187 type_equals(aar
.mta_contents
, bar
.mta_contents
));
1194 typedef struct member
{
1197 const char *m_tgtname
;
1198 mdb_ctf_id_t m_tgtid
;
1202 static int vread_helper(mdb_ctf_id_t
, char *, mdb_ctf_id_t
, char *,
1203 const char *, uint_t
);
1206 member_cb(const char *name
, mdb_ctf_id_t modmid
, ulong_t modoff
, void *data
)
1208 member_t
*mp
= data
;
1209 char *modbuf
= mp
->m_modbuf
;
1210 mdb_ctf_id_t tgtmid
;
1211 char *tgtbuf
= mp
->m_tgtbuf
;
1215 (void) mdb_snprintf(tgtname
, sizeof (tgtname
),
1216 "member %s of type %s", name
, mp
->m_tgtname
);
1218 if (mdb_ctf_member_info(mp
->m_tgtid
, name
, &tgtoff
, &tgtmid
) != 0) {
1219 mdb_ctf_warn(mp
->m_flags
,
1220 "could not find %s\n", tgtname
);
1221 return (set_errno(EMDB_CTFNOMEMB
));
1224 return (vread_helper(modmid
, modbuf
+ modoff
/ NBBY
,
1225 tgtmid
, tgtbuf
+ tgtoff
/ NBBY
, tgtname
, mp
->m_flags
));
1228 typedef struct enum_value
{
1230 const char *ev_name
;
1234 enum_cb(const char *name
, int value
, void *data
)
1236 enum_value_t
*ev
= data
;
1238 if (strcmp(name
, ev
->ev_name
) == 0) {
1239 *ev
->ev_modbuf
= value
;
1246 vread_helper(mdb_ctf_id_t modid
, char *modbuf
,
1247 mdb_ctf_id_t tgtid
, char *tgtbuf
, const char *tgtname
, uint_t flags
)
1249 size_t modsz
, tgtsz
;
1250 int modkind
, tgtkind
;
1254 mdb_ctf_arinfo_t tar
, mar
;
1257 char mdbtypename
[128];
1258 ctf_encoding_t tgt_encoding
, mod_encoding
;
1259 boolean_t signed_int
= B_FALSE
;
1261 if (mdb_ctf_type_name(tgtid
, typename
, sizeof (typename
)) == NULL
) {
1262 (void) mdb_snprintf(typename
, sizeof (typename
),
1263 "#%ul", mdb_ctf_type_id(tgtid
));
1265 if (mdb_ctf_type_name(modid
,
1266 mdbtypename
, sizeof (mdbtypename
)) == NULL
) {
1267 (void) mdb_snprintf(mdbtypename
, sizeof (mdbtypename
),
1268 "#%ul", mdb_ctf_type_id(modid
));
1271 if (tgtname
== NULL
)
1275 * Resolve the types to their canonical form.
1277 (void) mdb_ctf_type_resolve(modid
, &modid
);
1278 (void) mdb_ctf_type_resolve(tgtid
, &tgtid
);
1280 if ((modkind
= mdb_ctf_type_kind(modid
)) == -1) {
1282 "couldn't determine type kind of mdb module type %s\n",
1284 return (-1); /* errno is set for us */
1286 if ((tgtkind
= mdb_ctf_type_kind(tgtid
)) == -1) {
1288 "couldn't determine type kind of %s\n", typename
);
1289 return (-1); /* errno is set for us */
1292 if ((modsz
= mdb_ctf_type_size(modid
)) == -1UL) {
1293 mdb_ctf_warn(flags
, "couldn't determine type size of "
1294 "mdb module type %s\n", mdbtypename
);
1295 return (-1); /* errno is set for us */
1297 if ((tgtsz
= mdb_ctf_type_size(tgtid
)) == -1UL) {
1298 mdb_ctf_warn(flags
, "couldn't determine size of %s (%s)\n",
1300 return (-1); /* errno is set for us */
1303 if (tgtkind
== CTF_K_POINTER
&& modkind
== CTF_K_INTEGER
&&
1304 strcmp(mdbtypename
, "uintptr_t") == 0) {
1305 /* allow them to convert a pointer to a uintptr_t */
1306 ASSERT(modsz
== tgtsz
);
1307 } else if (tgtkind
!= modkind
) {
1308 mdb_ctf_warn(flags
, "unexpected kind for type %s (%s)\n",
1310 return (set_errno(EMDB_INCOMPAT
));
1317 * Must determine if the target and module types have the same
1318 * encoding before we can copy them.
1320 if (mdb_ctf_type_encoding(tgtid
, &tgt_encoding
) != 0) {
1322 "couldn't determine encoding of type %s (%s)\n",
1324 return (-1); /* errno is set for us */
1326 if (mdb_ctf_type_encoding(modid
, &mod_encoding
) != 0) {
1327 mdb_ctf_warn(flags
, "couldn't determine encoding of "
1328 "mdb module type %s\n", mdbtypename
);
1329 return (-1); /* errno is set for us */
1332 if (modkind
== CTF_K_INTEGER
) {
1333 if ((tgt_encoding
.cte_format
& CTF_INT_SIGNED
) !=
1334 (mod_encoding
.cte_format
& CTF_INT_SIGNED
)) {
1336 "signedness mismatch between type "
1337 "%s (%s) and mdb module type %s\n",
1338 typename
, tgtname
, mdbtypename
);
1339 return (set_errno(EMDB_INCOMPAT
));
1342 ((tgt_encoding
.cte_format
& CTF_INT_SIGNED
) != 0);
1343 } else if (tgt_encoding
.cte_format
!= mod_encoding
.cte_format
) {
1345 "encoding mismatch (%#x != %#x) between type "
1346 "%s (%s) and mdb module type %s\n",
1347 tgt_encoding
.cte_format
, mod_encoding
.cte_format
,
1348 typename
, tgtname
, mdbtypename
);
1349 return (set_errno(EMDB_INCOMPAT
));
1354 * If the sizes don't match we need to be tricky to make
1355 * sure that the caller gets the correct data.
1357 if (modsz
< tgtsz
) {
1358 mdb_ctf_warn(flags
, "size of type %s (%s) is too "
1359 "large for mdb module type %s\n",
1360 typename
, tgtname
, mdbtypename
);
1361 return (set_errno(EMDB_INCOMPAT
));
1362 } else if (modsz
> tgtsz
) {
1365 * Fill modbuf with 1's for sign extension if target
1366 * buf is a signed integer and its value is negative.
1368 * S = sign bit (in most-significant byte)
1371 * +--------+--------+--------+--------+
1373 * +--------+--------+--------+--------+
1376 * LITTLE ENDIAN DATA
1377 * +--------+--------+--------+--------+
1379 * +--------+--------+--------+--------+
1384 if (signed_int
&& (tgtbuf
[0] & 0x80) != 0)
1386 if (signed_int
&& (tgtbuf
[tgtsz
- 1] & 0x80) != 0)
1388 (void) memset(modbuf
, 0xFF, modsz
);
1390 bzero(modbuf
, modsz
);
1392 bcopy(tgtbuf
, modbuf
+ modsz
- tgtsz
, tgtsz
);
1394 bcopy(tgtbuf
, modbuf
, tgtsz
);
1397 bcopy(tgtbuf
, modbuf
, modsz
);
1403 if (modsz
!= tgtsz
|| modsz
!= sizeof (int)) {
1404 mdb_ctf_warn(flags
, "unexpected size of type %s (%s)\n",
1406 return (set_errno(EMDB_INCOMPAT
));
1410 * Default to the same value as in the target.
1412 bcopy(tgtbuf
, modbuf
, sizeof (int));
1418 ev
.ev_modbuf
= (int *)modbuf
;
1419 ev
.ev_name
= mdb_ctf_enum_name(tgtid
, i
);
1420 if (ev
.ev_name
== NULL
) {
1422 "unexpected value %u of enum type %s (%s)\n",
1423 i
, typename
, tgtname
);
1424 return (set_errno(EMDB_INCOMPAT
));
1427 ret
= mdb_ctf_enum_iter(modid
, enum_cb
, &ev
);
1429 /* value not found */
1431 "unexpected value %s (%u) of enum type %s (%s)\n",
1432 ev
.ev_name
, i
, typename
, tgtname
);
1433 return (set_errno(EMDB_INCOMPAT
));
1434 } else if (ret
== 1) {
1437 } else if (ret
== -1) {
1438 mdb_ctf_warn(flags
, "could not iterate enum %s (%s)\n",
1444 mbr
.m_modbuf
= modbuf
;
1445 mbr
.m_tgtbuf
= tgtbuf
;
1446 mbr
.m_tgtid
= tgtid
;
1447 mbr
.m_flags
= flags
;
1448 mbr
.m_tgtname
= typename
;
1450 return (mdb_ctf_member_iter(modid
, member_cb
, &mbr
));
1455 * Unions are a little tricky. The only time it's truly
1456 * safe to read in a union is if no part of the union or
1457 * any of its component types have changed. The correct
1458 * use of this feature is to read the containing structure,
1459 * figure out which component of the union is valid, compute
1460 * the location of that in the target and then read in
1461 * that part of the structure.
1464 if (!type_equals(modid
, tgtid
)) {
1465 mdb_ctf_warn(flags
, "inexact match for union %s (%s)\n",
1467 return (set_errno(EMDB_INCOMPAT
));
1470 ASSERT(modsz
== tgtsz
);
1472 bcopy(tgtbuf
, modbuf
, modsz
);
1477 if (mdb_ctf_array_info(tgtid
, &tar
) != 0) {
1479 "couldn't get array info for %s (%s)\n",
1481 return (-1); /* errno is set for us */
1483 if (mdb_ctf_array_info(modid
, &mar
) != 0) {
1485 "couldn't get array info for mdb module type %s\n",
1487 return (-1); /* errno is set for us */
1490 if (tar
.mta_nelems
!= mar
.mta_nelems
) {
1492 "unexpected array size (%u) for type %s (%s)\n",
1493 tar
.mta_nelems
, typename
, tgtname
);
1494 return (set_errno(EMDB_INCOMPAT
));
1497 if ((modsz
= mdb_ctf_type_size(mar
.mta_contents
)) == -1UL) {
1498 mdb_ctf_warn(flags
, "couldn't determine type size of "
1499 "mdb module type %s\n", mdbtypename
);
1500 return (-1); /* errno is set for us */
1502 if ((tgtsz
= mdb_ctf_type_size(tar
.mta_contents
)) == -1UL) {
1504 "couldn't determine size of %s (%s)\n",
1506 return (-1); /* errno is set for us */
1509 for (i
= 0; i
< tar
.mta_nelems
; i
++) {
1510 ret
= vread_helper(mar
.mta_contents
, modbuf
+ i
* modsz
,
1511 tar
.mta_contents
, tgtbuf
+ i
* tgtsz
,
1521 mdb_ctf_warn(flags
, "unsupported kind %d for type %s (%s)\n",
1522 modkind
, typename
, tgtname
);
1523 return (set_errno(EMDB_INCOMPAT
));
1527 * Like mdb_vread(), mdb_ctf_vread() is used to read from the target's
1528 * virtual address space. However, mdb_ctf_vread() can be used to safely
1529 * read a complex type (e.g. a struct) from the target, even if MDB was compiled
1530 * against a different definition of that type (e.g. when debugging a crash
1531 * dump from an older release).
1533 * Callers can achieve this by defining their own type which corresponds to the
1534 * type in the target, but contains only the members that the caller requires.
1535 * Using the CTF type information embedded in the target, mdb_ctf_vread will
1536 * find the required members in the target and fill in the caller's structure.
1537 * The members are located by name, and their types are verified to be
1540 * By convention, the caller will declare a type with the name "mdb_<type>",
1541 * where <type> is the name of the type in the target (e.g. mdb_zio_t). This
1542 * type will contain the members that the caller is interested in. For example:
1544 * typedef struct mdb_zio {
1545 * enum zio_type io_type;
1546 * uintptr_t io_waiter;
1549 * uintptr_t list_next;
1556 * error = mdb_ctf_vread(&zio, "zio_t", "mdb_zio_t", zio_target_addr, 0);
1558 * If a given MDB module has different dcmds or walkers that need to read
1559 * different members from the same struct, then different "mdb_" types
1560 * should be declared for each caller. By convention, these types should
1561 * be named "mdb_<dcmd or walker>_<type>", e.g. mdb_findstack_kthread_t
1562 * for ::findstack. If the MDB module is compiled from several source files,
1563 * one must be especially careful to not define different types with the
1564 * same name in different source files, because the compiler can not detect
1567 * Enums will also be translated by name, so the mdb module will receive
1568 * the enum value it expects even if the target has renumbered the enum.
1569 * Warning: it will therefore only work with enums are only used to store
1570 * legitimate enum values (not several values or-ed together).
1572 * By default, if mdb_ctf_vread() can not find any members or enum values,
1573 * it will print a descriptive message (with mdb_warn()) and fail.
1574 * Passing MDB_CTF_VREAD_QUIET in 'flags' will suppress the warning message.
1575 * Additional flags can be used to ignore specific types of translation
1576 * failure, but should be used with caution, because they will silently leave
1577 * the caller's buffer uninitialized.
1580 mdb_ctf_vread(void *modbuf
, const char *target_typename
,
1581 const char *mdb_typename
, uintptr_t addr
, uint_t flags
)
1591 if ((mod
= mdb_get_module()) == NULL
|| (mfp
= mod
->mod_ctfp
) == NULL
) {
1592 mdb_ctf_warn(flags
, "no ctf data found for mdb module %s\n",
1594 return (set_errno(EMDB_NOCTF
));
1597 if ((mid
= ctf_lookup_by_name(mfp
, mdb_typename
)) == CTF_ERR
) {
1598 mdb_ctf_warn(flags
, "couldn't find ctf data for "
1599 "type %s in mdb module %s\n",
1600 mdb_typename
, mod
->mod_name
);
1601 return (set_errno(ctf_to_errno(ctf_errno(mfp
))));
1604 set_ctf_id(&modid
, mfp
, mid
);
1606 if (mdb_ctf_lookup_by_name(target_typename
, &tgtid
) != 0) {
1608 "couldn't find type %s in target's ctf data\n",
1610 return (set_errno(EMDB_NOCTF
));
1614 * Read the data out of the target's address space.
1616 if ((size
= mdb_ctf_type_size(tgtid
)) == -1UL) {
1617 mdb_ctf_warn(flags
, "couldn't determine size of type %s\n",
1619 return (-1); /* errno is set for us */
1622 tgtbuf
= mdb_alloc(size
, UM_SLEEP
| UM_GC
);
1624 if (mdb_vread(tgtbuf
, size
, addr
) < 0) {
1625 mdb_ctf_warn(flags
, "couldn't read %s from %p\n",
1626 target_typename
, addr
);
1627 return (-1); /* errno is set for us */
1630 return (vread_helper(modid
, modbuf
, tgtid
, tgtbuf
, NULL
, flags
));
1634 * Note: mdb_ctf_readsym() doesn't take separate parameters for the name
1635 * of the target's type vs the mdb module's type. Use with complicated
1636 * types (e.g. structs) may result in unnecessary failure if a member of
1637 * the struct has been changed in the target, but is not actually needed
1638 * by the mdb module. Use mdb_lookup_by_name() + mdb_ctf_vread() to
1639 * avoid this problem.
1642 mdb_ctf_readsym(void *buf
, const char *typename
, const char *name
, uint_t flags
)
1646 if (mdb_lookup_by_obj(MDB_TGT_OBJ_EVERY
, name
, &sym
) != 0) {
1647 mdb_ctf_warn(flags
, "couldn't find symbol %s\n", name
);
1648 return (-1); /* errno is set for us */
1651 return (mdb_ctf_vread(buf
, typename
, typename
, sym
.st_value
, flags
));
1655 mdb_ctf_bufopen(const void *ctf_va
, size_t ctf_size
, const void *sym_va
,
1656 Shdr
*symhdr
, const void *str_va
, Shdr
*strhdr
, int *errp
)
1658 ctf_sect_t ctdata
, symtab
, strtab
;
1660 ctdata
.cts_name
= ".SUNW_ctf";
1661 ctdata
.cts_type
= SHT_PROGBITS
;
1662 ctdata
.cts_flags
= 0;
1663 ctdata
.cts_data
= ctf_va
;
1664 ctdata
.cts_size
= ctf_size
;
1665 ctdata
.cts_entsize
= 1;
1666 ctdata
.cts_offset
= 0;
1668 symtab
.cts_name
= ".symtab";
1669 symtab
.cts_type
= symhdr
->sh_type
;
1670 symtab
.cts_flags
= symhdr
->sh_flags
;
1671 symtab
.cts_data
= sym_va
;
1672 symtab
.cts_size
= symhdr
->sh_size
;
1673 symtab
.cts_entsize
= symhdr
->sh_entsize
;
1674 symtab
.cts_offset
= symhdr
->sh_offset
;
1676 strtab
.cts_name
= ".strtab";
1677 strtab
.cts_type
= strhdr
->sh_type
;
1678 strtab
.cts_flags
= strhdr
->sh_flags
;
1679 strtab
.cts_data
= str_va
;
1680 strtab
.cts_size
= strhdr
->sh_size
;
1681 strtab
.cts_entsize
= strhdr
->sh_entsize
;
1682 strtab
.cts_offset
= strhdr
->sh_offset
;
1684 return (ctf_bufopen(&ctdata
, &symtab
, &strtab
, errp
));
1688 mdb_ctf_synthetics_init(void)
1692 if ((mdb
.m_synth
= ctf_create(&err
)) == NULL
)
1693 return (set_errno(ctf_to_errno(err
)));
1699 mdb_ctf_synthetics_fini(void)
1701 if (mdb
.m_synth
== NULL
)
1704 ctf_close(mdb
.m_synth
);
1709 mdb_ctf_synthetics_create_base(int kind
)
1711 const synth_intrinsic_t
*synp
;
1712 const synth_typedef_t
*sytp
;
1715 ctf_file_t
*cp
= mdb
.m_synth
;
1717 if (mdb
.m_synth
== NULL
) {
1718 mdb_printf("synthetic types disabled: ctf create failed\n");
1723 case SYNTHETIC_ILP32
:
1724 synp
= synth_builtins32
;
1725 sytp
= synth_typedefs32
;
1727 case SYNTHETIC_LP64
:
1728 synp
= synth_builtins64
;
1729 sytp
= synth_typedefs64
;
1732 mdb_dprintf(MDB_DBG_CTF
, "invalid type of intrinsic: %d\n",
1738 for (; synp
->syn_name
!= NULL
; synp
++) {
1739 if (synp
->syn_kind
== CTF_K_INTEGER
) {
1740 err
= ctf_add_integer(cp
, CTF_ADD_ROOT
, synp
->syn_name
,
1743 err
= ctf_add_float(cp
, CTF_ADD_ROOT
, synp
->syn_name
,
1747 if (err
== CTF_ERR
) {
1748 mdb_dprintf(MDB_DBG_CTF
, "couldn't add synthetic "
1749 "type: %s\n", synp
->syn_name
);
1754 if (ctf_update(cp
) == CTF_ERR
) {
1755 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types\n");
1759 for (; sytp
->syt_src
!= NULL
; sytp
++) {
1760 id
= ctf_lookup_by_name(cp
, sytp
->syt_src
);
1761 if (id
== CTF_ERR
) {
1762 mdb_dprintf(MDB_DBG_CTF
, "cailed to lookup %s: %s\n",
1763 sytp
->syt_src
, ctf_errmsg(ctf_errno(cp
)));
1766 if (ctf_add_typedef(cp
, CTF_ADD_ROOT
, sytp
->syt_targ
, id
) ==
1768 mdb_dprintf(MDB_DBG_CTF
, "couldn't add typedef %s "
1769 "%s: %s\n", sytp
->syt_targ
, sytp
->syt_src
,
1770 ctf_errmsg(ctf_errno(cp
)));
1775 if (ctf_update(cp
) == CTF_ERR
) {
1776 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types\n");
1783 err
= set_errno(ctf_to_errno(ctf_errno(cp
)));
1784 (void) ctf_discard(cp
);
1789 mdb_ctf_synthetics_reset(void)
1791 mdb_ctf_synthetics_fini();
1792 return (mdb_ctf_synthetics_init());
1796 mdb_ctf_add_typedef(const char *name
, const mdb_ctf_id_t
*p
, mdb_ctf_id_t
*new)
1800 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)p
;
1802 if (mdb
.m_synth
== NULL
) {
1803 mdb_printf("synthetic types disabled: ctf create failed\n");
1807 if (mdb_ctf_lookup_by_name(name
, &tid
) == 0) {
1808 mdb_dprintf(MDB_DBG_CTF
, "failed to add type %s: a type "
1809 "with that name already exists\n", name
);
1810 return (set_errno(EEXIST
));
1813 rid
= ctf_add_type(mdb
.m_synth
, mcip
->mci_fp
, mcip
->mci_id
);
1814 if (rid
== CTF_ERR
) {
1815 mdb_dprintf(MDB_DBG_CTF
, "failed to add reference type: %s\n",
1816 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1817 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1819 rid
= ctf_add_typedef(mdb
.m_synth
, CTF_ADD_ROOT
, name
, rid
);
1820 if (rid
== CTF_ERR
) {
1821 mdb_dprintf(MDB_DBG_CTF
, "failed to add typedef: %s",
1822 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1823 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1826 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1827 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1828 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1829 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1833 set_ctf_id(new, mdb
.m_synth
, rid
);
1839 mdb_ctf_add_struct(const char *name
, mdb_ctf_id_t
*rid
)
1844 if (mdb
.m_synth
== NULL
) {
1845 mdb_printf("synthetic types disabled: ctf create failed\n");
1849 if (name
!= NULL
&& mdb_ctf_lookup_by_name(name
, &tid
) == 0) {
1850 mdb_dprintf(MDB_DBG_CTF
, "failed to add type %s: a type "
1851 "with that name already exists\n", name
);
1852 return (set_errno(EEXIST
));
1855 if ((id
= ctf_add_struct(mdb
.m_synth
, CTF_ADD_ROOT
, name
)) ==
1857 mdb_dprintf(MDB_DBG_CTF
, "failed to add struct: %s\n",
1858 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1859 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1862 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1863 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1864 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1865 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1869 set_ctf_id(rid
, mdb
.m_synth
, id
);
1875 mdb_ctf_add_union(const char *name
, mdb_ctf_id_t
*rid
)
1880 if (mdb
.m_synth
== NULL
) {
1881 mdb_printf("synthetic types disabled: ctf create failed\n");
1885 if (name
!= NULL
&& mdb_ctf_lookup_by_name(name
, &tid
) == 0) {
1886 mdb_dprintf(MDB_DBG_CTF
, "failed to add type %s: a type "
1887 "with that name already exists\n", name
);
1888 return (set_errno(EEXIST
));
1891 if ((id
= ctf_add_union(mdb
.m_synth
, CTF_ADD_ROOT
, name
)) ==
1893 mdb_dprintf(MDB_DBG_CTF
, "failed to add union: %s\n",
1894 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1895 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1898 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1899 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1900 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1901 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1905 set_ctf_id(rid
, mdb
.m_synth
, id
);
1911 mdb_ctf_add_member(const mdb_ctf_id_t
*p
, const char *name
,
1912 const mdb_ctf_id_t
*mtype
, mdb_ctf_id_t
*rid
)
1915 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)p
;
1916 mdb_ctf_impl_t
*mcim
= (mdb_ctf_impl_t
*)mtype
;
1918 if (mdb
.m_synth
== NULL
) {
1919 mdb_printf("synthetic types disabled: ctf create failed\n");
1923 if (mcip
->mci_fp
!= mdb
.m_synth
) {
1924 mdb_dprintf(MDB_DBG_CTF
, "requested to add member to a type "
1925 "that wasn't created from a synthetic\n");
1926 return (set_errno(EINVAL
));
1929 mtid
= ctf_add_type(mdb
.m_synth
, mcim
->mci_fp
, mcim
->mci_id
);
1930 if (mtid
== CTF_ERR
) {
1931 mdb_dprintf(MDB_DBG_CTF
, "failed to add member type: %s\n",
1932 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1933 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1936 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1937 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1938 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1939 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1942 id
= ctf_add_member(mdb
.m_synth
, mcip
->mci_id
, name
, mtid
);
1943 if (id
== CTF_ERR
) {
1944 mdb_dprintf(MDB_DBG_CTF
, "failed to add member %s: %s\n",
1945 name
, ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1946 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1949 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1950 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1951 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1952 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1956 set_ctf_id(rid
, mdb
.m_synth
, id
);
1962 mdb_ctf_add_array(const mdb_ctf_arinfo_t
*marp
, mdb_ctf_id_t
*rid
)
1964 mdb_ctf_impl_t
*mcip
;
1968 if (mdb
.m_synth
== NULL
) {
1969 mdb_printf("synthetic types disabled: ctf create failed\n");
1973 car
.ctr_nelems
= marp
->mta_nelems
;
1975 mcip
= (mdb_ctf_impl_t
*)&marp
->mta_contents
;
1976 id
= ctf_add_type(mdb
.m_synth
, mcip
->mci_fp
, mcip
->mci_id
);
1977 if (id
== CTF_ERR
) {
1978 mdb_dprintf(MDB_DBG_CTF
, "failed to add member type: %s\n",
1979 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1980 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1982 car
.ctr_contents
= id
;
1984 mcip
= (mdb_ctf_impl_t
*)&marp
->mta_index
;
1985 id
= ctf_add_type(mdb
.m_synth
, mcip
->mci_fp
, mcip
->mci_id
);
1986 if (id
== CTF_ERR
) {
1987 mdb_dprintf(MDB_DBG_CTF
, "failed to add member type: %s\n",
1988 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1989 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1993 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
1994 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
1995 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
1996 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
1999 id
= ctf_add_array(mdb
.m_synth
, CTF_ADD_ROOT
, &car
);
2000 if (id
== CTF_ERR
) {
2001 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2002 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2003 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2006 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
2007 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2008 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2009 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2013 set_ctf_id(rid
, mdb
.m_synth
, id
);
2019 mdb_ctf_add_pointer(const mdb_ctf_id_t
*p
, mdb_ctf_id_t
*rid
)
2022 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)p
;
2024 if (mdb
.m_synth
== NULL
) {
2025 mdb_printf("synthetic types disabled: ctf create failed\n");
2029 id
= ctf_add_type(mdb
.m_synth
, mcip
->mci_fp
, mcip
->mci_id
);
2030 if (id
== CTF_ERR
) {
2031 mdb_dprintf(MDB_DBG_CTF
, "failed to add pointer type: %s\n",
2032 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2033 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2036 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
2037 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2038 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2039 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2043 id
= ctf_add_pointer(mdb
.m_synth
, CTF_ADD_ROOT
, id
);
2044 if (id
== CTF_ERR
) {
2045 mdb_dprintf(MDB_DBG_CTF
, "failed to add pointer: %s\n",
2046 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2047 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2050 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
2051 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2052 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2053 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2058 set_ctf_id(rid
, mdb
.m_synth
, id
);
2064 mdb_ctf_type_delete(const mdb_ctf_id_t
*id
)
2068 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)id
;
2070 if (mcip
->mci_fp
!= mdb
.m_synth
) {
2071 mdb_warn("bad ctf_file_t, expected synth container\n");
2075 ret
= ctf_delete_type(mcip
->mci_fp
, mcip
->mci_id
);
2077 mdb_dprintf(MDB_DBG_CTF
, "failed to delete synthetic type: %s",
2078 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2079 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2082 if (ctf_update(mdb
.m_synth
) == CTF_ERR
) {
2083 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types: %s",
2084 ctf_errmsg(ctf_errno(mdb
.m_synth
)));
2085 return (set_errno(ctf_to_errno(ctf_errno(mdb
.m_synth
))));
2092 mdb_ctf_synthetics_file_cb(mdb_ctf_id_t id
, void *arg
)
2094 ctf_file_t
*targ
= arg
;
2095 mdb_ctf_impl_t
*mcip
= (mdb_ctf_impl_t
*)&id
;
2097 if (ctf_add_type(targ
, mcip
->mci_fp
, mcip
->mci_id
) == CTF_ERR
) {
2098 mdb_dprintf(MDB_DBG_CTF
, "failed to add type %d: %s\n",
2099 mcip
->mci_id
, ctf_errmsg(ctf_errno(mcip
->mci_fp
)));
2100 return (set_errno(ctf_to_errno(ctf_errno(mcip
->mci_fp
))));
2107 mdb_ctf_synthetics_from_file(const char *file
)
2109 ctf_file_t
*fp
, *syn
= mdb
.m_synth
;
2114 mdb_warn("synthetic types disabled: ctf create failed\n");
2118 if ((fp
= mdb_ctf_open(file
, &ret
)) == NULL
) {
2119 mdb_warn("failed to parse ctf data in %s: %s\n", file
,
2127 ti
.ti_cb
= mdb_ctf_synthetics_file_cb
;
2128 if (ctf_type_iter(fp
, type_iter_cb
, &ti
) == CTF_ERR
) {
2129 ret
= set_errno(ctf_to_errno(ctf_errno(fp
)));
2130 mdb_warn("failed to add types");
2134 if (ctf_update(syn
) == CTF_ERR
) {
2135 mdb_dprintf(MDB_DBG_CTF
, "failed to update synthetic types\n");
2136 ret
= set_errno(ctf_to_errno(ctf_errno(fp
)));
2142 (void) ctf_discard(syn
);